This commit is contained in:
dima 2016-12-06 23:20:29 +01:00
parent b92b02b6d6
commit c1898be3d6
49 changed files with 712 additions and 799 deletions

View File

@ -118,7 +118,7 @@ module VagrantPlugins
b.use ConfigValidate
b.use ClearForwardedPorts
b.use Call, IsCreated do |env, b2|
if !env[:result]
unless env[:result]
b2.use MessageNotCreated
next
end
@ -128,7 +128,7 @@ module VagrantPlugins
end
b2.use Call, IsRunning do |env2, b3|
next if !env2[:result]
next unless env2[:result]
# VM is running, halt it.
b3.use HaltDomain
@ -142,7 +142,7 @@ module VagrantPlugins
def self.action_reload
Vagrant::Action::Builder.new.tap do |b|
b.use Call, IsCreated do |env, b2|
if !env[:result]
unless env[:result]
b2.use MessageNotCreated
next
end
@ -168,15 +168,11 @@ module VagrantPlugins
Vagrant::Action::Builder.new.tap do |b|
b.use ConfigValidate
b.use Call, IsCreated do |env, b2|
if !env[:result]
unless env[:result]
# Try to remove stale volumes anyway
b2.use SetNameOfDomain
if env[:machine].config.vm.box
b2.use RemoveStaleVolume
end
if !env[:result]
b2.use MessageNotCreated
end
b2.use RemoveStaleVolume if env[:machine].config.vm.box
b2.use MessageNotCreated unless env[:result]
next
end
@ -195,13 +191,13 @@ module VagrantPlugins
Vagrant::Action::Builder.new.tap do |b|
b.use ConfigValidate
b.use Call, IsCreated do |env, b2|
if !env[:result]
unless env[:result]
b2.use MessageNotCreated
next
end
b2.use Call, IsRunning do |env2, b3|
if !env2[:result]
unless env2[:result]
b3.use MessageNotRunning
next
end
@ -217,13 +213,13 @@ module VagrantPlugins
Vagrant::Action::Builder.new.tap do |b|
b.use ConfigValidate
b.use Call, IsCreated do |env, b2|
if !env[:result]
unless env[:result]
b2.use MessageNotCreated
next
end
b2.use Call, IsRunning do |env2, b3|
if !env2[:result]
unless env2[:result]
b3.use MessageNotRunning
next
end
@ -241,13 +237,13 @@ module VagrantPlugins
Vagrant::Action::Builder.new.tap do |b|
b.use ConfigValidate
b.use Call, IsCreated do |env, b2|
if !env[:result]
unless env[:result]
b2.use MessageNotCreated
next
end
b2.use Call, IsRunning do |env2, b3|
if !env2[:result]
unless env2[:result]
b3.use MessageNotRunning
next
end
@ -263,13 +259,13 @@ module VagrantPlugins
Vagrant::Action::Builder.new.tap do |b|
b.use ConfigValidate
b.use Call, IsCreated do |env, b2|
if !env[:result]
unless env[:result]
b2.use MessageNotCreated
next
end
b2.use Call, IsSuspended do |env2, b3|
if !env2[:result]
unless env2[:result]
b3.use MessageNotSuspended
next
end
@ -291,13 +287,13 @@ module VagrantPlugins
Vagrant::Action::Builder.new.tap do |b|
b.use ConfigValidate
b.use Call, IsCreated do |env, b2|
if !env[:result]
unless env[:result]
b2.use MessageNotCreated
next
end
b2.use Call, IsRunning do |env2, b3|
if !env2[:result]
unless env2[:result]
b3.use MessageNotRunning
next
end
@ -305,7 +301,6 @@ module VagrantPlugins
b3.use SSHRun
end
end
end
end
@ -351,7 +346,7 @@ module VagrantPlugins
autoload :WaitTillUp, action_root.join('wait_till_up')
autoload :PrepareNFSValidIds, action_root.join('prepare_nfs_valid_ids')
autoload :SSHRun, 'vagrant/action/builtin/ssh_run'
autoload :SSHRun, 'vagrant/action/builtin/ssh_run'
autoload :HandleBox, 'vagrant/action/builtin/handle_box'
autoload :SyncedFolders, 'vagrant/action/builtin/synced_folders'
autoload :SyncedFolderCleanup, 'vagrant/action/builtin/synced_folder_cleanup'

View File

@ -17,8 +17,9 @@ module VagrantPlugins
# Fog libvirt currently doesn't support snapshots. Use
# ruby-libvirt client directly. Note this is racy, see
# http://www.libvirt.org/html/libvirt-libvirt.html#virDomainSnapshotListNames
libvirt_domain = env[:machine].provider.driver.connection.client.lookup_domain_by_uuid(
env[:machine].id)
libvirt_domain = env[:machine].provider.driver.connection.client.lookup_domain_by_uuid(
env[:machine].id
)
libvirt_domain.list_snapshots.each do |name|
@logger.info("Deleting snapshot '#{name}'")
begin
@ -29,14 +30,12 @@ module VagrantPlugins
end
# must remove managed saves
if libvirt_domain.has_managed_save?
libvirt_domain.managed_save_remove
end
libvirt_domain.managed_save_remove if libvirt_domain.has_managed_save?
domain = env[:machine].provider.driver.connection.servers.get(env[:machine].id.to_s)
if env[:machine].provider_config.disks.empty? and
env[:machine].provider_config.cdroms.empty?
if env[:machine].provider_config.disks.empty? &&
env[:machine].provider_config.cdroms.empty?
# if using default configuration of disks and cdroms
# cdroms are consider volumes, but cannot be destroyed
domain.destroy(destroy_volumes: true)
@ -56,7 +55,7 @@ module VagrantPlugins
elsif disk[:path]
poolname = env[:machine].provider_config.storage_pool_name
libvirt_disk = domain.volumes.select do |x|
# FIXME can remove pool/target.img and pool/123/target.img
# FIXME: can remove pool/target.img and pool/123/target.img
x.path =~ /\/#{disk[:path]}$/ && x.pool_name == poolname
end.first
libvirt_disk.destroy if libvirt_disk

View File

@ -7,8 +7,7 @@ module VagrantPlugins
# Destroy all networks created for this specific domain. Skip
# removing if network has still active connections.
class DestroyNetworks
def initialize(app, env)
def initialize(app, _env)
@logger = Log4r::Logger.new('vagrant_libvirt::action::destroy_networks')
@app = app
end
@ -37,11 +36,12 @@ module VagrantPlugins
# if there is an error or if the network just doesn't exist
begin
libvirt_network = env[:machine].provider.driver.connection.client.lookup_network_by_uuid(
network_uuid)
network_uuid
)
rescue Libvirt::RetrieveError => e
# this network is already destroyed, so move on
if e.message =~ /Network not found/
@logger.info "It is already undefined"
@logger.info 'It is already undefined'
next
# some other error occured, so raise it again
else
@ -52,38 +52,37 @@ module VagrantPlugins
# Skip removing if network has still active connections.
xml = Nokogiri::XML(libvirt_network.xml_desc)
connections = xml.xpath('/network/@connections').first
if connections != nil
@logger.info "Still has connections so will not undefine"
unless connections.nil?
@logger.info 'Still has connections so will not undefine'
created_networks << network_uuid
next
end
# Shutdown network first.
# Undefine network.
begin
libvirt_network.destroy
libvirt_network.undefine
@logger.info "Undefined it"
@logger.info 'Undefined it'
rescue => e
raise Errors::DestroyNetworkError,
network_name: libvirt_network.name,
error_message: e.message
network_name: libvirt_network.name,
error_message: e.message
end
end
file.close
# Update status of created networks after removing some/all of them.
# Not sure why we are doing this, something else seems to always delete the file
if created_networks.length > 0
if !created_networks.empty?
File.open(created_networks_file, 'w') do |file|
@logger.info "Writing new created_networks file"
@logger.info 'Writing new created_networks file'
created_networks.each do |network_uuid|
file.puts network_uuid
end
end
else
@logger.info "Deleting created_networks file"
@logger.info 'Deleting created_networks file'
File.delete(created_networks_file)
end

View File

@ -5,7 +5,7 @@ module VagrantPlugins
class ForwardPorts
@@lock = Mutex.new
def initialize(app, env)
def initialize(app, _env)
@app = app
@logger = Log4r::Logger.new('vagrant_libvirt::action::forward_ports')
end
@ -18,12 +18,11 @@ module VagrantPlugins
# Warn if we're port forwarding to any privileged ports
env[:forwarded_ports].each do |fp|
if fp[:host] <= 1024
env[:ui].warn I18n.t(
'vagrant.actions.vm.forward_ports.privileged_ports'
)
break
end
next unless fp[:host] <= 1024
env[:ui].warn I18n.t(
'vagrant.actions.vm.forward_ports.privileged_ports'
)
break
end
# Continue, we need the VM to be booted in order to grab its IP
@ -44,8 +43,8 @@ module VagrantPlugins
}
@env[:ui].info(I18n.t(
'vagrant.actions.vm.forward_ports.forwarding_entry',
message_attributes
'vagrant.actions.vm.forward_ports.forwarding_entry',
message_attributes
))
ssh_pid = redirect_port(
@ -68,12 +67,11 @@ module VagrantPlugins
config.vm.networks.each do |type, options|
next if options[:disabled]
if type == :forwarded_port && options[:id] != 'ssh'
if options.fetch(:host_ip, '').to_s.strip.empty?
options.delete(:host_ip)
end
mappings[options[:host]] = options
next unless type == :forwarded_port && options[:id] != 'ssh'
if options.fetch(:host_ip, '').to_s.strip.empty?
options.delete(:host_ip)
end
mappings[options[:host]] = options
end
mappings.values
@ -98,8 +96,8 @@ module VagrantPlugins
PasswordAuthentication=no
ForwardX11=#{ssh_info[:forward_x11] ? 'yes' : 'no'}
) + ssh_info[:private_key_path].map do |pk|
"IdentityFile='\"#{pk}\"'"
end).map { |s| s.prepend('-o ') }.join(' ')
"IdentityFile='\"#{pk}\"'"
end).map { |s| s.prepend('-o ') }.join(' ')
options += " -o ProxyCommand=\"#{ssh_info[:proxy_command]}\"" if machine.provider_config.connect_via_ssh
@ -111,7 +109,7 @@ module VagrantPlugins
@env[:ui].info 'Requesting sudo for host port(s) <= 1024'
r = system('sudo -v')
if r
ssh_cmd << 'sudo ' # add sudo prefix
ssh_cmd << 'sudo ' # add sudo prefix
end
end
end
@ -122,7 +120,7 @@ module VagrantPlugins
log_file = ssh_forward_log_file(host_ip, host_port,
guest_ip, guest_port)
@logger.info "Logging to #{log_file}"
spawn(ssh_cmd, [:out, :err] => [log_file, 'w'])
spawn(ssh_cmd, [:out, :err] => [log_file, 'w'])
end
def ssh_forward_log_file(host_ip, host_port, guest_ip, guest_port)
@ -131,7 +129,7 @@ module VagrantPlugins
File.join(
log_dir,
'ssh-forwarding-%s_%s-%s_%s.log' %
[ host_ip, host_port, guest_ip, guest_port ]
[host_ip, host_port, guest_ip, guest_port]
)
end
@ -155,7 +153,7 @@ module VagrantPlugins
class ClearForwardedPorts
@@lock = Mutex.new
def initialize(app, env)
def initialize(app, _env)
@app = app
@logger = Log4r::Logger.new(
'vagrant_libvirt::action::clear_forward_ports'
@ -175,7 +173,7 @@ module VagrantPlugins
kill_cmd = ''
if tag[:port] <= 1024
kill_cmd << 'sudo ' # add sudo prefix
kill_cmd << 'sudo ' # add sudo prefix
end
kill_cmd << "kill #{tag[:pid]}"
@ -199,8 +197,8 @@ module VagrantPlugins
glob = @env[:machine].data_dir.join('pids').to_s + '/ssh_*.pid'
@ssh_pids = Dir[glob].map do |file|
{
:pid => File.read(file).strip.chomp,
:port => File.basename(file)['ssh_'.length..-1*('.pid'.length+1)].to_i
pid: File.read(file).strip.chomp,
port: File.basename(file)['ssh_'.length..-1 * ('.pid'.length + 1)].to_i
}
end
end

View File

@ -5,25 +5,25 @@ module VagrantPlugins
module Action
# Halt the domain.
class HaltDomain
def initialize(app, env)
@logger = Log4r::Logger.new("vagrant_libvirt::action::halt_domain")
def initialize(app, _env)
@logger = Log4r::Logger.new('vagrant_libvirt::action::halt_domain')
@app = app
end
def call(env)
env[:ui].info(I18n.t("vagrant_libvirt.halt_domain"))
env[:ui].info(I18n.t('vagrant_libvirt.halt_domain'))
domain = env[:machine].provider.driver.connection.servers.get(env[:machine].id.to_s)
raise Errors::NoDomainError if domain == nil
raise Errors::NoDomainError if domain.nil?
@logger.info("Trying gracefull shutdown.")
@logger.info('Trying gracefull shutdown.')
domain.shutdown
begin
domain.wait_for(30) {
domain.wait_for(30) do
!ready?
}
end
rescue Fog::Errors::TimeoutError
@logger.info("VM is still running. Calling force poweroff.")
@logger.info('VM is still running. Calling force poweroff.')
domain.poweroff
end
@ -33,4 +33,3 @@ module VagrantPlugins
end
end
end

View File

@ -4,38 +4,38 @@ module VagrantPlugins
module ProviderLibvirt
module Action
class HandleBoxImage
@@lock = Mutex.new
def initialize(app, env)
def initialize(app, _env)
@logger = Log4r::Logger.new('vagrant_libvirt::action::handle_box_image')
@app = app
end
def call(env)
# Verify box metadata for mandatory values.
#
# Virtual size has to be set for allocating space in storage pool.
box_virtual_size = env[:machine].box.metadata['virtual_size']
if box_virtual_size == nil
raise Errors::NoBoxVirtualSizeSet
end
raise Errors::NoBoxVirtualSizeSet if box_virtual_size.nil?
# Support qcow2 format only for now, but other formats with backing
# store capability should be usable.
box_format = env[:machine].box.metadata['format']
if box_format == nil
if box_format.nil?
raise Errors::NoBoxFormatSet
elsif box_format != 'qcow2'
raise Errors::WrongBoxFormatSet
end
# Get config options
config = env[:machine].provider_config
config = env[:machine].provider_config
box_image_file = env[:machine].box.directory.join('box.img').to_s
env[:box_volume_name] = env[:machine].box.name.to_s.dup.gsub("/", "-VAGRANTSLASH-")
env[:box_volume_name] << "_vagrant_box_image_#{env[:machine].box.version.to_s rescue ''}.img"
env[:box_volume_name] = env[:machine].box.name.to_s.dup.gsub('/', '-VAGRANTSLASH-')
env[:box_volume_name] << "_vagrant_box_image_#{begin
env[:machine].box.version.to_s
rescue
''
end}.img"
# Override box_virtual_size
if config.machine_virtual_size
@ -60,15 +60,16 @@ module VagrantPlugins
@@lock.synchronize do
# Don't continue if image already exists in storage pool.
break if ProviderLibvirt::Util::Collection.find_matching(
env[:machine].provider.driver.connection.volumes.all, env[:box_volume_name])
env[:machine].provider.driver.connection.volumes.all, env[:box_volume_name]
)
# Box is not available as a storage pool volume. Create and upload
# it as a copy of local box image.
env[:ui].info(I18n.t('vagrant_libvirt.uploading_volume'))
# Create new volume in storage pool
unless File.exists?(box_image_file)
raise Vagrant::Errors::BoxNotFound.new(name: env[:machine].box.name)
unless File.exist?(box_image_file)
raise Vagrant::Errors::BoxNotFound, name: env[:machine].box.name
end
box_image_size = File.size(box_image_file) # B
message = "Creating volume #{env[:box_volume_name]}"
@ -77,20 +78,21 @@ module VagrantPlugins
begin
fog_volume = env[:machine].provider.driver.connection.volumes.create(
name: env[:box_volume_name],
allocation: "#{box_image_size/1024/1024}M",
allocation: "#{box_image_size / 1024 / 1024}M",
capacity: "#{box_virtual_size}G",
format_type: box_format,
pool_name: config.storage_pool_name)
pool_name: config.storage_pool_name
)
rescue Fog::Errors::Error => e
raise Errors::FogCreateVolumeError,
:error_message => e.message
error_message: e.message
end
# Upload box image to storage pool
ret = upload_image(box_image_file, config.storage_pool_name,
env[:box_volume_name], env) do |progress|
env[:ui].clear_line
env[:ui].report_progress(progress, box_image_size, false)
env[:box_volume_name], env) do |progress|
env[:ui].clear_line
env[:ui].report_progress(progress, box_image_size, false)
end
# Clear the line one last time since the progress meter doesn't
@ -120,10 +122,11 @@ module VagrantPlugins
begin
pool = env[:machine].provider.driver.connection.client.lookup_storage_pool_by_name(
pool_name)
pool_name
)
volume = pool.lookup_volume_by_name(volume_name)
stream = env[:machine].provider.driver.connection.client.stream
volume.upload(stream, offset=0, length=image_size)
volume.upload(stream, offset = 0, length = image_size)
# Exception ProviderLibvirt::RetrieveError can be raised if buffer is
# longer than length accepted by API send function.
@ -131,10 +134,10 @@ module VagrantPlugins
# TODO: How to find out if buffer is too large and what is the
# length that send function will accept?
buf_size = 1024*250 # 250K
buf_size = 1024 * 250 # 250K
progress = 0
open(image_file, 'rb') do |io|
while (buff = io.read(buf_size)) do
while (buff = io.read(buf_size))
sent = stream.send buff
progress += sent
yield progress
@ -142,14 +145,12 @@ module VagrantPlugins
end
rescue => e
raise Errors::ImageUploadError,
:error_message => e.message
error_message: e.message
end
return progress == image_size
progress == image_size
end
end
end
end
end

View File

@ -8,8 +8,8 @@ module VagrantPlugins
@@lock = Mutex.new
def initialize(app, env)
@logger = Log4r::Logger.new("vagrant_libvirt::action::handle_storage_pool")
def initialize(app, _env)
@logger = Log4r::Logger.new('vagrant_libvirt::action::handle_storage_pool')
@app = app
end
@ -23,7 +23,8 @@ module VagrantPlugins
@@lock.synchronize do
# Check for storage pool, where box image should be created
break if ProviderLibvirt::Util::Collection.find_matching(
env[:machine].provider.driver.connection.pools.all, config.storage_pool_name)
env[:machine].provider.driver.connection.pools.all, config.storage_pool_name
)
@logger.info("No storage pool '#{config.storage_pool_name}' is available.")
@ -37,21 +38,20 @@ module VagrantPlugins
# ruby-libvirt client directly.
begin
libvirt_pool = env[:machine].provider.driver.connection.client.define_storage_pool_xml(
to_xml('default_storage_pool'))
to_xml('default_storage_pool')
)
libvirt_pool.build
libvirt_pool.create
rescue => e
raise Errors::CreatingStoragePoolError,
:error_message => e.message
error_message: e.message
end
raise Errors::NoStoragePool if !libvirt_pool
raise Errors::NoStoragePool unless libvirt_pool
end
@app.call(env)
end
end
end
end
end

View File

@ -4,7 +4,7 @@ module VagrantPlugins
# This can be used with "Call" built-in to check if the machine
# is created and branch in the middleware.
class IsCreated
def initialize(app, env)
def initialize(app, _env)
@app = app
end

View File

@ -4,13 +4,13 @@ module VagrantPlugins
# This can be used with "Call" built-in to check if the machine
# is running and branch in the middleware.
class IsRunning
def initialize(app, env)
def initialize(app, _env)
@app = app
end
def call(env)
domain = env[:machine].provider.driver.connection.servers.get(env[:machine].id.to_s)
raise Errors::NoDomainError if domain == nil
raise Errors::NoDomainError if domain.nil?
env[:result] = domain.state.to_s == 'running'
@app.call(env)

View File

@ -4,16 +4,16 @@ module VagrantPlugins
# This can be used with "Call" built-in to check if the machine
# is suspended and branch in the middleware.
class IsSuspended
def initialize(app, env)
def initialize(app, _env)
@app = app
end
def call(env)
domain = env[:machine].provider.driver.connection.servers.get(env[:machine].id.to_s)
raise Errors::NoDomainError if domain == nil
raise Errors::NoDomainError if domain.nil?
config = env[:machine].provider_config
libvirt_domain = env[:machine].provider.driver.connection.client.lookup_domain_by_uuid(env[:machine].id)
libvirt_domain = env[:machine].provider.driver.connection.client.lookup_domain_by_uuid(env[:machine].id)
if config.suspend_mode == 'managedsave'
if libvirt_domain.has_managed_save?
env[:result] = libvirt_domain.has_managed_save?
@ -33,7 +33,7 @@ module VagrantPlugins
env[:result] = domain.state.to_s == 'paused'
end
end
@app.call(env)
end
end

View File

@ -2,12 +2,12 @@ module VagrantPlugins
module ProviderLibvirt
module Action
class MessageAlreadyCreated
def initialize(app, env)
def initialize(app, _env)
@app = app
end
def call(env)
env[:ui].info(I18n.t("vagrant_libvirt.already_created"))
env[:ui].info(I18n.t('vagrant_libvirt.already_created'))
@app.call(env)
end
end

View File

@ -2,12 +2,12 @@ module VagrantPlugins
module ProviderLibvirt
module Action
class MessageNotCreated
def initialize(app, env)
def initialize(app, _env)
@app = app
end
def call(env)
env[:ui].info(I18n.t("vagrant_libvirt.not_created"))
env[:ui].info(I18n.t('vagrant_libvirt.not_created'))
@app.call(env)
end
end

View File

@ -2,12 +2,12 @@ module VagrantPlugins
module ProviderLibvirt
module Action
class MessageNotRunning
def initialize(app, env)
def initialize(app, _env)
@app = app
end
def call(env)
env[:ui].info(I18n.t("vagrant_libvirt.not_running"))
env[:ui].info(I18n.t('vagrant_libvirt.not_running'))
@app.call(env)
end
end

View File

@ -2,12 +2,12 @@ module VagrantPlugins
module ProviderLibvirt
module Action
class MessageNotSuspended
def initialize(app, env)
def initialize(app, _env)
@app = app
end
def call(env)
env[:ui].info(I18n.t("vagrant_libvirt.not_suspended"))
env[:ui].info(I18n.t('vagrant_libvirt.not_suspended'))
@app.call(env)
end
end

View File

@ -14,14 +14,15 @@ module VagrantPlugins
def call(env)
env[:ui].info(I18n.t('vagrant_libvirt.package_domain'))
libvirt_domain = env[:machine].provider.driver.connection.client.lookup_domain_by_uuid(
env[:machine].id)
libvirt_domain = env[:machine].provider.driver.connection.client.lookup_domain_by_uuid(
env[:machine].id
)
domain = env[:machine].provider.driver.connection.servers.get(env[:machine].id.to_s)
root_disk = domain.volumes.select do |x|
x.name == libvirt_domain.name + '.img'
end.first
boxname = env['package.output']
raise "#{boxname}: Already exists" if File.exists?(boxname)
raise "#{boxname}: Already exists" if File.exist?(boxname)
@tmp_dir = Dir.pwd + '/_tmp_package'
@tmp_img = @tmp_dir + '/box.img'
Dir.mkdir(@tmp_dir)
@ -37,11 +38,11 @@ module VagrantPlugins
`qemu-img rebase -p -b "" #{@tmp_img}`
# remove hw association with interface
# working for centos with lvs default disks
`virt-sysprep --no-logfile --operations defaults,-ssh-userdir -a #{@tmp_img} `
`virt-sysprep --no-logfile --operations defaults,-ssh-userdir -a #{@tmp_img}`
Dir.chdir(@tmp_dir)
img_size = `qemu-img info #{@tmp_img} | grep 'virtual size' | awk '{print $3;}' | tr -d 'G'`.chomp
File.write(@tmp_dir + '/metadata.json', metadata_content(img_size))
File.write(@tmp_dir + '/Vagrantfile',vagrantfile_content)
File.write(@tmp_dir + '/Vagrantfile', vagrantfile_content)
assebmle_box(boxname)
FileUtils.mv(@tmp_dir + '/' + boxname, '../' + boxname)
FileUtils.rm_rf(@tmp_dir)

View File

@ -8,9 +8,9 @@ module VagrantPlugins
class PrepareNFSSettings
include Vagrant::Action::Builtin::MixinSyncedFolders
def initialize(app,env)
def initialize(app, _env)
@app = app
@logger = Log4r::Logger.new("vagrant::action::vm::nfs")
@logger = Log4r::Logger.new('vagrant::action::vm::nfs')
end
def call(env)
@ -18,7 +18,7 @@ module VagrantPlugins
@app.call(env)
if using_nfs?
@logger.info("Using NFS, preparing NFS settings by reading host IP and machine IP")
@logger.info('Using NFS, preparing NFS settings by reading host IP and machine IP')
env[:nfs_machine_ip] = read_machine_ip(env[:machine])
env[:nfs_host_ip] = read_host_ip(env[:nfs_machine_ip])
@ -41,7 +41,7 @@ module VagrantPlugins
# @return [String]
def read_host_ip(ip)
UDPSocket.open do |s|
if(ip.kind_of?(Array))
if ip.is_a?(Array)
s.connect(ip.last, 1)
else
s.connect(ip, 1)
@ -49,6 +49,7 @@ module VagrantPlugins
s.addr.last
end
end
# Returns the IP address of the guest
#
# @param [Machine] machine
@ -60,7 +61,7 @@ module VagrantPlugins
# check other ips
command = "ip=$(which ip); ${ip:-/sbin/ip} addr show | grep -i 'inet ' | grep -v '127.0.0.1' | tr -s ' ' | cut -d' ' -f3 | cut -d'/' -f 1"
result = ""
result = ''
machine.communicate.execute(command) do |type, data|
result << data if type == :stdout
end

View File

@ -2,9 +2,9 @@ module VagrantPlugins
module ProviderLibvirt
module Action
class PrepareNFSValidIds
def initialize(app, env)
def initialize(app, _env)
@app = app
@logger = Log4r::Logger.new("vagrant::action::vm::nfs")
@logger = Log4r::Logger.new('vagrant::action::vm::nfs')
end
def call(env)

View File

@ -3,8 +3,7 @@ module VagrantPlugins
module ProviderLibvirt
module Action
class PruneNFSExports
def initialize(app, env)
def initialize(app, _env)
@app = app
end
@ -16,7 +15,8 @@ module VagrantPlugins
# not exiisted in array will removed from nfs
uuids.delete(uuid)
env[:host].capability(
:nfs_prune, env[:machine].ui, uuids)
:nfs_prune, env[:machine].ui, uuids
)
end
@app.call(env)

View File

@ -1,12 +1,12 @@
require "log4r"
require 'log4r'
module VagrantPlugins
module ProviderLibvirt
module Action
class ReadMacAddresses
def initialize(app, env)
def initialize(app, _env)
@app = app
@logger = Log4r::Logger.new("vagrant_libvirt::action::read_mac_addresses")
@logger = Log4r::Logger.new('vagrant_libvirt::action::read_mac_addresses')
end
def call(env)
@ -19,21 +19,19 @@ module VagrantPlugins
domain = libvirt.client.lookup_domain_by_uuid(machine.id)
if domain.nil?
@logger.info("Machine could not be found, assuming it got destroyed")
@logger.info('Machine could not be found, assuming it got destroyed')
machine.id = nil
return nil
end
xml = Nokogiri::XML(domain.xml_desc)
mac = xml.xpath("/domain/devices/interface/mac/@address")
mac = xml.xpath('/domain/devices/interface/mac/@address')
if mac.length == 0
return {}
end
return {} if mac.empty?
Hash[mac.each_with_index.map do |x,i|
Hash[mac.each_with_index.map do |x, i|
@logger.debug("interface[#{i}] = #{x.value}")
[i,x.value]
[i, x.value]
end]
end
end

View File

@ -4,14 +4,14 @@ module VagrantPlugins
module ProviderLibvirt
module Action
class RemoveLibvirtImage
def initialize(app, env)
@logger = Log4r::Logger.new("vagrant_libvirt::action::remove_libvirt_image")
def initialize(app, _env)
@logger = Log4r::Logger.new('vagrant_libvirt::action::remove_libvirt_image')
@app = app
end
def call(env)
env[:ui].info("Vagrant-libvirt plugin removed box only from you LOCAL ~/.vagrant/boxes directory")
env[:ui].info("From libvirt storage pool you have to delete image manually(virsh, virt-manager or by any other tool)")
env[:ui].info('Vagrant-libvirt plugin removed box only from you LOCAL ~/.vagrant/boxes directory')
env[:ui].info('From libvirt storage pool you have to delete image manually(virsh, virt-manager or by any other tool)')
@app.call(env)
end
end

View File

@ -1,15 +1,14 @@
require 'log4r'
#require 'log4r/yamlconfigurator'
# require 'log4r/yamlconfigurator'
module VagrantPlugins
module ProviderLibvirt
module Action
class RemoveStaleVolume
def initialize(app, _env)
# log4r_config= YAML.load_file(File.join(File.dirname(__FILE__),"log4r.yaml"))
# log_cfg = Log4r::YamlConfigurator
# log_cfg.decode_yaml( log4r_config['log4r_config'] )
# log4r_config= YAML.load_file(File.join(File.dirname(__FILE__),"log4r.yaml"))
# log_cfg = Log4r::YamlConfigurator
# log_cfg.decode_yaml( log4r_config['log4r_config'] )
@logger = Log4r::Logger.new('vagrant_libvirt::action::remove_stale_volume')
@app = app
@ -22,7 +21,8 @@ module VagrantPlugins
config = env[:machine].provider_config
# Check for storage pool, where box image should be created
fog_pool = ProviderLibvirt::Util::Collection.find_matching(
env[:machine].provider.driver.connection.pools.all, config.storage_pool_name)
env[:machine].provider.driver.connection.pools.all, config.storage_pool_name
)
@logger.debug("**** Pool #{fog_pool.name}")
# This is name of newly created image for vm.
@ -31,7 +31,8 @@ module VagrantPlugins
# remove root storage
box_volume = ProviderLibvirt::Util::Collection.find_matching(
env[:machine].provider.driver.connection.volumes.all, name)
env[:machine].provider.driver.connection.volumes.all, name
)
if box_volume && box_volume.pool_name == fog_pool.name
@logger.info("Deleting volume #{box_volume.key}")
box_volume.destroy

View File

@ -5,18 +5,18 @@ module VagrantPlugins
module Action
# Resume suspended domain.
class ResumeDomain
def initialize(app, env)
@logger = Log4r::Logger.new("vagrant_libvirt::action::resume_domain")
def initialize(app, _env)
@logger = Log4r::Logger.new('vagrant_libvirt::action::resume_domain')
@app = app
end
def call(env)
env[:ui].info(I18n.t("vagrant_libvirt.resuming_domain"))
env[:ui].info(I18n.t('vagrant_libvirt.resuming_domain'))
domain = env[:machine].provider.driver.connection.servers.get(env[:machine].id.to_s)
raise Errors::NoDomainError if domain == nil
raise Errors::NoDomainError if domain.nil?
libvirt_domain = env[:machine].provider.driver.connection.client.lookup_domain_by_uuid(env[:machine].id)
libvirt_domain = env[:machine].provider.driver.connection.client.lookup_domain_by_uuid(env[:machine].id)
config = env[:machine].provider_config
if config.suspend_mode == 'managedsave'
domain.start

View File

@ -2,11 +2,10 @@ require 'securerandom'
module VagrantPlugins
module ProviderLibvirt
module Action
# Setup name for domain and domain volumes.
class SetNameOfDomain
def initialize(app, env)
@logger = Log4r::Logger.new("vagrant_libvirt::action::set_name_of_domain")
def initialize(app, _env)
@logger = Log4r::Logger.new('vagrant_libvirt::action::set_name_of_domain')
@app = app
end
@ -14,14 +13,15 @@ module VagrantPlugins
env[:domain_name] = build_domain_name(env)
begin
@logger.info("Looking for domain #{env[:domain_name]} through list " +
@logger.info("Looking for domain #{env[:domain_name]} through list " \
"#{env[:machine].provider.driver.connection.servers.all}")
# Check if the domain name is not already taken
domain = ProviderLibvirt::Util::Collection.find_matching(
env[:machine].provider.driver.connection.servers.all, env[:domain_name])
env[:machine].provider.driver.connection.servers.all, env[:domain_name]
)
rescue Fog::Errors::Error => e
@logger.info("#{e}")
@logger.info(e.to_s)
domain = nil
end
@ -29,7 +29,7 @@ module VagrantPlugins
unless domain.nil?
raise ProviderLibvirt::Errors::DomainNameExists,
:domain_name => env[:domain_name]
domain_name: env[:domain_name]
end
@app.call(env)
@ -46,21 +46,19 @@ module VagrantPlugins
config = env[:machine].provider_config
domain_name =
if config.default_prefix.nil?
env[:root_path].basename.to_s.dup.concat("_")
env[:root_path].basename.to_s.dup.concat('_')
elsif config.default_prefix.empty?
# don't have any prefix, not even "_"
""
''
else
config.default_prefix.to_s.dup.concat("_")
config.default_prefix.to_s.dup.concat('_')
end
domain_name << env[:machine].name.to_s
domain_name.gsub!(/[^-a-z0-9_\.]/i, '')
domain_name << "_#{Time.now.utc.to_i}_#{SecureRandom.hex(10)}" if config.random_hostname
domain_name
end
end
end
end
end

View File

@ -1,13 +1,13 @@
require 'pathname'
require "log4r"
require 'log4r'
module VagrantPlugins
module ProviderLibvirt
module Action
class ShareFolders
def initialize(app, env)
@logger = Log4r::Logger.new("vagrant::action::vm::share_folders")
def initialize(app, _env)
@logger = Log4r::Logger.new('vagrant::action::vm::share_folders')
@app = app
end
@ -37,36 +37,34 @@ module VagrantPlugins
# Prepares the shared folders by verifying they exist and creating them
# if they don't.
def prepare_folders
shared_folders.each do |id, options|
shared_folders.each do |_id, options|
hostpath = Pathname.new(options[:hostpath]).expand_path(@env[:root_path])
if !hostpath.directory? && options[:create]
# Host path doesn't exist, so let's create it.
@logger.debug("Host path doesn't exist, creating: #{hostpath}")
next unless !hostpath.directory? && options[:create]
# Host path doesn't exist, so let's create it.
@logger.debug("Host path doesn't exist, creating: #{hostpath}")
begin
hostpath.mkpath
rescue Errno::EACCES
raise Vagrant::Errors::SharedFolderCreateFailed,
:path => hostpath.to_s
end
begin
hostpath.mkpath
rescue Errno::EACCES
raise Vagrant::Errors::SharedFolderCreateFailed,
path: hostpath.to_s
end
end
end
def create_metadata
@env[:ui].info I18n.t("vagrant.actions.vm.share_folders.creating")
@env[:ui].info I18n.t('vagrant.actions.vm.share_folders.creating')
folders = []
shared_folders.each do |id, data|
folders << {
:name => id,
:hostpath => File.expand_path(data[:hostpath], @env[:root_path]),
:transient => data[:transient]
name: id,
hostpath: File.expand_path(data[:hostpath], @env[:root_path]),
transient: data[:transient]
}
end
end
end
end
end

View File

@ -6,25 +6,25 @@ module VagrantPlugins
module Action
# Just start the domain.
class StartDomain
def initialize(app, env)
@logger = Log4r::Logger.new("vagrant_libvirt::action::start_domain")
def initialize(app, _env)
@logger = Log4r::Logger.new('vagrant_libvirt::action::start_domain')
@app = app
end
def call(env)
env[:ui].info(I18n.t("vagrant_libvirt.starting_domain"))
env[:ui].info(I18n.t('vagrant_libvirt.starting_domain'))
domain = env[:machine].provider.driver.connection.servers.get(env[:machine].id.to_s)
raise Errors::NoDomainError if domain == nil
raise Errors::NoDomainError if domain.nil?
config = env[:machine].provider_config
begin
# update domain settings on change.
libvirt_domain = env[:machine].provider.driver.connection.client.lookup_domain_by_uuid(env[:machine].id)
libvirt_domain = env[:machine].provider.driver.connection.client.lookup_domain_by_uuid(env[:machine].id)
if config.memory.to_i*1024 != libvirt_domain.max_memory
libvirt_domain.max_memory = config.memory.to_i*1024
if config.memory.to_i * 1024 != libvirt_domain.max_memory
libvirt_domain.max_memory = config.memory.to_i * 1024
libvirt_domain.memory = libvirt_domain.max_memory
end
begin
@ -34,46 +34,44 @@ module VagrantPlugins
descr_changed = false
# additional disk bus
config.disks.each {|disk|
config.disks.each do |disk|
device = disk[:device]
bus = disk[:bus]
REXML::XPath.each(xml_descr,'/domain/devices/disk[@device="disk"]/target[@dev="'+device+'"]') {|disk_target|
if disk_target.attributes['bus'] != bus
descr_changed = true
disk_target.attributes['bus'] = bus
disk_target.parent.delete_element("#{disk_target.parent.xpath}/address")
end
}
}
# disk_bus
REXML::XPath.each(xml_descr,'/domain/devices/disk[@device="disk"]/target[@dev="vda"]') {|disk_target|
if disk_target.attributes['bus'] != config.disk_bus
REXML::XPath.each(xml_descr, '/domain/devices/disk[@device="disk"]/target[@dev="' + device + '"]') do |disk_target|
next unless disk_target.attributes['bus'] != bus
descr_changed = true
disk_target.attributes['bus'] = config.disk_bus
disk_target.attributes['bus'] = bus
disk_target.parent.delete_element("#{disk_target.parent.xpath}/address")
end
}
end
# disk_bus
REXML::XPath.each(xml_descr, '/domain/devices/disk[@device="disk"]/target[@dev="vda"]') do |disk_target|
next unless disk_target.attributes['bus'] != config.disk_bus
descr_changed = true
disk_target.attributes['bus'] = config.disk_bus
disk_target.parent.delete_element("#{disk_target.parent.xpath}/address")
end
# Iterface type
REXML::XPath.each(xml_descr,'/domain/devices/interface/model') {|iface_model|
REXML::XPath.each(xml_descr, '/domain/devices/interface/model') do |iface_model|
if iface_model.attributes['type'] != config.nic_model_type
descr_changed = true
iface_model.attributes['type'] = config.nic_model_type
end
}
end
# vCpu count
if config.cpus.to_i != libvirt_domain.vcpus.length
descr_changed = true
REXML::XPath.first(xml_descr,'/domain/vcpu').text = config.cpus
REXML::XPath.first(xml_descr, '/domain/vcpu').text = config.cpus
end
# cpu_mode
cpu = REXML::XPath.first(xml_descr,'/domain/cpu')
cpu = REXML::XPath.first(xml_descr, '/domain/cpu')
if cpu.nil?
descr_changed = true
cpu = REXML::Element.new('cpu', REXML::XPath.first(xml_descr,'/domain'))
cpu = REXML::Element.new('cpu', REXML::XPath.first(xml_descr, '/domain'))
cpu.attributes['mode'] = config.cpu_mode
else
if cpu.attributes['mode'] != config.cpu_mode
@ -83,10 +81,10 @@ module VagrantPlugins
end
if config.cpu_mode != 'host-passthrough'
cpu_model = REXML::XPath.first(xml_descr,'/domain/cpu/model')
cpu_model = REXML::XPath.first(xml_descr, '/domain/cpu/model')
if cpu_model.nil?
descr_changed = true
cpu_model = REXML::Element.new('model', REXML::XPath.first(xml_descr,'/domain/cpu'))
cpu_model = REXML::Element.new('model', REXML::XPath.first(xml_descr, '/domain/cpu'))
cpu_model.attributes['fallback'] = 'allow'
cpu_model.text = config.cpu_model
else
@ -99,46 +97,46 @@ module VagrantPlugins
cpu_model.attributes['fallback'] = config.cpu_fallback
end
end
vmx_feature = REXML::XPath.first(xml_descr,'/domain/cpu/feature[@name="vmx"]')
svm_feature = REXML::XPath.first(xml_descr,'/domain/cpu/feature[@name="svm"]')
vmx_feature = REXML::XPath.first(xml_descr, '/domain/cpu/feature[@name="vmx"]')
svm_feature = REXML::XPath.first(xml_descr, '/domain/cpu/feature[@name="svm"]')
if config.nested
if vmx_feature.nil?
descr_changed = true
vmx_feature = REXML::Element.new('feature', REXML::XPath.first(xml_descr,'/domain/cpu'))
vmx_feature = REXML::Element.new('feature', REXML::XPath.first(xml_descr, '/domain/cpu'))
vmx_feature.attributes['policy'] = 'optional'
vmx_feature.attributes['name'] = 'vmx'
end
if svm_feature.nil?
descr_changed = true
svm_feature = REXML::Element.new('feature', REXML::XPath.first(xml_descr,'/domain/cpu'))
svm_feature = REXML::Element.new('feature', REXML::XPath.first(xml_descr, '/domain/cpu'))
svm_feature.attributes['policy'] = 'optional'
svm_feature.attributes['name'] = 'svm'
end
else
if !vmx_feature.nil?
unless vmx_feature.nil?
descr_changed = true
cpu.delete_element(vmx_feature)
end
if !svm_feature.nil?
unless svm_feature.nil?
descr_changed = true
cpu.delete_element(svm_feature)
end
end
else
if cpu.elements.to_a.length > 0
unless cpu.elements.to_a.empty?
descr_changed = true
cpu.elements.each {|elem|
cpu.elements.each do |elem|
cpu.delete_element(elem)
}
end
end
end
# Graphics
graphics = REXML::XPath.first(xml_descr,'/domain/devices/graphics')
graphics = REXML::XPath.first(xml_descr, '/domain/devices/graphics')
if config.graphics_type != 'none'
if graphics.nil?
if graphics.nil?
descr_changed = true
graphics = REXML::Element.new('graphics', REXML::XPath.first(xml_descr,'/domain/devices'))
graphics = REXML::Element.new('graphics', REXML::XPath.first(xml_descr, '/domain/devices'))
end
if graphics.attributes['type'] != config.graphics_type
descr_changed = true
@ -168,21 +166,19 @@ module VagrantPlugins
graphics.attributes['passwd'] = config.graphics_passwd
end
end
else
# graphics_type = none, remove entire element
if !graphics.nil?
graphics.parent.delete_element(graphics)
end
else
# graphics_type = none, remove entire element
graphics.parent.delete_element(graphics) unless graphics.nil?
end
#TPM
# TPM
if config.tpm_path
raise Errors::FogCreateServerError, "The TPM Path must be fully qualified" unless config.tpm_path[0].chr == '/'
raise Errors::FogCreateServerError, 'The TPM Path must be fully qualified' unless config.tpm_path[0].chr == '/'
tpm = REXML::XPath.first(xml_descr,'/domain/devices/tpm')
tpm = REXML::XPath.first(xml_descr, '/domain/devices/tpm')
if tpm.nil?
descr_changed = true
tpm = REXML::Element.new('tpm', REXML::XPath.first(xml_descr,'/domain/devices/tpm/model'))
tpm = REXML::Element.new('tpm', REXML::XPath.first(xml_descr, '/domain/devices/tpm/model'))
tpm.attributes['model'] = config.tpm_model
tpm_backend_type = tpm.add_element('backend')
tpm_backend_type.attributes['type'] = config.tpm_type
@ -205,15 +201,15 @@ module VagrantPlugins
end
# Video device
video = REXML::XPath.first(xml_descr,'/domain/devices/video')
if !video.nil? and config.graphics_type == 'none'
video = REXML::XPath.first(xml_descr, '/domain/devices/video')
if !video.nil? && (config.graphics_type == 'none')
# graphics_type = none, video devices are removed since there is no possible output
descr_changed = true
video.parent.delete_element(video)
else
video_model = REXML::XPath.first(xml_descr,'/domain/devices/video/model')
video_model = REXML::XPath.first(xml_descr, '/domain/devices/video/model')
if video_model.nil?
video_model = REXML::Element.new('model', REXML::XPath.first(xml_descr,'/domain/devices/video'))
video_model = REXML::Element.new('model', REXML::XPath.first(xml_descr, '/domain/devices/video'))
video_model.attributes['type'] = config.video_type
video_model.attributes['vram'] = config.video_vram
else
@ -227,10 +223,10 @@ module VagrantPlugins
# dtb
if config.dtb
dtb = REXML::XPath.first(xml_descr,'/domain/os/dtb')
dtb = REXML::XPath.first(xml_descr, '/domain/os/dtb')
if dtb.nil?
descr_changed = true
dtb = REXML::Element.new('dtb', REXML::XPath.first(xml_descr,'/domain/os'))
dtb = REXML::Element.new('dtb', REXML::XPath.first(xml_descr, '/domain/os'))
dtb.text = config.dtb
else
if dtb.text != config.dtb
@ -242,10 +238,10 @@ module VagrantPlugins
# kernel and initrd
if config.kernel
kernel= REXML::XPath.first(xml_descr,'/domain/os/kernel')
kernel = REXML::XPath.first(xml_descr, '/domain/os/kernel')
if kernel.nil?
descr_changed = true
kernel = REXML::Element.new('kernel', REXML::XPath.first(xml_descr,'/domain/os'))
kernel = REXML::Element.new('kernel', REXML::XPath.first(xml_descr, '/domain/os'))
kernel.text = config.kernel
else
if kernel.text != config.kernel
@ -255,10 +251,10 @@ module VagrantPlugins
end
end
if config.initrd
initrd = REXML::XPath.first(xml_descr,'/domain/os/initrd')
initrd = REXML::XPath.first(xml_descr, '/domain/os/initrd')
if initrd.nil?
descr_changed = true
initrd = REXML::Element.new('initrd', REXML::XPath.first(xml_descr,'/domain/os'))
initrd = REXML::Element.new('initrd', REXML::XPath.first(xml_descr, '/domain/os'))
initrd.text = config.initrd
else
if initrd.text != config.initrd
@ -272,12 +268,12 @@ module VagrantPlugins
if descr_changed
begin
libvirt_domain.undefine
new_descr = ""
new_descr = ''
xml_descr.write new_descr
server = env[:machine].provider.driver.connection.servers.create(xml: new_descr)
rescue Fog::Errors::Error => e
server = env[:machine].provider.driver.connection.servers.create(xml: descr)
raise Errors::FogCreateServerError, error_message: e.message
raise Errors::FogCreateServerError, error_message: e.message
end
end
rescue => e
@ -288,13 +284,12 @@ module VagrantPlugins
# Actually start the domain
domain.start
rescue => e
raise Errors::FogError, :message => e.message
raise Errors::FogError, message: e.message
end
@app.call(env)
end
end
end
end
end

View File

@ -5,21 +5,21 @@ module VagrantPlugins
module Action
# Suspend domain.
class SuspendDomain
def initialize(app, env)
@logger = Log4r::Logger.new("vagrant_libvirt::action::suspend_domain")
def initialize(app, _env)
@logger = Log4r::Logger.new('vagrant_libvirt::action::suspend_domain')
@app = app
end
# make pause
def call(env)
env[:ui].info(I18n.t("vagrant_libvirt.suspending_domain"))
env[:ui].info(I18n.t('vagrant_libvirt.suspending_domain'))
domain = env[:machine].provider.driver.connection.servers.get(env[:machine].id.to_s)
raise Errors::NoDomainError if domain == nil
raise Errors::NoDomainError if domain.nil?
config = env[:machine].provider_config
if config.suspend_mode == 'managedsave'
libvirt_domain = env[:machine].provider.driver.connection.client.lookup_domain_by_uuid(env[:machine].id)
libvirt_domain = env[:machine].provider.driver.connection.client.lookup_domain_by_uuid(env[:machine].id)
begin
libvirt_domain.managed_save
rescue => e

View File

@ -6,14 +6,13 @@ require 'vagrant/util/retryable'
module VagrantPlugins
module ProviderLibvirt
module Action
# Wait till domain is started, till it obtains an IP address and is
# accessible via ssh.
class WaitTillUp
include Vagrant::Util::Retryable
def initialize(app, env)
@logger = Log4r::Logger.new("vagrant_libvirt::action::wait_till_up")
def initialize(app, _env)
@logger = Log4r::Logger.new('vagrant_libvirt::action::wait_till_up')
@app = app
end
@ -23,63 +22,63 @@ module VagrantPlugins
# Get domain object
domain = env[:machine].provider.driver.get_domain(env[:machine].id.to_s)
if domain == nil
if domain.nil?
raise Errors::NoDomainError,
:error_message => "Domain #{env[:machine].id} not found"
error_message: "Domain #{env[:machine].id} not found"
end
# Wait for domain to obtain an ip address. Ip address is searched
# from arp table, either localy or remotely via ssh, if libvirt
# connection was done via ssh.
env[:ip_address] = nil
env[:metrics]["instance_ip_time"] = Util::Timer.time do
env[:metrics]['instance_ip_time'] = Util::Timer.time do
@logger.debug("Searching for IP for MAC address: #{domain.mac}")
env[:ui].info(I18n.t("vagrant_libvirt.waiting_for_ip"))
retryable(:on => Fog::Errors::TimeoutError, :tries => 300) do
env[:ui].info(I18n.t('vagrant_libvirt.waiting_for_ip'))
retryable(on: Fog::Errors::TimeoutError, tries: 300) do
# If we're interrupted don't worry about waiting
return terminate(env) if env[:interrupted]
# Wait for domain to obtain an ip address
domain.wait_for(2) {
addresses.each_pair do |type, ip|
env[:ip_address] = ip[0] if ip[0] != nil
domain.wait_for(2) do
addresses.each_pair do |_type, ip|
env[:ip_address] = ip[0] unless ip[0].nil?
end
env[:ip_address] != nil
}
!env[:ip_address].nil?
end
end
end
@logger.info("Got IP address #{env[:ip_address]}")
@logger.info("Time for getting IP: #{env[:metrics]["instance_ip_time"]}")
@logger.info("Time for getting IP: #{env[:metrics]['instance_ip_time']}")
# Machine has ip address assigned, now wait till we are able to
# connect via ssh.
env[:metrics]["instance_ssh_time"] = Util::Timer.time do
env[:ui].info(I18n.t("vagrant_libvirt.waiting_for_ssh"))
retryable(:on => Fog::Errors::TimeoutError, :tries => 60) do
env[:metrics]['instance_ssh_time'] = Util::Timer.time do
env[:ui].info(I18n.t('vagrant_libvirt.waiting_for_ssh'))
retryable(on: Fog::Errors::TimeoutError, tries: 60) do
# If we're interrupted don't worry about waiting
next if env[:interrupted]
# Wait till we are able to connect via ssh.
while true
loop do
# If we're interrupted then just back out
break if env[:interrupted]
break if env[:machine].communicate.ready?
sleep 2
end
end
end
end
# if interrupted above, just terminate immediately
return terminate(env) if env[:interrupted]
@logger.info("Time for SSH ready: #{env[:metrics]["instance_ssh_time"]}")
@logger.info("Time for SSH ready: #{env[:metrics]['instance_ssh_time']}")
# Booted and ready for use.
#env[:ui].info(I18n.t("vagrant_libvirt.ready"))
# env[:ui].info(I18n.t("vagrant_libvirt.ready"))
@app.call(env)
end
def recover(env)
return if env["vagrant.error"].is_a?(Vagrant::Errors::VagrantError)
return if env['vagrant.error'].is_a?(Vagrant::Errors::VagrantError)
# Undo the import
terminate(env)
@ -88,7 +87,7 @@ module VagrantPlugins
def terminate(env)
if env[:machine].provider.state.id != :not_created
# If we're not supposed to destroy on error then just return
return if !env[:destroy_on_error]
return unless env[:destroy_on_error]
destroy_env = env.dup
destroy_env.delete(:interrupted)
@ -101,4 +100,3 @@ module VagrantPlugins
end
end
end

View File

@ -1,5 +1,5 @@
require "digest/md5"
require "vagrant/util/retryable"
require 'digest/md5'
require 'vagrant/util/retryable'
module VagrantPlugins
module ProviderLibvirt
@ -8,30 +8,31 @@ module VagrantPlugins
extend Vagrant::Util::Retryable
def self.mount_p9_shared_folder(machine, folders)
folders.each do |name, opts|
folders.each do |_name, opts|
# Expand the guest path so we can handle things like "~/vagrant"
expanded_guest_path = machine.guest.capability(
:shell_expand_guest_path, opts[:guestpath])
:shell_expand_guest_path, opts[:guestpath]
)
# Do the actual creating and mounting
machine.communicate.sudo("mkdir -p #{expanded_guest_path}")
# Mount
mount_tag = Digest::MD5.new.update(opts[:hostpath]).to_s[0,31]
mount_tag = Digest::MD5.new.update(opts[:hostpath]).to_s[0, 31]
mount_opts="-o trans=virtio"
mount_opts = '-o trans=virtio'
mount_opts += ",access=#{opts[:owner]}" if opts[:owner]
mount_opts += ",version=#{opts[:version]}" if opts[:version]
mount_opts += ",#{opts[:mount_opts]}" if opts[:mount_opts]
mount_command = "mount -t 9p #{mount_opts} '#{mount_tag}' #{expanded_guest_path}"
retryable(:on => Vagrant::Errors::LinuxMountFailed,
:tries => 5,
:sleep => 3) do
retryable(on: Vagrant::Errors::LinuxMountFailed,
tries: 5,
sleep: 3) do
machine.communicate.sudo('modprobe 9p')
machine.communicate.sudo('modprobe 9pnet_virtio')
machine.communicate.sudo(mount_command,
:error_class => Vagrant::Errors::LinuxMountFailed)
error_class: Vagrant::Errors::LinuxMountFailed)
end
end
end

View File

@ -7,7 +7,7 @@ module VagrantPlugins
# and the mac as uppercase string without colons as value
nic_macs = {}
machine.provider.mac_addresses.each do |index, mac|
nic_macs[index+1] = mac.upcase.gsub(':','')
nic_macs[index + 1] = mac.upcase.delete(':')
end
nic_macs
end

View File

@ -1,7 +1,7 @@
require 'log4r'
require 'ostruct'
require 'nokogiri'
require "digest/md5"
require 'digest/md5'
require 'vagrant/util/subprocess'
require 'vagrant/errors'
@ -19,7 +19,7 @@ module VagrantPlugins
@logger = Log4r::Logger.new('vagrant_libvirt::synced_folders::9p')
end
def usable?(machine, raise_error = false)
def usable?(machine, _raise_error = false)
# bail now if not using libvirt since checking version would throw error
return false unless machine.provider_name == :libvirt
@ -36,43 +36,43 @@ module VagrantPlugins
begin
# loop through folders
folders.each do |id, folder_opts|
folder_opts.merge!({ target: id,
accessmode: 'passthrough',
mount: true,
readonly: nil }) { |_k, ov, _nv| ov }
folder_opts.merge!(target: id,
accessmode: 'passthrough',
mount: true,
readonly: nil) { |_k, ov, _nv| ov }
mount_tag = Digest::MD5.new.update(folder_opts[:hostpath]).to_s[0,31]
mount_tag = Digest::MD5.new.update(folder_opts[:hostpath]).to_s[0, 31]
folder_opts[:mount_tag] = mount_tag
machine.ui.info "================\nMachine id: #{machine.id}\nShould be mounting folders\n #{id}, opts: #{folder_opts}"
xml = to_xml('filesystem', folder_opts)
xml = to_xml('filesystem', folder_opts)
# puts "<<<<< XML:\n #{xml}\n >>>>>"
@conn.lookup_domain_by_uuid(machine.id).attach_device(xml, 0)
end
rescue => e
machine.ui.error("could not attach device because: #{e}")
raise VagrantPlugins::ProviderLibvirt::Errors::AttachDeviceError,
error_message: e.message
error_message: e.message
end
end
# TODO once up, mount folders
# TODO: once up, mount folders
def enable(machine, folders, _opts)
# Go through each folder and mount
machine.ui.info('mounting p9 share in guest')
# Only mount folders that have a guest path specified.
mount_folders = {}
folders.each do |id, opts|
if opts[:mount] && opts[:guestpath] && ! opts[:guestpath].empty?
mount_folders[id] = opts.dup
# merge common options if not given
mount_folders[id].merge!(version: '9p2000.L') { |_k, ov, _nv| ov }
end
next unless opts[:mount] && opts[:guestpath] && !opts[:guestpath].empty?
mount_folders[id] = opts.dup
# merge common options if not given
mount_folders[id].merge!(version: '9p2000.L') { |_k, ov, _nv| ov }
end
# Mount the actual folder
machine.guest.capability(
:mount_p9_shared_folder, mount_folders)
:mount_p9_shared_folder, mount_folders
)
end
def cleanup(machine, _opts)
@ -84,7 +84,8 @@ module VagrantPlugins
if machine.id && machine.id != ''
dom = @conn.lookup_domain_by_uuid(machine.id)
Nokogiri::XML(dom.xml_desc).xpath(
'/domain/devices/filesystem').each do |xml|
'/domain/devices/filesystem'
).each do |xml|
dom.detach_device(xml.to_s)
machine.ui.info 'Cleaned up shared folders'
end

View File

@ -3,9 +3,10 @@ require 'vagrant'
class Numeric
Alphabet = ('a'..'z').to_a
def vdev
s, q = '', self
s = ''
q = self
(q, r = (q - 1).divmod(26)) && s.prepend(Alphabet[r]) until q.zero?
'vd'+s
'vd' + s
end
end
@ -141,7 +142,7 @@ module VagrantPlugins
@management_network_address = UNSET_VALUE
@management_network_mode = UNSET_VALUE
@management_network_mac = UNSET_VALUE
@management_network_guest_ipv6 = UNSET_VALUE
@management_network_guest_ipv6 = UNSET_VALUE
# Domain specific settings.
@uuid = UNSET_VALUE
@ -197,11 +198,11 @@ module VagrantPlugins
@pcis = UNSET_VALUE
# Random number device passthrough
@rng = UNSET_VALUE
@rng = UNSET_VALUE
# USB device passthrough
@usbs = UNSET_VALUE
# Redirected devices
@redirdevs = UNSET_VALUE
@redirfilters = UNSET_VALUE
@ -214,28 +215,26 @@ module VagrantPlugins
end
def boot(device)
@boot_order << device # append
@boot_order << device # append
end
def _get_device(disks)
# skip existing devices and also the first one (vda)
exist = disks.collect {|x| x[:device]}+[1.vdev.to_s]
skip = 1 # we're 1 based, not 0 based...
while true do
dev = skip.vdev # get lettered device
if !exist.include?(dev)
return dev
end
skip+=1
exist = disks.collect { |x| x[:device] } + [1.vdev.to_s]
skip = 1 # we're 1 based, not 0 based...
loop do
dev = skip.vdev # get lettered device
return dev unless exist.include?(dev)
skip += 1
end
end
def _get_cdrom_dev(cdroms)
exist = Hash[cdroms.collect{|x| [x[:dev],true]}]
exist = Hash[cdroms.collect { |x| [x[:dev], true] }]
# hda - hdc
curr = "a".ord
while curr <= "d".ord
dev = "hd" + curr.chr
curr = 'a'.ord
while curr <= 'd'.ord
dev = 'hd' + curr.chr
if exist[dev]
curr += 1
next
@ -249,9 +248,7 @@ module VagrantPlugins
end
def _generate_numa
if @cpus % @numa_nodes != 0
raise 'NUMA nodes must be a factor of CPUs'
end
raise 'NUMA nodes must be a factor of CPUs' if @cpus % @numa_nodes != 0
if @memory % @numa_nodes != 0
raise 'NUMA nodes must be a factor of memory'
@ -265,152 +262,116 @@ module VagrantPlugins
numa_cpu = Array(numa_cpu_start..numa_cpu_end).join(',')
numa_mem = @memory / @numa_nodes
numa.push({
id: node,
cpu: numa_cpu,
mem: numa_mem
})
numa.push(id: node,
cpu: numa_cpu,
mem: numa_mem)
end
@numa_nodes = numa
end
def cpu_feature(options={})
def cpu_feature(options = {})
if options[:name].nil? || options[:policy].nil?
raise 'CPU Feature name AND policy must be specified'
end
if @cpu_features == UNSET_VALUE
@cpu_features = []
end
@cpu_features = [] if @cpu_features == UNSET_VALUE
@cpu_features.push({
name: options[:name],
policy: options[:policy]
})
@cpu_features.push(name: options[:name],
policy: options[:policy])
end
def input(options={})
def input(options = {})
if options[:type].nil? || options[:bus].nil?
raise 'Input type AND bus must be specified'
end
if @inputs == UNSET_VALUE
@inputs = []
end
@inputs = [] if @inputs == UNSET_VALUE
@inputs.push({
type: options[:type],
bus: options[:bus]
})
@inputs.push(type: options[:type],
bus: options[:bus])
end
def channel(options={})
def channel(options = {})
if options[:type].nil?
raise "Channel type must be specified."
raise 'Channel type must be specified.'
elsif options[:type] == 'unix' && options[:target_type] == 'guestfwd'
# Guest forwarding requires a target (ip address) and a port
if options[:target_address].nil? || options[:target_port].nil? ||
options[:source_path].nil?
raise 'guestfwd requires target_address, target_port and source_path'
end
# Guest forwarding requires a target (ip address) and a port
if options[:target_address].nil? || options[:target_port].nil? ||
options[:source_path].nil?
raise 'guestfwd requires target_address, target_port and source_path'
end
end
if @channels == UNSET_VALUE
@channels = []
end
@channels = [] if @channels == UNSET_VALUE
@channels.push({
type: options[:type],
source_mode: options[:source_mode],
source_path: options[:source_path],
target_address: options[:target_address],
target_name: options[:target_name],
target_port: options[:target_port],
target_type: options[:target_type]
})
@channels.push(type: options[:type],
source_mode: options[:source_mode],
source_path: options[:source_path],
target_address: options[:target_address],
target_name: options[:target_name],
target_port: options[:target_port],
target_type: options[:target_type])
end
def random(options={})
if !options[:model].nil? && options[:model] != "random"
def random(options = {})
if !options[:model].nil? && options[:model] != 'random'
raise 'The only supported rng backend is "random".'
end
if @rng == UNSET_VALUE
@rng = {}
end
@rng = {} if @rng == UNSET_VALUE
@rng[:model] = options[:model]
end
def pci(options={})
def pci(options = {})
if options[:bus].nil? || options[:slot].nil? || options[:function].nil?
raise 'Bus AND slot AND function must be specified. Check `lspci` for that numbers.'
end
if @pcis == UNSET_VALUE
@pcis = []
end
@pcis = [] if @pcis == UNSET_VALUE
@pcis.push({
bus: options[:bus],
slot: options[:slot],
function: options[:function]
})
@pcis.push(bus: options[:bus],
slot: options[:slot],
function: options[:function])
end
def usb(options={})
def usb(options = {})
if (options[:bus].nil? || options[:device].nil?) && options[:vendor].nil? && options[:product].nil?
raise 'Bus and device and/or vendor and/or product must be specified. Check `lsusb` for these.'
end
if @usbs == UNSET_VALUE
@usbs = []
end
@usbs = [] if @usbs == UNSET_VALUE
@usbs.push({
bus: options[:bus],
device: options[:device],
vendor: options[:vendor],
product: options[:product],
startupPolicy: options[:startupPolicy],
})
@usbs.push(bus: options[:bus],
device: options[:device],
vendor: options[:vendor],
product: options[:product],
startupPolicy: options[:startupPolicy])
end
def redirdev(options={})
if options[:type].nil?
raise 'Type must be specified.'
end
def redirdev(options = {})
raise 'Type must be specified.' if options[:type].nil?
if @redirdevs == UNSET_VALUE
@redirdevs = []
end
@redirdevs = [] if @redirdevs == UNSET_VALUE
@redirdevs.push({
type: options[:type],
})
@redirdevs.push(type: options[:type])
end
def redirfilter(options={})
if options[:allow].nil?
raise 'Option allow must be specified.'
end
def redirfilter(options = {})
raise 'Option allow must be specified.' if options[:allow].nil?
if @redirfilters == UNSET_VALUE
@redirfilters = []
end
@redirfilters = [] if @redirfilters == UNSET_VALUE
@redirfilters.push({
class: options[:class] || -1,
vendor: options[:class] || -1,
product: options[:class] || -1,
version: options[:class] || -1,
allow: options[:allow],
})
@redirfilters.push(class: options[:class] || -1,
vendor: options[:class] || -1,
product: options[:class] || -1,
version: options[:class] || -1,
allow: options[:allow])
end
# NOTE: this will run twice for each time it's needed- keep it idempotent
def storage(storage_type, options={})
def storage(storage_type, options = {})
if storage_type == :file
if options[:device] == :cdrom
_handle_cdrom_storage(options)
@ -420,7 +381,7 @@ module VagrantPlugins
end
end
def _handle_cdrom_storage(options={})
def _handle_cdrom_storage(options = {})
# <disk type="file" device="cdrom">
# <source file="/home/user/virtio-win-0.1-100.iso"/>
# <target dev="hdc"/>
@ -432,39 +393,39 @@ module VagrantPlugins
# as will the address unit number (unit=0, unit=1, etc)
options = {
:bus => "ide",
:path => nil,
bus: 'ide',
path: nil
}.merge(options)
cdrom = {
:dev => options[:dev],
:bus => options[:bus],
:path => options[:path]
dev: options[:dev],
bus: options[:bus],
path: options[:path]
}
@cdroms << cdrom
end
def _handle_disk_storage(options={})
def _handle_disk_storage(options = {})
options = {
:type => 'qcow2',
:size => '10G', # matches the fog default
:path => nil,
:bus => 'virtio'
type: 'qcow2',
size: '10G', # matches the fog default
path: nil,
bus: 'virtio'
}.merge(options)
disk = {
:device => options[:device],
:type => options[:type],
:size => options[:size],
:path => options[:path],
:bus => options[:bus],
:cache => options[:cache] || 'default',
:allow_existing => options[:allow_existing],
:shareable => options[:shareable],
device: options[:device],
type: options[:type],
size: options[:size],
path: options[:path],
bus: options[:bus],
cache: options[:cache] || 'default',
allow_existing: options[:allow_existing],
shareable: options[:shareable]
}
@disks << disk # append
@disks << disk # append
end
# code to generate URI from a config moved out of the connect action
@ -473,30 +434,28 @@ module VagrantPlugins
# Setup connection uri.
uri = @driver.dup
virt_path = case uri
when 'qemu', 'openvz', 'uml', 'phyp', 'parallels', 'kvm'
'/system'
when '@en', 'esx'
'/'
when 'vbox', 'vmwarews', 'hyperv'
'/session'
else
raise "Require specify driver #{uri}"
when 'qemu', 'openvz', 'uml', 'phyp', 'parallels', 'kvm'
'/system'
when '@en', 'esx'
'/'
when 'vbox', 'vmwarews', 'hyperv'
'/session'
else
raise "Require specify driver #{uri}"
end
if uri == 'kvm'
uri = 'qemu' # use qemu uri for kvm domain type
uri = 'qemu' # use qemu uri for kvm domain type
end
if @connect_via_ssh
uri << '+ssh://'
if @username
uri << @username + '@'
end
uri << @username + '@' if @username
if @host
uri << @host
else
uri << 'localhost'
end
uri << if @host
@host
else
'localhost'
end
else
uri << '://'
uri << @host if @host
@ -513,8 +472,8 @@ module VagrantPlugins
uri << @id_ssh_key_file
end
# set path to libvirt socket
uri << "\&socket="+@socket if @socket
return uri
uri << "\&socket=" + @socket if @socket
uri
end
def finalize!
@ -533,21 +492,21 @@ module VagrantPlugins
@management_network_guest_ipv6 = 'yes' if @management_network_guest_ipv6 == UNSET_VALUE
# generate a URI if none is supplied
@uri = _generate_uri() if @uri == UNSET_VALUE
@uri = _generate_uri if @uri == UNSET_VALUE
# Domain specific settings.
@uuid = '' if @uuid == UNSET_VALUE
@memory = 512 if @memory == UNSET_VALUE
@cpus = 1 if @cpus == UNSET_VALUE
@cpu_mode = 'host-model' if @cpu_mode == UNSET_VALUE
@cpu_model = if (@cpu_model == UNSET_VALUE and @cpu_mode == 'custom')
'qemu64'
elsif (@cpu_mode != 'custom')
''
@cpu_model = if (@cpu_model == UNSET_VALUE) && (@cpu_mode == 'custom')
'qemu64'
elsif @cpu_mode != 'custom'
''
end
@cpu_fallback = 'allow' if @cpu_fallback == UNSET_VALUE
@cpu_features = [] if @cpu_features == UNSET_VALUE
@numa_nodes = @numa_nodes == UNSET_VALUE ? nil : _generate_numa()
@numa_nodes = @numa_nodes == UNSET_VALUE ? nil : _generate_numa
@loader = nil if @loader == UNSET_VALUE
@machine_type = nil if @machine_type == UNSET_VALUE
@machine_arch = nil if @machine_arch == UNSET_VALUE
@ -564,7 +523,7 @@ module VagrantPlugins
@graphics_autoport = 'yes' if @graphics_port == UNSET_VALUE
@graphics_autoport = 'no' if @graphics_port != UNSET_VALUE
if (@graphics_type != 'vnc' && @graphics_type != 'spice') ||
@graphics_passwd == UNSET_VALUE
@graphics_passwd == UNSET_VALUE
@graphics_passwd = nil
end
@graphics_port = 5900 if @graphics_port == UNSET_VALUE
@ -595,10 +554,10 @@ module VagrantPlugins
end
# Inputs
@inputs = [{:type => "mouse", :bus => "ps2"}] if @inputs == UNSET_VALUE
@inputs = [{ type: 'mouse', bus: 'ps2' }] if @inputs == UNSET_VALUE
# Channels
@channels = [ ] if @channels == UNSET_VALUE
@channels = [] if @channels == UNSET_VALUE
# PCI device passthrough
@pcis = [] if @pcis == UNSET_VALUE
@ -608,13 +567,13 @@ module VagrantPlugins
# USB device passthrough
@usbs = [] if @usbs == UNSET_VALUE
# Redirected devices
@redirdevs = [] if @redirdevs == UNSET_VALUE
@redirfilters = [] if @redirfilters == UNSET_VALUE
# Suspend mode
@suspend_mode = "pause" if @suspend_mode == UNSET_VALUE
@suspend_mode = 'pause' if @suspend_mode == UNSET_VALUE
# Autostart
@autostart = false if @autostart == UNSET_VALUE
@ -624,7 +583,7 @@ module VagrantPlugins
errors = _detected_errors
machine.provider_config.disks.each do |disk|
if disk[:path] and disk[:path][0] == '/'
if disk[:path] && (disk[:path][0] == '/')
errors << "absolute volume paths like '#{disk[:path]}' not yet supported"
end
end
@ -635,7 +594,7 @@ module VagrantPlugins
end
end
{ "Libvirt Provider" => errors }
{ 'Libvirt Provider' => errors }
end
def merge(other)

View File

@ -4,7 +4,6 @@ require 'log4r'
module VagrantPlugins
module ProviderLibvirt
class Driver
# store the connection at the process level
#
# possibly this should be a connection pool using the connection
@ -34,7 +33,7 @@ module VagrantPlugins
# Setup command for retrieving IP address for newly created machine
# with some MAC address. Get it from dnsmasq leases table
ip_command = %q[ awk "/$mac/ {print \$1}" /proc/net/arp ]
ip_command = %q( awk "/$mac/ {print \$1}" /proc/net/arp )
conn_attr[:libvirt_ip_command] = ip_command
@logger.info("Connecting to Libvirt (#{uri}) ...")
@ -42,7 +41,7 @@ module VagrantPlugins
@@connection = Fog::Compute.new(conn_attr)
rescue Fog::Errors::Error => e
raise Errors::FogLibvirtConnectionError,
:error_message => e.message
error_message: e.message
end
@@connection
@ -81,19 +80,19 @@ module VagrantPlugins
ip_address = nil
begin
domain.wait_for(2) do
addresses.each_pair do |type, ip|
addresses.each_pair do |_type, ip|
# Multiple leases are separated with a newline, return only
# the most recent address
ip_address = ip[0].split("\n").first if ip[0] != nil
ip_address = ip[0].split("\n").first unless ip[0].nil?
end
ip_address != nil
!ip_address.nil?
end
rescue Fog::Errors::TimeoutError
@logger.info("Timeout at waiting for an ip address for machine %s" % machine.name)
@logger.info('Timeout at waiting for an ip address for machine %s' % machine.name)
end
if not ip_address
@logger.info("No arp table entry found for machine %s" % machine.name)
unless ip_address
@logger.info('No arp table entry found for machine %s' % machine.name)
return nil
end
@ -110,11 +109,9 @@ module VagrantPlugins
end
# TODO: terminated no longer appears to be a valid fog state, remove?
if domain.nil? || domain.state.to_sym == :terminated
return :not_created
end
return :not_created if domain.nil? || domain.state.to_sym == :terminated
return domain.state.gsub("-", "_").to_sym
domain.state.tr('-', '_').to_sym
end
end
end

View File

@ -33,7 +33,6 @@ module VagrantPlugins
error_key(:image_upload_error)
end
# Box exceptions
class NoBoxVolume < VagrantLibvirtError
error_key(:no_box_volume)
@ -51,7 +50,6 @@ module VagrantPlugins
error_key(:wrong_box_format)
end
# Fog libvirt exceptions
class FogError < VagrantLibvirtError
error_key(:fog_error)
@ -142,7 +140,6 @@ module VagrantPlugins
class DeleteSnapshotError < VagrantLibvirtError
error_key(:delete_snapshot_error)
end
end
end
end

View File

@ -29,21 +29,20 @@ module VagrantPlugins
hook.after Vagrant::Action::Builtin::BoxRemove, Action.remove_libvirt_image
end
guest_capability('linux', 'mount_p9_shared_folder') do
require_relative 'cap/mount_p9'
Cap::MountP9
end
provider_capability(:libvirt, :nic_mac_addresses) do
require_relative "cap/nic_mac_addresses"
require_relative 'cap/nic_mac_addresses'
Cap::NicMacAddresses
end
# lower priority than nfs or rsync
# https://github.com/vagrant-libvirt/vagrant-libvirt/pull/170
synced_folder("9p", 4) do
require_relative "cap/synced_folder"
synced_folder('9p', 4) do
require_relative 'cap/synced_folder'
VagrantPlugins::SyncedFolder9p::SyncedFolder
end
@ -71,7 +70,7 @@ module VagrantPlugins
# Some constants, such as "true" resolve to booleans, so the
# above error checking doesn't catch it. This will check to make
# sure that the log level is an integer, as Log4r requires.
level = nil if !level.is_a?(Integer)
level = nil unless level.is_a?(Integer)
# Set the logging level on all "vagrant" namespaced
# logs as long as we have a valid level.
@ -88,7 +87,6 @@ module VagrantPlugins
# from the parent logger.
setup_logging
setup_i18n
end
end
end

View File

@ -33,8 +33,7 @@ module VagrantPlugins
# can use this method to load in new data for the actual backing
# machine or to realize that the machine is now gone (the ID can
# become `nil`).
def machine_id_changed
end
def machine_id_changed; end
# This should return a hash of information that explains how to
# SSH into the machine. If the machine is not at a point where
@ -45,12 +44,12 @@ module VagrantPlugins
#
# Ssh info has following format..
#
#{
# {
# :host => "1.2.3.4",
# :port => "22",
# :username => "mitchellh",
# :private_key_path => "/path/to/my/key"
#}
# }
# note that modifing @machine.id or accessing @machine.state is not
# thread safe, so be careful to avoid these here as this method may
# be called from other threads of execution.
@ -60,21 +59,23 @@ module VagrantPlugins
# if can't determine the IP, just return nil and let the core
# deal with it, similar to the docker provider
return nil if !ip
return nil unless ip
ssh_info = {
:host => ip,
:port => @machine.config.ssh.guest_port,
:forward_agent => @machine.config.ssh.forward_agent,
:forward_x11 => @machine.config.ssh.forward_x11,
host: ip,
port: @machine.config.ssh.guest_port,
forward_agent: @machine.config.ssh.forward_agent,
forward_x11: @machine.config.ssh.forward_x11
}
ssh_info[:proxy_command] = (
"ssh '#{@machine.provider_config.host}' " +
"-l '#{@machine.provider_config.username}' " +
"-i '#{@machine.provider_config.id_ssh_key_file}' " +
"nc %h %p"
) if @machine.provider_config.connect_via_ssh
if @machine.provider_config.connect_via_ssh
ssh_info[:proxy_command] =
"ssh '#{@machine.provider_config.host}' " \
"-l '#{@machine.provider_config.username}' " \
"-i '#{@machine.provider_config.id_ssh_key_file}' " \
'nc %h %p'
end
ssh_info
end
@ -94,22 +95,21 @@ module VagrantPlugins
# This should return the state of the machine within this provider.
# The state must be an instance of {MachineState}.
def state
state_id = nil
state_id = :not_created if !@machine.id
state_id = :not_created if (
!state_id && (!@machine.id || !driver.created?(@machine.id)))
state_id = :not_created unless @machine.id
state_id = :not_created if
!state_id && (!@machine.id || !driver.created?(@machine.id))
# Query the driver for the current state of the machine
state_id = driver.state(@machine) if @machine.id && !state_id
state_id = :unknown if !state_id
state_id = :unknown unless state_id
# This is a special pseudo-state so that we don't set the
# NOT_CREATED_ID while we're setting up the machine. This avoids
# clearing the data dir.
state_id = :preparing if @machine.id == "preparing"
state_id = :preparing if @machine.id == 'preparing'
# Get the short and long description
short = state_id.to_s.gsub("_", " ")
short = state_id.to_s.tr('_', ' ')
long = I18n.t("vagrant_libvirt.states.#{state_id}")
# If we're not created, then specify the special ID flag
@ -122,10 +122,9 @@ module VagrantPlugins
end
def to_s
id = @machine.id.nil? ? "new" : @machine.id
id = @machine.id.nil? ? 'new' : @machine.id
"Libvirt (#{id})"
end
end
end
end

View File

@ -3,10 +3,9 @@ module VagrantPlugins
module Util
autoload :ErbTemplate, 'vagrant-libvirt/util/erb_template'
autoload :Collection, 'vagrant-libvirt/util/collection'
autoload :Timer, 'vagrant-libvirt/util/timer'
autoload :NetworkUtil, 'vagrant-libvirt/util/network_util'
autoload :ErrorCodes, 'vagrant-libvirt/util/error_codes'
autoload :Timer, 'vagrant-libvirt/util/timer'
autoload :NetworkUtil, 'vagrant-libvirt/util/network_util'
autoload :ErrorCodes, 'vagrant-libvirt/util/error_codes'
end
end
end

View File

@ -2,7 +2,6 @@ module VagrantPlugins
module ProviderLibvirt
module Util
module Collection
# This method finds a matching _thing_ in a collection of
# _things_. This works matching if the ID or NAME equals to
# `name`. Or, if `name` is a regexp, a partial match is chosen
@ -14,9 +13,7 @@ module VagrantPlugins
nil
end
end
end
end
end

View File

@ -4,22 +4,18 @@ module VagrantPlugins
module ProviderLibvirt
module Util
module ErbTemplate
# TODO might be a chance to use vagrant template system according to https://github.com/mitchellh/vagrant/issues/3231
def to_xml template_name = nil, data = binding
erb = template_name || self.class.to_s.split("::").last.downcase
path = File.join(File.dirname(__FILE__), "..", "templates",
# TODO: might be a chance to use vagrant template system according to https://github.com/mitchellh/vagrant/issues/3231
def to_xml(template_name = nil, data = binding)
erb = template_name || self.class.to_s.split('::').last.downcase
path = File.join(File.dirname(__FILE__), '..', 'templates',
"#{erb}.xml.erb")
template = File.read(path)
# TODO according to erubis documentation, we should rather use evaluate and forget about
# TODO: according to erubis documentation, we should rather use evaluate and forget about
# binding since the template may then change variables values
Erubis::Eruby.new(template, :trim => true).result(data)
Erubis::Eruby.new(template, trim: true).result(data)
end
end
end
end
end

View File

@ -6,19 +6,19 @@ module VagrantPlugins
VIR_ERR_OK = 0
VIR_ERR_INTERNAL_ERROR = 1 # internal error
VIR_ERR_NO_MEMORY = 2 # memory allocation failure
VIR_ERR_NO_SUPPORT = 3 # no support for this function
VIR_ERR_UNKNOWN_HOST = 4 # could not resolve hostname
VIR_ERR_NO_CONNECT = 5 # can't connect to hypervisor
VIR_ERR_INVALID_CONN = 6 # invalid connection object
VIR_ERR_INVALID_DOMAIN = 7 # invalid domain object
VIR_ERR_NO_SUPPORT = 3 # no support for this function
VIR_ERR_UNKNOWN_HOST = 4 # could not resolve hostname
VIR_ERR_NO_CONNECT = 5 # can't connect to hypervisor
VIR_ERR_INVALID_CONN = 6 # invalid connection object
VIR_ERR_INVALID_DOMAIN = 7 # invalid domain object
VIR_ERR_INVALID_ARG = 8 # invalid function argument
VIR_ERR_OPERATION_FAILED = 9 # a command to hypervisor failed
VIR_ERR_OPERATION_FAILED = 9 # a command to hypervisor failed
VIR_ERR_GET_FAILED = 10 # a HTTP GET command to failed
VIR_ERR_POST_FAILED = 11 # a HTTP POST command to failed
VIR_ERR_HTTP_ERROR = 12 # unexpected HTTP error code
VIR_ERR_SEXPR_SERIAL = 13 # failure to serialize an S-Expr
VIR_ERR_NO_XEN = 14 # could not open Xen hypervisor control
VIR_ERR_XEN_CALL = 15 # failure doing an hypervisor call
VIR_ERR_SEXPR_SERIAL = 13 # failure to serialize an S-Expr
VIR_ERR_NO_XEN = 14 # could not open Xen hypervisor control
VIR_ERR_XEN_CALL = 15 # failure doing an hypervisor call
VIR_ERR_OS_TYPE = 16 # unknown OS type
VIR_ERR_NO_KERNEL = 17 # missing kernel information
VIR_ERR_NO_ROOT = 18 # missing root device information
@ -32,31 +32,31 @@ module VagrantPlugins
VIR_ERR_CALL_FAILED = 26 # not supported by the drivers (DEPRECATED)
VIR_ERR_XML_ERROR = 27 # an XML description is not well formed or broken
VIR_ERR_DOM_EXIST = 28 # the domain already exist
VIR_ERR_OPERATION_DENIED = 29 # operation forbidden on read-only connections
VIR_ERR_OPERATION_DENIED = 29 # operation forbidden on read-only connections
VIR_ERR_OPEN_FAILED = 30 # failed to open a conf file
VIR_ERR_READ_FAILED = 31 # failed to read a conf file
VIR_ERR_PARSE_FAILED = 32 # failed to parse a conf file
VIR_ERR_PARSE_FAILED = 32 # failed to parse a conf file
VIR_ERR_CONF_SYNTAX = 33 # failed to parse the syntax of a conf file
VIR_ERR_WRITE_FAILED = 34 # failed to write a conf file
VIR_ERR_XML_DETAIL = 35 # detail of an XML error
VIR_ERR_WRITE_FAILED = 34 # failed to write a conf file
VIR_ERR_XML_DETAIL = 35 # detail of an XML error
VIR_ERR_INVALID_NETWORK = 36 # invalid network object
VIR_ERR_NETWORK_EXIST = 37 # the network already exist
VIR_ERR_SYSTEM_ERROR = 38 # general system call failure
VIR_ERR_RPC = 39 # some sort of RPC error
VIR_ERR_GNUTLS_ERROR = 40 # error from a GNUTLS call
VIR_WAR_NO_NETWORK = 41 # failed to start network
VIR_ERR_GNUTLS_ERROR = 40 # error from a GNUTLS call
VIR_WAR_NO_NETWORK = 41 # failed to start network
VIR_ERR_NO_DOMAIN = 42 # domain not found or unexpectedly disappeared
VIR_ERR_NO_NETWORK = 43 # network not found
VIR_ERR_INVALID_MAC = 44 # invalid MAC address
VIR_ERR_AUTH_FAILED = 45 # authentication failed
VIR_ERR_INVALID_STORAGE_POOL = 46 # invalid storage pool object
VIR_ERR_INVALID_STORAGE_POOL = 46 # invalid storage pool object
VIR_ERR_INVALID_STORAGE_VOL = 47 # invalid storage vol object
VIR_WAR_NO_STORAGE = 48 # failed to start storage
VIR_WAR_NO_STORAGE = 48 # failed to start storage
VIR_ERR_NO_STORAGE_POOL = 49 # storage pool not found
VIR_ERR_NO_STORAGE_VOL = 50 # storage volume not found
VIR_WAR_NO_NODE = 51 # failed to start node driver
VIR_ERR_INVALID_NODE_DEVICE = 52 # invalid node device object
VIR_ERR_NO_NODE_DEVICE = 53 # node device not found
VIR_ERR_NO_NODE_DEVICE = 53 # node device not found
VIR_ERR_NO_SECURITY_MODEL = 54 # security model not found
VIR_ERR_OPERATION_INVALID = 55 # operation is not applicable at this time
VIR_WAR_NO_INTERFACE = 56 # failed to start interface driver
@ -64,32 +64,32 @@ module VagrantPlugins
VIR_ERR_INVALID_INTERFACE = 58 # invalid interface object
VIR_ERR_MULTIPLE_INTERFACES = 59 # more than one matching interface found
VIR_WAR_NO_NWFILTER = 60 # failed to start nwfilter driver
VIR_ERR_INVALID_NWFILTER = 61 # invalid nwfilter object
VIR_ERR_INVALID_NWFILTER = 61 # invalid nwfilter object
VIR_ERR_NO_NWFILTER = 62 # nw filter pool not found
VIR_ERR_BUILD_FIREWALL = 63 # nw filter pool not found
VIR_ERR_BUILD_FIREWALL = 63 # nw filter pool not found
VIR_WAR_NO_SECRET = 64 # failed to start secret storage
VIR_ERR_INVALID_SECRET = 65 # invalid secret
VIR_ERR_INVALID_SECRET = 65 # invalid secret
VIR_ERR_NO_SECRET = 66 # secret not found
VIR_ERR_CONFIG_UNSUPPORTED = 67 # unsupported configuration construct
VIR_ERR_CONFIG_UNSUPPORTED = 67 # unsupported configuration construct
VIR_ERR_OPERATION_TIMEOUT = 68 # timeout occurred during operation
VIR_ERR_MIGRATE_PERSIST_FAILED = 69 # a migration worked, but making the VM persist on the dest host failed
VIR_ERR_HOOK_SCRIPT_FAILED = 70 # a synchronous hook script failed
VIR_ERR_MIGRATE_PERSIST_FAILED = 69 # a migration worked, but making the VM persist on the dest host failed
VIR_ERR_HOOK_SCRIPT_FAILED = 70 # a synchronous hook script failed
VIR_ERR_INVALID_DOMAIN_SNAPSHOT = 71 # invalid domain snapshot
VIR_ERR_NO_DOMAIN_SNAPSHOT = 72 # domain snapshot not found
VIR_ERR_INVALID_STREAM = 73 # stream pointer not valid
VIR_ERR_NO_DOMAIN_SNAPSHOT = 72 # domain snapshot not found
VIR_ERR_INVALID_STREAM = 73 # stream pointer not valid
VIR_ERR_ARGUMENT_UNSUPPORTED = 74 # valid API use but unsupported by the given driver
VIR_ERR_STORAGE_PROBE_FAILED = 75 # storage pool probe failed
VIR_ERR_STORAGE_POOL_BUILT = 76 # storage pool already built
VIR_ERR_STORAGE_POOL_BUILT = 76 # storage pool already built
VIR_ERR_SNAPSHOT_REVERT_RISKY = 77 # force was not requested for a risky domain snapshot revert
VIR_ERR_OPERATION_ABORTED = 78 # operation on a domain was canceled/aborted by user
VIR_ERR_AUTH_CANCELLED = 79 # authentication cancelled
VIR_ERR_NO_DOMAIN_METADATA = 80 # The metadata is not present
VIR_ERR_MIGRATE_UNSAFE = 81 # Migration is not safe
VIR_ERR_OVERFLOW = 82 # integer overflow
VIR_ERR_AUTH_CANCELLED = 79 # authentication cancelled
VIR_ERR_NO_DOMAIN_METADATA = 80 # The metadata is not present
VIR_ERR_MIGRATE_UNSAFE = 81 # Migration is not safe
VIR_ERR_OVERFLOW = 82 # integer overflow
VIR_ERR_BLOCK_COPY_ACTIVE = 83 # action prevented by block copy job
VIR_ERR_OPERATION_UNSUPPORTED = 84 # The requested operation is not supported
VIR_ERR_SSH = 85 # error in ssh transport driver
VIR_ERR_AGENT_UNRESPONSIVE = 86 # guest agent is unresponsive, not running or not usable
VIR_ERR_AGENT_UNRESPONSIVE = 86 # guest agent is unresponsive, not running or not usable
VIR_ERR_RESOURCE_BUSY = 87 # resource is already in use
VIR_ERR_ACCESS_DENIED = 88 # operation on the object/resource was denied
VIR_ERR_DBUS_SERVICE = 89 # error from a dbus service
@ -98,4 +98,3 @@ module VagrantPlugins
end
end
end

View File

@ -19,25 +19,25 @@ module VagrantPlugins
management_network_ip = IPAddr.new(management_network_address)
rescue ArgumentError
raise Errors::ManagementNetworkError,
error_message: "#{management_network_address} is not a valid IP address"
error_message: "#{management_network_address} is not a valid IP address"
end
# capture address into $1 and mask into $2
management_network_ip.inspect =~ /IPv4:(.*)\/(.*)>/
if $2 == '255.255.255.255'
if Regexp.last_match(2) == '255.255.255.255'
raise Errors::ManagementNetworkError,
error_message: "#{management_network_address} does not include both an address and subnet mask"
error_message: "#{management_network_address} does not include both an address and subnet mask"
end
management_network_options = {
iface_type: :private_network,
network_name: management_network_name,
ip: $1,
netmask: $2,
ip: Regexp.last_match(1),
netmask: Regexp.last_match(2),
dhcp_enabled: true,
forward_mode: management_network_mode,
guest_ipv6: management_network_guest_ipv6,
guest_ipv6: management_network_guest_ipv6
}
unless management_network_mac.nil?
@ -45,7 +45,7 @@ module VagrantPlugins
end
# add management network to list of networks to check
networks = [ management_network_options ]
networks = [management_network_options]
env[:machine].config.vm.networks.each do |type, original_options|
logger.debug "In config found network type #{type} options #{original_options}"
@ -59,18 +59,18 @@ module VagrantPlugins
iface_type: type,
netmask: '255.255.255.0',
dhcp_enabled: true,
forward_mode: 'nat',
forward_mode: 'nat'
}.merge(options)
if options[:type].to_s == 'dhcp' && options[:ip].nil?
options[:network_name] = "vagrant-private-dhcp"
options[:network_name] = 'vagrant-private-dhcp'
end
# add to list of networks to check
networks.push(options)
end
return networks
networks
end
# Return a list of all (active and inactive) libvirt networks as a list
@ -84,7 +84,8 @@ module VagrantPlugins
# Iterate over all (active and inactive) networks.
active.concat(inactive).each do |network_name|
libvirt_network = libvirt_client.lookup_network_by_name(
network_name)
network_name
)
# Parse ip address and netmask from the network xml description.
xml = Nokogiri::XML(libvirt_network.xml_desc)
@ -93,19 +94,15 @@ module VagrantPlugins
netmask = xml.xpath('/network/ip/@netmask').first
netmask = netmask.value if netmask
if xml.at_xpath('//network/ip/dhcp')
dhcp_enabled = true
else
dhcp_enabled = false
end
dhcp_enabled = if xml.at_xpath('//network/ip/dhcp')
true
else
false
end
# Calculate network address of network from ip address and
# netmask.
if ip && netmask
network_address = network_address(ip, netmask)
else
network_address = nil
end
network_address = (network_address(ip, netmask) if ip && netmask)
libvirt_networks << {
name: network_name,
@ -123,7 +120,6 @@ module VagrantPlugins
libvirt_networks
end
end
end
end

View File

@ -1,5 +1,5 @@
module VagrantPlugins
module ProviderLibvirt
VERSION = '0.0.36'
VERSION = '0.0.36'.freeze
end
end

View File

@ -1,14 +1,13 @@
require "ostruct"
require "pathname"
require 'ostruct'
require 'pathname'
class EnvironmentHelper
attr_writer :domain_name
attr_accessor :random_hostname, :name, :default_prefix
def [](value)
self.send(value.to_sym)
send(value.to_sym)
end
def cpus
@ -34,15 +33,14 @@ class EnvironmentHelper
end
def root_path
Pathname.new("./spec/support/foo")
Pathname.new('./spec/support/foo')
end
def domain_name
#noop
# noop
end
def libvirt_compute
OpenStruct.new(servers: [])
end
end

View File

@ -1,30 +1,30 @@
require 'fog/libvirt'
shared_context "libvirt" do
include_context "unit"
shared_context 'libvirt' do
include_context 'unit'
let(:libvirt_context) { true }
let(:id) { "dummy-vagrant_dummy" }
let(:connection) { double("connection") }
let(:domain) { double("domain") }
let(:id) { 'dummy-vagrant_dummy' }
let(:connection) { double('connection') }
let(:domain) { double('domain') }
def connection_result(options={})
def connection_result(options = {})
result = options.fetch(:result, nil)
double("connection_result" => result)
double('connection_result' => result)
end
before (:each) do
# we don't want unit tests to ever run commands on the system; so we wire
# in a double to ensure any unexpected messages raise exceptions
stub_const("::Fog::Compute", connection)
stub_const('::Fog::Compute', connection)
# drivers also call vm_exists? during init;
allow(connection).to receive(:servers).with(kind_of(String)).
and_return(connection_result(result: nil))
allow(connection).to receive(:servers).with(kind_of(String))
.and_return(connection_result(result: nil))
# return some information for domain when needed
allow(domain).to receive(:mac).and_return("9C:D5:53:F1:5A:E7")
allow(domain).to receive(:mac).and_return('9C:D5:53:F1:5A:E7')
machine.stub(:id => id)
machine.stub(id: id)
end
end

View File

@ -1,9 +1,10 @@
require 'spec_helper'
shared_context "unit" do
shared_context 'unit' do
include_context 'vagrant-unit'
let(:vagrantfile) do <<-EOF
let(:vagrantfile) do
<<-EOF
Vagrant.configure('2') do |config|
config.vm.define :test
end
@ -15,20 +16,19 @@ shared_context "unit" do
test_env
end
let(:env) { { env: iso_env, machine: machine, ui: ui, root_path: '/rootpath' } }
let(:conf) { Vagrant::Config::V2::DummyConfig.new() }
let(:ui) { Vagrant::UI::Basic.new() }
let(:conf) { Vagrant::Config::V2::DummyConfig.new }
let(:ui) { Vagrant::UI::Basic.new }
let(:iso_env) { test_env.create_vagrant_env ui_class: Vagrant::UI::Basic }
let(:machine) { iso_env.machine(:test, :libvirt) }
# Mock the communicator to prevent SSH commands for being executed.
let(:communicator) { double('communicator') }
# Mock the guest operating system.
let(:guest) { double('guest') }
let(:app) { lambda { |env| } }
let(:plugin) { register_plugin() }
let(:app) { ->(env) {} }
let(:plugin) { register_plugin }
before (:each) do
machine.stub(:guest => guest)
machine.stub(:communicator => communicator)
machine.stub(guest: guest)
machine.stub(communicator: communicator)
end
end

View File

@ -1,51 +1,51 @@
require "spec_helper"
require "support/sharedcontext"
require "support/libvirt_context"
require 'spec_helper'
require 'support/sharedcontext'
require 'support/libvirt_context'
require "vagrant-libvirt/action/destroy_domain"
require 'vagrant-libvirt/action/destroy_domain'
describe VagrantPlugins::ProviderLibvirt::Action::DestroyDomain do
subject { described_class.new(app, env) }
include_context "unit"
include_context "libvirt"
include_context 'unit'
include_context 'libvirt'
let(:libvirt_domain) { double("libvirt_domain") }
let(:libvirt_client) { double("libvirt_client") }
let(:servers) { double("servers") }
let(:libvirt_domain) { double('libvirt_domain') }
let(:libvirt_client) { double('libvirt_client') }
let(:servers) { double('servers') }
describe "#call" do
describe '#call' do
before do
allow_any_instance_of(VagrantPlugins::ProviderLibvirt::Driver).
to receive(:connection).and_return(connection)
allow_any_instance_of(VagrantPlugins::ProviderLibvirt::Driver)
.to receive(:connection).and_return(connection)
allow(connection).to receive(:client).and_return(libvirt_client)
allow(libvirt_client).to receive(:lookup_domain_by_uuid).
and_return(libvirt_domain)
allow(libvirt_client).to receive(:lookup_domain_by_uuid)
.and_return(libvirt_domain)
allow(connection).to receive(:servers).and_return(servers)
allow(servers).to receive(:get).and_return(domain)
# always see this at the start of #call
expect(ui).to receive(:info).with("Removing domain...")
expect(ui).to receive(:info).with('Removing domain...')
end
context "when no snapshots" do
let(:root_disk) { double("libvirt_root_disk") }
context 'when no snapshots' do
let(:root_disk) { double('libvirt_root_disk') }
before do
allow(libvirt_domain).to receive(:list_snapshots).and_return([])
allow(libvirt_domain).to receive(:has_managed_save?).and_return(nil)
root_disk.stub(:name => "test.img")
root_disk.stub(name: 'test.img')
end
context "when only has root disk" do
it "calls fog to destroy volumes" do
expect(domain).to receive(:destroy).with(:destroy_volumes => true)
context 'when only has root disk' do
it 'calls fog to destroy volumes' do
expect(domain).to receive(:destroy).with(destroy_volumes: true)
expect(subject.call(env)).to be_nil
end
end
context "when has additional disks" do
let(:vagrantfile) { <<-EOF
context 'when has additional disks' do
let(:vagrantfile) do
<<-EOF
Vagrant.configure('2') do |config|
config.vm.define :test
config.vm.provider :libvirt do |libvirt|
@ -53,26 +53,27 @@ describe VagrantPlugins::ProviderLibvirt::Action::DestroyDomain do
end
end
EOF
}
let(:extra_disk) { double("libvirt_extra_disk") }
before do
extra_disk.stub(:name => "test-vdb.qcow2")
end
it "destroys disks individually" do
allow(libvirt_domain).to receive(:name).and_return("test")
let(:extra_disk) { double('libvirt_extra_disk') }
before do
extra_disk.stub(name: 'test-vdb.qcow2')
end
it 'destroys disks individually' do
allow(libvirt_domain).to receive(:name).and_return('test')
allow(domain).to receive(:volumes).and_return([extra_disk], [root_disk])
expect(domain).to receive(:destroy).with(:destroy_volumes => false)
expect(extra_disk).to receive(:destroy) # extra disk remove
expect(domain).to receive(:destroy).with(destroy_volumes: false)
expect(extra_disk).to receive(:destroy) # extra disk remove
expect(root_disk).to receive(:destroy) # root disk remove
expect(subject.call(env)).to be_nil
end
end
context "when has CDROMs attached" do
let(:vagrantfile) { <<-EOF
context 'when has CDROMs attached' do
let(:vagrantfile) do
<<-EOF
Vagrant.configure('2') do |config|
config.vm.define :test
config.vm.provider :libvirt do |libvirt|
@ -80,13 +81,13 @@ describe VagrantPlugins::ProviderLibvirt::Action::DestroyDomain do
end
end
EOF
}
end
it "uses explicit removal of disks" do
allow(libvirt_domain).to receive(:name).and_return("test")
it 'uses explicit removal of disks' do
allow(libvirt_domain).to receive(:name).and_return('test')
allow(domain).to receive(:volumes).and_return([root_disk])
expect(domain).to_not receive(:destroy).with(:destroy_volumes => true)
expect(domain).to_not receive(:destroy).with(destroy_volumes: true)
expect(root_disk).to receive(:destroy) # root disk remove
expect(subject.call(env)).to be_nil
end

View File

@ -1,11 +1,11 @@
require "spec_helper"
require 'spec_helper'
describe VagrantPlugins::ProviderLibvirt::Action::SetNameOfDomain do
before :each do
@env = EnvironmentHelper.new
end
it "builds unique domain name" do
it 'builds unique domain name' do
@env.random_hostname = true
dmn = VagrantPlugins::ProviderLibvirt::Action::SetNameOfDomain.new(Object.new, @env)
first = dmn.build_domain_name(@env)
@ -13,8 +13,8 @@ describe VagrantPlugins::ProviderLibvirt::Action::SetNameOfDomain do
first.should_not eq(second)
end
it "builds simple domain name" do
@env.default_prefix= 'pre'
it 'builds simple domain name' do
@env.default_prefix = 'pre'
dmn = VagrantPlugins::ProviderLibvirt::Action::SetNameOfDomain.new(Object.new, @env)
dmn.build_domain_name(@env).should eq('pre_')
end

View File

@ -1,65 +1,64 @@
require "vagrant-libvirt/action/wait_till_up"
require "vagrant-libvirt/errors"
require 'vagrant-libvirt/action/wait_till_up'
require 'vagrant-libvirt/errors'
require "spec_helper"
require "support/sharedcontext"
require "support/libvirt_context"
require 'spec_helper'
require 'support/sharedcontext'
require 'support/libvirt_context'
describe VagrantPlugins::ProviderLibvirt::Action::WaitTillUp do
subject { described_class.new(app, env) }
include_context "vagrant-unit"
include_context "libvirt"
include_context "unit"
include_context 'vagrant-unit'
include_context 'libvirt'
include_context 'unit'
describe "#call" do
describe '#call' do
before do
allow_any_instance_of(VagrantPlugins::ProviderLibvirt::Driver).
to receive(:get_domain).and_return(domain)
allow_any_instance_of(VagrantPlugins::ProviderLibvirt::Driver).to receive(:state).
and_return(:running)
allow_any_instance_of(VagrantPlugins::ProviderLibvirt::Driver)
.to receive(:get_domain).and_return(domain)
allow_any_instance_of(VagrantPlugins::ProviderLibvirt::Driver).to receive(:state)
.and_return(:running)
end
context "when machine does not exist" do
context 'when machine does not exist' do
before do
allow_any_instance_of(VagrantPlugins::ProviderLibvirt::Driver).
to receive(:get_domain).and_return(nil)
allow_any_instance_of(VagrantPlugins::ProviderLibvirt::Driver)
.to receive(:get_domain).and_return(nil)
end
it "raises exception" do
it 'raises exception' do
expect(app).to_not receive(:call)
expect{subject.call(env)}.to raise_error(::VagrantPlugins::ProviderLibvirt::Errors::NoDomainError,
/No domain found. Domain dummy-vagrant_dummy not found/)
expect { subject.call(env) }.to raise_error(::VagrantPlugins::ProviderLibvirt::Errors::NoDomainError,
/No domain found. Domain dummy-vagrant_dummy not found/)
end
end
context "when machine is booting" do
context "if interrupted looking for IP" do
context 'when machine is booting' do
context 'if interrupted looking for IP' do
before do
env[:interrupted] = true
end
it "should exit" do
it 'should exit' do
expect(app).to_not receive(:call)
expect(ui).to receive(:info).with("Waiting for domain to get an IP address...")
expect(ui).to receive(:info).with('Waiting for domain to get an IP address...')
expect(subject.call(env)).to be_nil
end
end
context "if interrupted waiting for SSH" do
context 'if interrupted waiting for SSH' do
before do
allow(domain).to receive(:wait_for).and_return(true)
allow(env).to receive(:[]).and_call_original
allow(env).to receive(:[]).with(:interrupted).and_return(false, true, true)
allow(env).to receive(:[]).with(:ip_address).and_return("192.168.121.2")
allow(env).to receive(:[]).with(:ip_address).and_return('192.168.121.2')
end
it "should exit after getting IP" do
it 'should exit after getting IP' do
expect(app).to_not receive(:call)
expect(ui).to receive(:info).with("Waiting for domain to get an IP address...")
expect(ui).to receive(:info).with("Waiting for SSH to become available...")
expect(ui).to receive(:info).with('Waiting for domain to get an IP address...')
expect(ui).to receive(:info).with('Waiting for SSH to become available...')
logger = subject.instance_variable_get(:@logger)
expect(logger).to receive(:debug).with(/Searching for IP for MAC address: .*/)
expect(logger).to receive(:info).with("Got IP address 192.168.121.2")
expect(logger).to receive(:info).with('Got IP address 192.168.121.2')
expect(logger).to receive(:info).with(/Time for getting IP: .*/)
expect(env[:machine].communicate).to_not receive(:ready?)
expect(subject.call(env)).to be_nil
@ -67,57 +66,57 @@ describe VagrantPlugins::ProviderLibvirt::Action::WaitTillUp do
end
end
context "when machine boots and ssh available" do
context 'when machine boots and ssh available' do
before do
allow(domain).to receive(:wait_for).and_return(true)
allow(env).to receive(:[]).and_call_original
allow(env).to receive(:[]).with(:interrupted).and_return(false)
allow(env).to receive(:[]).with(:ip_address).and_return("192.168.121.2")
allow(env).to receive(:[]).with(:ip_address).and_return('192.168.121.2')
end
it "should call the next hook" do
it 'should call the next hook' do
expect(app).to receive(:call)
expect(ui).to receive(:info).with("Waiting for domain to get an IP address...")
expect(ui).to receive(:info).with("Waiting for SSH to become available...")
expect(ui).to receive(:info).with('Waiting for domain to get an IP address...')
expect(ui).to receive(:info).with('Waiting for SSH to become available...')
expect(env[:machine].communicate).to receive(:ready?).and_return(true)
expect(subject.call(env)).to be_nil
end
end
end
describe "#recover" do
describe '#recover' do
before do
allow_any_instance_of(VagrantPlugins::ProviderLibvirt::Driver).to receive(:get_domain).and_return(machine)
allow_any_instance_of(VagrantPlugins::ProviderLibvirt::Driver).to receive(:state).
and_return(:not_created)
allow_any_instance_of(VagrantPlugins::ProviderLibvirt::Driver).to receive(:state)
.and_return(:not_created)
allow(env).to receive(:[]).and_call_original
end
it "should do nothing by default" do
it 'should do nothing by default' do
expect(env).to_not receive(:[]).with(:action_runner) # cleanup
expect(subject.recover(env)).to be_nil
end
context "with machine coming up" do
context 'with machine coming up' do
before do
allow_any_instance_of(VagrantPlugins::ProviderLibvirt::Driver).to receive(:state).
and_return(:running)
allow_any_instance_of(VagrantPlugins::ProviderLibvirt::Driver).to receive(:state)
.and_return(:running)
env[:destroy_on_error] = true
end
context "and user has disabled destroy on failure" do
context 'and user has disabled destroy on failure' do
before do
env[:destroy_on_error] = false
end
it "skips terminate on failure" do
it 'skips terminate on failure' do
expect(env).to_not receive(:[]).with(:action_runner) # cleanup
expect(subject.recover(env)).to be_nil
end
end
context "and using default settings" do
context 'and using default settings' do
let(:runner) { double('runner') }
it "deletes VM on failure" do
it 'deletes VM on failure' do
expect(env).to receive(:[]).with(:action_runner).and_return(runner) # cleanup
expect(runner).to receive(:run)
expect(subject.recover(env)).to be_nil

View File

@ -1,107 +1,103 @@
require "spec_helper"
require "support/sharedcontext"
require 'spec_helper'
require 'support/sharedcontext'
require "vagrant-libvirt/config"
require 'vagrant-libvirt/config'
describe VagrantPlugins::ProviderLibvirt::Config do
include_context "unit"
include_context 'unit'
def assert_invalid
errors = subject.validate(machine)
if errors.values.any? { |v| !v.empty? }
raise "No errors: #{errors.inspect}"
end
raise "No errors: #{errors.inspect}" if errors.values.any? { |v| !v.empty? }
end
def assert_valid
errors = subject.validate(machine)
if !errors.values.all? { |v| v.empty? }
raise "Errors: #{errors.inspect}"
end
raise "Errors: #{errors.inspect}" unless errors.values.all?(&:empty?)
end
describe "#validate" do
it "is valid with defaults" do
describe '#validate' do
it 'is valid with defaults' do
assert_valid
end
it "is valid if relative path used for disk" do
subject.storage :file, :path => '../path/to/file.qcow2'
it 'is valid if relative path used for disk' do
subject.storage :file, path: '../path/to/file.qcow2'
assert_valid
end
it "should be invalid if absolute path used for disk" do
subject.storage :file, :path => '/absolute/path/to/file.qcow2'
it 'should be invalid if absolute path used for disk' do
subject.storage :file, path: '/absolute/path/to/file.qcow2'
assert_invalid
end
context "with mac defined" do
let (:vm) { double("vm") }
let (:networks) { double("networks") }
context 'with mac defined' do
let (:vm) { double('vm') }
let (:networks) { double('networks') }
before do
allow(vm).to receive(:networks).and_return(networks)
allow(machine.config).to receive(:vm).and_return(vm)
end
it "is valid with valid mac" do
allow(networks).to receive(:each).and_return([:public, {:mac => "aa:bb:cc:dd:ee:ff"}])
it 'is valid with valid mac' do
allow(networks).to receive(:each).and_return([:public, { mac: 'aa:bb:cc:dd:ee:ff' }])
assert_valid
end
it "should be invalid if MAC not formatted correctly" do
allow(networks).to receive(:each).and_return([:public, {:mac => "aabbccddeeff"}])
it 'should be invalid if MAC not formatted correctly' do
allow(networks).to receive(:each).and_return([:public, { mac: 'aabbccddeeff' }])
assert_invalid
end
end
end
describe "#merge" do
describe '#merge' do
let(:one) { described_class.new }
let(:two) { described_class.new }
subject { one.merge(two) }
context "storage" do
context "with disks" do
context "assigned specific devices" do
it "should merge disks with specific devices" do
one.storage(:file, :device => "vdb")
two.storage(:file, :device => "vdc")
context 'storage' do
context 'with disks' do
context 'assigned specific devices' do
it 'should merge disks with specific devices' do
one.storage(:file, device: 'vdb')
two.storage(:file, device: 'vdc')
subject.finalize!
expect(subject.disks).to include(include(:device => "vdb"),
include(:device => "vdc"))
expect(subject.disks).to include(include(device: 'vdb'),
include(device: 'vdc'))
end
end
context "without devices given" do
it "should merge disks with different devices assigned automatically" do
context 'without devices given' do
it 'should merge disks with different devices assigned automatically' do
one.storage(:file)
two.storage(:file)
subject.finalize!
expect(subject.disks).to include(include(:device => "vdb"),
include(:device => "vdc"))
expect(subject.disks).to include(include(device: 'vdb'),
include(device: 'vdc'))
end
end
end
context "with cdroms only" do
context "assigned specific devs" do
it "should merge disks with specific devices" do
one.storage(:file, :device => :cdrom, :dev => "hda")
two.storage(:file, :device => :cdrom, :dev => "hdb")
context 'with cdroms only' do
context 'assigned specific devs' do
it 'should merge disks with specific devices' do
one.storage(:file, device: :cdrom, dev: 'hda')
two.storage(:file, device: :cdrom, dev: 'hdb')
subject.finalize!
expect(subject.cdroms).to include(include(:dev => "hda"),
include(:dev => "hdb"))
expect(subject.cdroms).to include(include(dev: 'hda'),
include(dev: 'hdb'))
end
end
context "without devs given" do
it "should merge cdroms with different devs assigned automatically" do
one.storage(:file, :device => :cdrom)
two.storage(:file, :device => :cdrom)
context 'without devs given' do
it 'should merge cdroms with different devs assigned automatically' do
one.storage(:file, device: :cdrom)
two.storage(:file, device: :cdrom)
subject.finalize!
expect(subject.cdroms).to include(include(:dev => "hda"),
include(:dev => "hdb"))
expect(subject.cdroms).to include(include(dev: 'hda'),
include(dev: 'hdb'))
end
end
end

View File

@ -1,11 +1,10 @@
require "support/sharedcontext"
require 'support/sharedcontext'
require "vagrant-libvirt/config"
require "vagrant-libvirt/util/erb_template"
require 'vagrant-libvirt/config'
require 'vagrant-libvirt/util/erb_template'
describe "templates/domain" do
include_context "unit"
describe 'templates/domain' do
include_context 'unit'
class DomainTemplateHelper < VagrantPlugins::ProviderLibvirt::Config
include VagrantPlugins::ProviderLibvirt::Util::ErbTemplate
@ -14,19 +13,19 @@ describe "templates/domain" do
let(:domain) { DomainTemplateHelper.new }
let(:xml_expected) { File.read(File.join(File.dirname(__FILE__), test_file)) }
context "when only defaults used" do
context 'when only defaults used' do
let(:test_file) { 'domain_defaults.xml' }
it "renders template" do
it 'renders template' do
domain.finalize!
expect(domain.to_xml('domain')).to eq xml_expected
end
end
context "when all settings enabled" do
context 'when all settings enabled' do
before do
domain.instance_variable_set('@domain_type', 'kvm')
domain.cpu_mode = 'custom'
domain.cpu_feature({:name => 'AAA', :policy => 'required'})
domain.cpu_feature(name: 'AAA', policy: 'required')
domain.machine_type = 'pc-compatible'
domain.machine_arch = 'x86_64'
domain.loader = '/efi/loader'
@ -37,32 +36,32 @@ describe "templates/domain" do
domain.instance_variable_set('@domain_volume_path', '/var/lib/libvirt/images/test.qcow2')
domain.instance_variable_set('@domain_volume_cache', 'unsafe')
domain.disk_bus = 'ide'
domain.storage(:file, {:path => 'test-disk1.qcow2'})
domain.storage(:file, {:path => 'test-disk2.qcow2'})
domain.storage(:file, path: 'test-disk1.qcow2')
domain.storage(:file, path: 'test-disk2.qcow2')
domain.disks.each do |disk|
disk[:absolute_path] = '/var/lib/libvirt/images/' + disk[:path]
end
domain.storage(:file, {:device => :cdrom})
domain.storage(:file, {:device => :cdrom})
domain.channel(:type => 'unix',
:target_name => 'org.qemu.guest_agent.0',
:target_type => 'virtio')
domain.channel(:type => 'unix',
:target_type => 'guestfwd',
:target_address => '192.0.2.42',
:target_port => '4242',
:source_path => '/tmp/foo')
domain.random(:model => 'random')
domain.pci(:bus => '0x06', :slot => '0x12', :function => '0x5')
domain.pci(:bus => '0x03', :slot => '0x00', :function => '0x0')
domain.usb(:bus => '1', :device => '2', :vendor => '0x1234', :product => '0xabcd')
domain.redirdev(:type => 'tcp', :host => 'localhost', :port => '4000')
domain.redirfilter(:class => '0x0b', :vendor => '0x08e6',
:product => '0x3437', :version => '2.00', :allow => 'yes')
domain.storage(:file, device: :cdrom)
domain.storage(:file, device: :cdrom)
domain.channel(type: 'unix',
target_name: 'org.qemu.guest_agent.0',
target_type: 'virtio')
domain.channel(type: 'unix',
target_type: 'guestfwd',
target_address: '192.0.2.42',
target_port: '4242',
source_path: '/tmp/foo')
domain.random(model: 'random')
domain.pci(bus: '0x06', slot: '0x12', function: '0x5')
domain.pci(bus: '0x03', slot: '0x00', function: '0x0')
domain.usb(bus: '1', device: '2', vendor: '0x1234', product: '0xabcd')
domain.redirdev(type: 'tcp', host: 'localhost', port: '4000')
domain.redirfilter(class: '0x0b', vendor: '0x08e6',
product: '0x3437', version: '2.00', allow: 'yes')
domain.tpm_path = '/dev/tpm0'
end
let(:test_file) { 'domain_all_settings.xml' }
it "renders template" do
it 'renders template' do
domain.finalize!
expect(domain.to_xml('domain')).to eq xml_expected
end