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

View File

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

View File

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

View File

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

View File

@@ -5,25 +5,25 @@ module VagrantPlugins
module Action module Action
# Halt the domain. # Halt the domain.
class HaltDomain class HaltDomain
def initialize(app, env) def initialize(app, _env)
@logger = Log4r::Logger.new("vagrant_libvirt::action::halt_domain") @logger = Log4r::Logger.new('vagrant_libvirt::action::halt_domain')
@app = app @app = app
end end
def call(env) 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) 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 domain.shutdown
begin begin
domain.wait_for(30) { domain.wait_for(30) do
!ready? !ready?
} end
rescue Fog::Errors::TimeoutError rescue Fog::Errors::TimeoutError
@logger.info("VM is still running. Calling force poweroff.") @logger.info('VM is still running. Calling force poweroff.')
domain.poweroff domain.poweroff
end end
@@ -33,4 +33,3 @@ module VagrantPlugins
end end
end end
end end

View File

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

View File

@@ -8,8 +8,8 @@ module VagrantPlugins
@@lock = Mutex.new @@lock = Mutex.new
def initialize(app, env) def initialize(app, _env)
@logger = Log4r::Logger.new("vagrant_libvirt::action::handle_storage_pool") @logger = Log4r::Logger.new('vagrant_libvirt::action::handle_storage_pool')
@app = app @app = app
end end
@@ -23,7 +23,8 @@ module VagrantPlugins
@@lock.synchronize do @@lock.synchronize do
# Check for storage pool, where box image should be created # Check for storage pool, where box image should be created
break if ProviderLibvirt::Util::Collection.find_matching( 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.") @logger.info("No storage pool '#{config.storage_pool_name}' is available.")
@@ -37,21 +38,20 @@ module VagrantPlugins
# ruby-libvirt client directly. # ruby-libvirt client directly.
begin begin
libvirt_pool = env[:machine].provider.driver.connection.client.define_storage_pool_xml( 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.build
libvirt_pool.create libvirt_pool.create
rescue => e rescue => e
raise Errors::CreatingStoragePoolError, raise Errors::CreatingStoragePoolError,
:error_message => e.message error_message: e.message
end end
raise Errors::NoStoragePool if !libvirt_pool raise Errors::NoStoragePool unless libvirt_pool
end end
@app.call(env) @app.call(env)
end end
end end
end 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 # This can be used with "Call" built-in to check if the machine
# is created and branch in the middleware. # is created and branch in the middleware.
class IsCreated class IsCreated
def initialize(app, env) def initialize(app, _env)
@app = app @app = app
end end

View File

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

View File

@@ -4,16 +4,16 @@ module VagrantPlugins
# This can be used with "Call" built-in to check if the machine # This can be used with "Call" built-in to check if the machine
# is suspended and branch in the middleware. # is suspended and branch in the middleware.
class IsSuspended class IsSuspended
def initialize(app, env) def initialize(app, _env)
@app = app @app = app
end end
def call(env) def call(env)
domain = env[:machine].provider.driver.connection.servers.get(env[:machine].id.to_s) 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 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 config.suspend_mode == 'managedsave'
if libvirt_domain.has_managed_save? if libvirt_domain.has_managed_save?
env[:result] = libvirt_domain.has_managed_save? env[:result] = libvirt_domain.has_managed_save?

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -8,9 +8,9 @@ module VagrantPlugins
class PrepareNFSSettings class PrepareNFSSettings
include Vagrant::Action::Builtin::MixinSyncedFolders include Vagrant::Action::Builtin::MixinSyncedFolders
def initialize(app,env) def initialize(app, _env)
@app = app @app = app
@logger = Log4r::Logger.new("vagrant::action::vm::nfs") @logger = Log4r::Logger.new('vagrant::action::vm::nfs')
end end
def call(env) def call(env)
@@ -18,7 +18,7 @@ module VagrantPlugins
@app.call(env) @app.call(env)
if using_nfs? 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_machine_ip] = read_machine_ip(env[:machine])
env[:nfs_host_ip] = read_host_ip(env[:nfs_machine_ip]) env[:nfs_host_ip] = read_host_ip(env[:nfs_machine_ip])
@@ -41,7 +41,7 @@ module VagrantPlugins
# @return [String] # @return [String]
def read_host_ip(ip) def read_host_ip(ip)
UDPSocket.open do |s| UDPSocket.open do |s|
if(ip.kind_of?(Array)) if ip.is_a?(Array)
s.connect(ip.last, 1) s.connect(ip.last, 1)
else else
s.connect(ip, 1) s.connect(ip, 1)
@@ -49,6 +49,7 @@ module VagrantPlugins
s.addr.last s.addr.last
end end
end end
# Returns the IP address of the guest # Returns the IP address of the guest
# #
# @param [Machine] machine # @param [Machine] machine
@@ -60,7 +61,7 @@ module VagrantPlugins
# check other ips # 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" 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| machine.communicate.execute(command) do |type, data|
result << data if type == :stdout result << data if type == :stdout
end end

View File

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

View File

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

View File

@@ -1,12 +1,12 @@
require "log4r" require 'log4r'
module VagrantPlugins module VagrantPlugins
module ProviderLibvirt module ProviderLibvirt
module Action module Action
class ReadMacAddresses class ReadMacAddresses
def initialize(app, env) def initialize(app, _env)
@app = app @app = app
@logger = Log4r::Logger.new("vagrant_libvirt::action::read_mac_addresses") @logger = Log4r::Logger.new('vagrant_libvirt::action::read_mac_addresses')
end end
def call(env) def call(env)
@@ -19,21 +19,19 @@ module VagrantPlugins
domain = libvirt.client.lookup_domain_by_uuid(machine.id) domain = libvirt.client.lookup_domain_by_uuid(machine.id)
if domain.nil? 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 machine.id = nil
return nil return nil
end end
xml = Nokogiri::XML(domain.xml_desc) 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 {} if mac.empty?
return {}
end
Hash[mac.each_with_index.map do |x,i| Hash[mac.each_with_index.map do |x, i|
@logger.debug("interface[#{i}] = #{x.value}") @logger.debug("interface[#{i}] = #{x.value}")
[i,x.value] [i, x.value]
end] end]
end end
end end

View File

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

View File

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

View File

@@ -5,18 +5,18 @@ module VagrantPlugins
module Action module Action
# Resume suspended domain. # Resume suspended domain.
class ResumeDomain class ResumeDomain
def initialize(app, env) def initialize(app, _env)
@logger = Log4r::Logger.new("vagrant_libvirt::action::resume_domain") @logger = Log4r::Logger.new('vagrant_libvirt::action::resume_domain')
@app = app @app = app
end end
def call(env) 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) 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 config = env[:machine].provider_config
if config.suspend_mode == 'managedsave' if config.suspend_mode == 'managedsave'
domain.start domain.start

View File

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

View File

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

View File

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

View File

@@ -5,21 +5,21 @@ module VagrantPlugins
module Action module Action
# Suspend domain. # Suspend domain.
class SuspendDomain class SuspendDomain
def initialize(app, env) def initialize(app, _env)
@logger = Log4r::Logger.new("vagrant_libvirt::action::suspend_domain") @logger = Log4r::Logger.new('vagrant_libvirt::action::suspend_domain')
@app = app @app = app
end end
# make pause # make pause
def call(env) 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) 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 config = env[:machine].provider_config
if config.suspend_mode == 'managedsave' 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 begin
libvirt_domain.managed_save libvirt_domain.managed_save
rescue => e rescue => e

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -4,22 +4,18 @@ module VagrantPlugins
module ProviderLibvirt module ProviderLibvirt
module Util module Util
module ErbTemplate 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)
# TODO might be a chance to use vagrant template system according to https://github.com/mitchellh/vagrant/issues/3231 erb = template_name || self.class.to_s.split('::').last.downcase
def to_xml template_name = nil, data = binding path = File.join(File.dirname(__FILE__), '..', 'templates',
erb = template_name || self.class.to_s.split("::").last.downcase
path = File.join(File.dirname(__FILE__), "..", "templates",
"#{erb}.xml.erb") "#{erb}.xml.erb")
template = File.read(path) 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 # 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 end
end end
end end

View File

@@ -6,19 +6,19 @@ module VagrantPlugins
VIR_ERR_OK = 0 VIR_ERR_OK = 0
VIR_ERR_INTERNAL_ERROR = 1 # internal error VIR_ERR_INTERNAL_ERROR = 1 # internal error
VIR_ERR_NO_MEMORY = 2 # memory allocation failure VIR_ERR_NO_MEMORY = 2 # memory allocation failure
VIR_ERR_NO_SUPPORT = 3 # no support for this function VIR_ERR_NO_SUPPORT = 3 # no support for this function
VIR_ERR_UNKNOWN_HOST = 4 # could not resolve hostname VIR_ERR_UNKNOWN_HOST = 4 # could not resolve hostname
VIR_ERR_NO_CONNECT = 5 # can't connect to hypervisor VIR_ERR_NO_CONNECT = 5 # can't connect to hypervisor
VIR_ERR_INVALID_CONN = 6 # invalid connection object VIR_ERR_INVALID_CONN = 6 # invalid connection object
VIR_ERR_INVALID_DOMAIN = 7 # invalid domain object VIR_ERR_INVALID_DOMAIN = 7 # invalid domain object
VIR_ERR_INVALID_ARG = 8 # invalid function argument 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_GET_FAILED = 10 # a HTTP GET command to failed
VIR_ERR_POST_FAILED = 11 # a HTTP POST 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_HTTP_ERROR = 12 # unexpected HTTP error code
VIR_ERR_SEXPR_SERIAL = 13 # failure to serialize an S-Expr VIR_ERR_SEXPR_SERIAL = 13 # failure to serialize an S-Expr
VIR_ERR_NO_XEN = 14 # could not open Xen hypervisor control VIR_ERR_NO_XEN = 14 # could not open Xen hypervisor control
VIR_ERR_XEN_CALL = 15 # failure doing an hypervisor call VIR_ERR_XEN_CALL = 15 # failure doing an hypervisor call
VIR_ERR_OS_TYPE = 16 # unknown OS type VIR_ERR_OS_TYPE = 16 # unknown OS type
VIR_ERR_NO_KERNEL = 17 # missing kernel information VIR_ERR_NO_KERNEL = 17 # missing kernel information
VIR_ERR_NO_ROOT = 18 # missing root device 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_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_XML_ERROR = 27 # an XML description is not well formed or broken
VIR_ERR_DOM_EXIST = 28 # the domain already exist 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_OPEN_FAILED = 30 # failed to open a conf file
VIR_ERR_READ_FAILED = 31 # failed to read 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_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_WRITE_FAILED = 34 # failed to write a conf file
VIR_ERR_XML_DETAIL = 35 # detail of an XML error VIR_ERR_XML_DETAIL = 35 # detail of an XML error
VIR_ERR_INVALID_NETWORK = 36 # invalid network object VIR_ERR_INVALID_NETWORK = 36 # invalid network object
VIR_ERR_NETWORK_EXIST = 37 # the network already exist VIR_ERR_NETWORK_EXIST = 37 # the network already exist
VIR_ERR_SYSTEM_ERROR = 38 # general system call failure VIR_ERR_SYSTEM_ERROR = 38 # general system call failure
VIR_ERR_RPC = 39 # some sort of RPC error VIR_ERR_RPC = 39 # some sort of RPC error
VIR_ERR_GNUTLS_ERROR = 40 # error from a GNUTLS call VIR_ERR_GNUTLS_ERROR = 40 # error from a GNUTLS call
VIR_WAR_NO_NETWORK = 41 # failed to start network VIR_WAR_NO_NETWORK = 41 # failed to start network
VIR_ERR_NO_DOMAIN = 42 # domain not found or unexpectedly disappeared VIR_ERR_NO_DOMAIN = 42 # domain not found or unexpectedly disappeared
VIR_ERR_NO_NETWORK = 43 # network not found VIR_ERR_NO_NETWORK = 43 # network not found
VIR_ERR_INVALID_MAC = 44 # invalid MAC address VIR_ERR_INVALID_MAC = 44 # invalid MAC address
VIR_ERR_AUTH_FAILED = 45 # authentication failed 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_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_POOL = 49 # storage pool not found
VIR_ERR_NO_STORAGE_VOL = 50 # storage volume not found VIR_ERR_NO_STORAGE_VOL = 50 # storage volume not found
VIR_WAR_NO_NODE = 51 # failed to start node driver VIR_WAR_NO_NODE = 51 # failed to start node driver
VIR_ERR_INVALID_NODE_DEVICE = 52 # invalid node device object 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_NO_SECURITY_MODEL = 54 # security model not found
VIR_ERR_OPERATION_INVALID = 55 # operation is not applicable at this time VIR_ERR_OPERATION_INVALID = 55 # operation is not applicable at this time
VIR_WAR_NO_INTERFACE = 56 # failed to start interface driver 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_INVALID_INTERFACE = 58 # invalid interface object
VIR_ERR_MULTIPLE_INTERFACES = 59 # more than one matching interface found VIR_ERR_MULTIPLE_INTERFACES = 59 # more than one matching interface found
VIR_WAR_NO_NWFILTER = 60 # failed to start nwfilter driver 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_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_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_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_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_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_HOOK_SCRIPT_FAILED = 70 # a synchronous hook script failed
VIR_ERR_INVALID_DOMAIN_SNAPSHOT = 71 # invalid domain snapshot VIR_ERR_INVALID_DOMAIN_SNAPSHOT = 71 # invalid domain snapshot
VIR_ERR_NO_DOMAIN_SNAPSHOT = 72 # domain snapshot not found VIR_ERR_NO_DOMAIN_SNAPSHOT = 72 # domain snapshot not found
VIR_ERR_INVALID_STREAM = 73 # stream pointer not valid 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_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_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_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_OPERATION_ABORTED = 78 # operation on a domain was canceled/aborted by user
VIR_ERR_AUTH_CANCELLED = 79 # authentication cancelled VIR_ERR_AUTH_CANCELLED = 79 # authentication cancelled
VIR_ERR_NO_DOMAIN_METADATA = 80 # The metadata is not present VIR_ERR_NO_DOMAIN_METADATA = 80 # The metadata is not present
VIR_ERR_MIGRATE_UNSAFE = 81 # Migration is not safe VIR_ERR_MIGRATE_UNSAFE = 81 # Migration is not safe
VIR_ERR_OVERFLOW = 82 # integer overflow VIR_ERR_OVERFLOW = 82 # integer overflow
VIR_ERR_BLOCK_COPY_ACTIVE = 83 # action prevented by block copy job 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_OPERATION_UNSUPPORTED = 84 # The requested operation is not supported
VIR_ERR_SSH = 85 # error in ssh transport driver 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_RESOURCE_BUSY = 87 # resource is already in use
VIR_ERR_ACCESS_DENIED = 88 # operation on the object/resource was denied VIR_ERR_ACCESS_DENIED = 88 # operation on the object/resource was denied
VIR_ERR_DBUS_SERVICE = 89 # error from a dbus service VIR_ERR_DBUS_SERVICE = 89 # error from a dbus service
@@ -98,4 +98,3 @@ module VagrantPlugins
end end
end end
end end

View File

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

View File

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

View File

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

View File

@@ -1,30 +1,30 @@
require 'fog/libvirt' require 'fog/libvirt'
shared_context "libvirt" do shared_context 'libvirt' do
include_context "unit" include_context 'unit'
let(:libvirt_context) { true } let(:libvirt_context) { true }
let(:id) { "dummy-vagrant_dummy" } let(:id) { 'dummy-vagrant_dummy' }
let(:connection) { double("connection") } let(:connection) { double('connection') }
let(:domain) { double("domain") } let(:domain) { double('domain') }
def connection_result(options={}) def connection_result(options = {})
result = options.fetch(:result, nil) result = options.fetch(:result, nil)
double("connection_result" => result) double('connection_result' => result)
end end
before (:each) do before (:each) do
# we don't want unit tests to ever run commands on the system; so we wire # 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 # 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; # drivers also call vm_exists? during init;
allow(connection).to receive(:servers).with(kind_of(String)). allow(connection).to receive(:servers).with(kind_of(String))
and_return(connection_result(result: nil)) .and_return(connection_result(result: nil))
# return some information for domain when needed # 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
end end

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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