vagrant-libvirt 0.0.40 → 0.0.41
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- metadata +13 -103
- data/.coveralls.yml +0 -1
- data/.github/issue_template.md +0 -37
- data/.gitignore +0 -21
- data/.travis.yml +0 -28
- data/CHANGELOG.md +0 -99
- data/Gemfile +0 -27
- data/LICENSE +0 -22
- data/README.md +0 -1311
- data/Rakefile +0 -8
- data/example_box/README.md +0 -29
- data/example_box/Vagrantfile +0 -60
- data/example_box/metadata.json +0 -5
- data/lib/vagrant-libvirt.rb +0 -29
- data/lib/vagrant-libvirt/action.rb +0 -362
- data/lib/vagrant-libvirt/action/create_domain.rb +0 -313
- data/lib/vagrant-libvirt/action/create_domain_volume.rb +0 -87
- data/lib/vagrant-libvirt/action/create_network_interfaces.rb +0 -294
- data/lib/vagrant-libvirt/action/create_networks.rb +0 -353
- data/lib/vagrant-libvirt/action/destroy_domain.rb +0 -83
- data/lib/vagrant-libvirt/action/destroy_networks.rb +0 -95
- data/lib/vagrant-libvirt/action/forward_ports.rb +0 -221
- data/lib/vagrant-libvirt/action/halt_domain.rb +0 -35
- data/lib/vagrant-libvirt/action/handle_box_image.rb +0 -156
- data/lib/vagrant-libvirt/action/handle_storage_pool.rb +0 -57
- data/lib/vagrant-libvirt/action/is_created.rb +0 -18
- data/lib/vagrant-libvirt/action/is_running.rb +0 -21
- data/lib/vagrant-libvirt/action/is_suspended.rb +0 -42
- data/lib/vagrant-libvirt/action/message_already_created.rb +0 -16
- data/lib/vagrant-libvirt/action/message_not_created.rb +0 -16
- data/lib/vagrant-libvirt/action/message_not_running.rb +0 -16
- data/lib/vagrant-libvirt/action/message_not_suspended.rb +0 -16
- data/lib/vagrant-libvirt/action/package_domain.rb +0 -105
- data/lib/vagrant-libvirt/action/prepare_nfs_settings.rb +0 -94
- data/lib/vagrant-libvirt/action/prepare_nfs_valid_ids.rb +0 -17
- data/lib/vagrant-libvirt/action/prune_nfs_exports.rb +0 -27
- data/lib/vagrant-libvirt/action/read_mac_addresses.rb +0 -40
- data/lib/vagrant-libvirt/action/remove_libvirt_image.rb +0 -20
- data/lib/vagrant-libvirt/action/remove_stale_volume.rb +0 -50
- data/lib/vagrant-libvirt/action/resume_domain.rb +0 -34
- data/lib/vagrant-libvirt/action/set_boot_order.rb +0 -109
- data/lib/vagrant-libvirt/action/set_name_of_domain.rb +0 -64
- data/lib/vagrant-libvirt/action/share_folders.rb +0 -71
- data/lib/vagrant-libvirt/action/start_domain.rb +0 -303
- data/lib/vagrant-libvirt/action/suspend_domain.rb +0 -40
- data/lib/vagrant-libvirt/action/wait_till_up.rb +0 -102
- data/lib/vagrant-libvirt/cap/mount_p9.rb +0 -42
- data/lib/vagrant-libvirt/cap/nic_mac_addresses.rb +0 -17
- data/lib/vagrant-libvirt/cap/synced_folder.rb +0 -113
- data/lib/vagrant-libvirt/config.rb +0 -698
- data/lib/vagrant-libvirt/driver.rb +0 -118
- data/lib/vagrant-libvirt/errors.rb +0 -149
- data/lib/vagrant-libvirt/plugin.rb +0 -92
- data/lib/vagrant-libvirt/provider.rb +0 -130
- data/lib/vagrant-libvirt/templates/default_storage_pool.xml.erb +0 -13
- data/lib/vagrant-libvirt/templates/domain.xml.erb +0 -229
- data/lib/vagrant-libvirt/templates/private_network.xml.erb +0 -34
- data/lib/vagrant-libvirt/templates/public_interface.xml.erb +0 -23
- data/lib/vagrant-libvirt/util.rb +0 -11
- data/lib/vagrant-libvirt/util/collection.rb +0 -19
- data/lib/vagrant-libvirt/util/erb_template.rb +0 -22
- data/lib/vagrant-libvirt/util/error_codes.rb +0 -100
- data/lib/vagrant-libvirt/util/network_util.rb +0 -138
- data/lib/vagrant-libvirt/util/timer.rb +0 -17
- data/lib/vagrant-libvirt/version.rb +0 -5
- data/locales/en.yml +0 -159
- data/spec/spec_helper.rb +0 -9
- data/spec/support/environment_helper.rb +0 -46
- data/spec/support/libvirt_context.rb +0 -30
- data/spec/support/sharedcontext.rb +0 -34
- data/spec/unit/action/destroy_domain_spec.rb +0 -97
- data/spec/unit/action/set_name_of_domain_spec.rb +0 -21
- data/spec/unit/action/wait_till_up_spec.rb +0 -127
- data/spec/unit/config_spec.rb +0 -106
- data/spec/unit/templates/domain_all_settings.xml +0 -133
- data/spec/unit/templates/domain_defaults.xml +0 -46
- data/spec/unit/templates/domain_spec.rb +0 -75
- data/tools/create_box.sh +0 -130
- data/tools/prepare_redhat_for_box.sh +0 -119
- data/vagrant-libvirt.gemspec +0 -28
@@ -1,40 +0,0 @@
|
|
1
|
-
require 'log4r'
|
2
|
-
|
3
|
-
module VagrantPlugins
|
4
|
-
module ProviderLibvirt
|
5
|
-
module Action
|
6
|
-
# Suspend domain.
|
7
|
-
class SuspendDomain
|
8
|
-
def initialize(app, _env)
|
9
|
-
@logger = Log4r::Logger.new('vagrant_libvirt::action::suspend_domain')
|
10
|
-
@app = app
|
11
|
-
end
|
12
|
-
|
13
|
-
# make pause
|
14
|
-
def call(env)
|
15
|
-
env[:ui].info(I18n.t('vagrant_libvirt.suspending_domain'))
|
16
|
-
|
17
|
-
domain = env[:machine].provider.driver.connection.servers.get(env[:machine].id.to_s)
|
18
|
-
raise Errors::NoDomainError if domain.nil?
|
19
|
-
|
20
|
-
config = env[:machine].provider_config
|
21
|
-
if config.suspend_mode == 'managedsave'
|
22
|
-
libvirt_domain = env[:machine].provider.driver.connection.client.lookup_domain_by_uuid(env[:machine].id)
|
23
|
-
begin
|
24
|
-
libvirt_domain.managed_save
|
25
|
-
rescue => e
|
26
|
-
env[:ui].error("Error doing a managed save for domain. It may have entered a paused state.
|
27
|
-
Check the output of `virsh managedsave DOMAIN_NAME --verbose` on the VM host, error: #{e.message}")
|
28
|
-
end
|
29
|
-
else
|
30
|
-
domain.suspend
|
31
|
-
end
|
32
|
-
|
33
|
-
@logger.info("Machine #{env[:machine].id} is suspended ")
|
34
|
-
|
35
|
-
@app.call(env)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
@@ -1,102 +0,0 @@
|
|
1
|
-
require 'log4r'
|
2
|
-
require 'vagrant-libvirt/errors'
|
3
|
-
require 'vagrant-libvirt/util/timer'
|
4
|
-
require 'vagrant/util/retryable'
|
5
|
-
|
6
|
-
module VagrantPlugins
|
7
|
-
module ProviderLibvirt
|
8
|
-
module Action
|
9
|
-
# Wait till domain is started, till it obtains an IP address and is
|
10
|
-
# accessible via ssh.
|
11
|
-
class WaitTillUp
|
12
|
-
include Vagrant::Util::Retryable
|
13
|
-
|
14
|
-
def initialize(app, _env)
|
15
|
-
@logger = Log4r::Logger.new('vagrant_libvirt::action::wait_till_up')
|
16
|
-
@app = app
|
17
|
-
end
|
18
|
-
|
19
|
-
def call(env)
|
20
|
-
# Initialize metrics if they haven't been
|
21
|
-
env[:metrics] ||= {}
|
22
|
-
|
23
|
-
# Get domain object
|
24
|
-
domain = env[:machine].provider.driver.get_domain(env[:machine].id.to_s)
|
25
|
-
if domain.nil?
|
26
|
-
raise Errors::NoDomainError,
|
27
|
-
error_message: "Domain #{env[:machine].id} not found"
|
28
|
-
end
|
29
|
-
|
30
|
-
# Wait for domain to obtain an ip address. Ip address is searched
|
31
|
-
# from arp table, either localy or remotely via ssh, if libvirt
|
32
|
-
# connection was done via ssh.
|
33
|
-
env[:ip_address] = nil
|
34
|
-
env[:metrics]['instance_ip_time'] = Util::Timer.time do
|
35
|
-
@logger.debug("Searching for IP for MAC address: #{domain.mac}")
|
36
|
-
env[:ui].info(I18n.t('vagrant_libvirt.waiting_for_ip'))
|
37
|
-
retryable(on: Fog::Errors::TimeoutError, tries: 300) do
|
38
|
-
# If we're interrupted don't worry about waiting
|
39
|
-
return terminate(env) if env[:interrupted]
|
40
|
-
|
41
|
-
# Wait for domain to obtain an ip address
|
42
|
-
domain.wait_for(2) do
|
43
|
-
addresses.each_pair do |_type, ip|
|
44
|
-
env[:ip_address] = ip[0] unless ip[0].nil?
|
45
|
-
end
|
46
|
-
!env[:ip_address].nil?
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
@logger.info("Got IP address #{env[:ip_address]}")
|
51
|
-
@logger.info("Time for getting IP: #{env[:metrics]['instance_ip_time']}")
|
52
|
-
|
53
|
-
# Machine has ip address assigned, now wait till we are able to
|
54
|
-
# connect via ssh.
|
55
|
-
env[:metrics]['instance_ssh_time'] = Util::Timer.time do
|
56
|
-
env[:ui].info(I18n.t('vagrant_libvirt.waiting_for_ssh'))
|
57
|
-
retryable(on: Fog::Errors::TimeoutError, tries: 60) do
|
58
|
-
# If we're interrupted don't worry about waiting
|
59
|
-
next if env[:interrupted]
|
60
|
-
|
61
|
-
# Wait till we are able to connect via ssh.
|
62
|
-
loop do
|
63
|
-
# If we're interrupted then just back out
|
64
|
-
break if env[:interrupted]
|
65
|
-
break if env[:machine].communicate.ready?
|
66
|
-
sleep 2
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
# if interrupted above, just terminate immediately
|
71
|
-
return terminate(env) if env[:interrupted]
|
72
|
-
@logger.info("Time for SSH ready: #{env[:metrics]['instance_ssh_time']}")
|
73
|
-
|
74
|
-
# Booted and ready for use.
|
75
|
-
# env[:ui].info(I18n.t("vagrant_libvirt.ready"))
|
76
|
-
|
77
|
-
@app.call(env)
|
78
|
-
end
|
79
|
-
|
80
|
-
def recover(env)
|
81
|
-
return if env['vagrant.error'].is_a?(Vagrant::Errors::VagrantError)
|
82
|
-
|
83
|
-
# Undo the import
|
84
|
-
terminate(env)
|
85
|
-
end
|
86
|
-
|
87
|
-
def terminate(env)
|
88
|
-
if env[:machine].provider.state.id != :not_created
|
89
|
-
# If we're not supposed to destroy on error then just return
|
90
|
-
return unless env[:destroy_on_error]
|
91
|
-
|
92
|
-
destroy_env = env.dup
|
93
|
-
destroy_env.delete(:interrupted)
|
94
|
-
destroy_env[:config_validate] = false
|
95
|
-
destroy_env[:force_confirm_destroy] = true
|
96
|
-
env[:action_runner].run(Action.action_destroy, destroy_env)
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|
@@ -1,42 +0,0 @@
|
|
1
|
-
require 'digest/md5'
|
2
|
-
require 'vagrant/util/retryable'
|
3
|
-
|
4
|
-
module VagrantPlugins
|
5
|
-
module ProviderLibvirt
|
6
|
-
module Cap
|
7
|
-
class MountP9
|
8
|
-
extend Vagrant::Util::Retryable
|
9
|
-
|
10
|
-
def self.mount_p9_shared_folder(machine, folders)
|
11
|
-
folders.each do |_name, opts|
|
12
|
-
# Expand the guest path so we can handle things like "~/vagrant"
|
13
|
-
expanded_guest_path = machine.guest.capability(
|
14
|
-
:shell_expand_guest_path, opts[:guestpath]
|
15
|
-
)
|
16
|
-
|
17
|
-
# Do the actual creating and mounting
|
18
|
-
machine.communicate.sudo("mkdir -p #{expanded_guest_path}")
|
19
|
-
|
20
|
-
# Mount
|
21
|
-
mount_tag = Digest::MD5.new.update(opts[:hostpath]).to_s[0, 31]
|
22
|
-
|
23
|
-
mount_opts = '-o trans=virtio'
|
24
|
-
mount_opts += ",access=#{opts[:owner]}" if opts[:owner]
|
25
|
-
mount_opts += ",version=#{opts[:version]}" if opts[:version]
|
26
|
-
mount_opts += ",#{opts[:mount_opts]}" if opts[:mount_opts]
|
27
|
-
|
28
|
-
mount_command = "mount -t 9p #{mount_opts} '#{mount_tag}' #{expanded_guest_path}"
|
29
|
-
retryable(on: Vagrant::Errors::LinuxMountFailed,
|
30
|
-
tries: 5,
|
31
|
-
sleep: 3) do
|
32
|
-
machine.communicate.sudo('modprobe 9p')
|
33
|
-
machine.communicate.sudo('modprobe 9pnet_virtio')
|
34
|
-
machine.communicate.sudo(mount_command,
|
35
|
-
error_class: Vagrant::Errors::LinuxMountFailed)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
module VagrantPlugins
|
2
|
-
module ProviderLibvirt
|
3
|
-
module Cap
|
4
|
-
class NicMacAddresses
|
5
|
-
def self.nic_mac_addresses(machine)
|
6
|
-
# Vagrant expects a Hash with an index starting at 1 as key
|
7
|
-
# and the mac as uppercase string without colons as value
|
8
|
-
nic_macs = {}
|
9
|
-
machine.provider.mac_addresses.each do |index, mac|
|
10
|
-
nic_macs[index + 1] = mac.upcase.delete(':')
|
11
|
-
end
|
12
|
-
nic_macs
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
@@ -1,113 +0,0 @@
|
|
1
|
-
require 'log4r'
|
2
|
-
require 'ostruct'
|
3
|
-
require 'nokogiri'
|
4
|
-
require 'digest/md5'
|
5
|
-
|
6
|
-
require 'vagrant/util/subprocess'
|
7
|
-
require 'vagrant/errors'
|
8
|
-
require 'vagrant-libvirt/errors'
|
9
|
-
# require_relative "helper"
|
10
|
-
|
11
|
-
module VagrantPlugins
|
12
|
-
module SyncedFolder9p
|
13
|
-
class SyncedFolder < Vagrant.plugin('2', :synced_folder)
|
14
|
-
include Vagrant::Util
|
15
|
-
include VagrantPlugins::ProviderLibvirt::Util::ErbTemplate
|
16
|
-
|
17
|
-
def initialize(*args)
|
18
|
-
super
|
19
|
-
@logger = Log4r::Logger.new('vagrant_libvirt::synced_folders::9p')
|
20
|
-
end
|
21
|
-
|
22
|
-
def usable?(machine, _raise_error = false)
|
23
|
-
# bail now if not using libvirt since checking version would throw error
|
24
|
-
return false unless machine.provider_name == :libvirt
|
25
|
-
|
26
|
-
# <filesystem/> support in device attach/detach introduced in 1.2.2
|
27
|
-
# version number format is major * 1,000,000 + minor * 1,000 + release
|
28
|
-
libvirt_version = machine.provider.driver.connection.client.libversion
|
29
|
-
libvirt_version >= 1_002_002
|
30
|
-
end
|
31
|
-
|
32
|
-
def prepare(machine, folders, _opts)
|
33
|
-
raise Vagrant::Errors::Error('No libvirt connection') if machine.provider.driver.connection.nil?
|
34
|
-
@conn = machine.provider.driver.connection.client
|
35
|
-
|
36
|
-
begin
|
37
|
-
# loop through folders
|
38
|
-
folders.each do |id, folder_opts|
|
39
|
-
folder_opts.merge!(target: id,
|
40
|
-
accessmode: 'passthrough',
|
41
|
-
mount: true,
|
42
|
-
readonly: nil) { |_k, ov, _nv| ov }
|
43
|
-
|
44
|
-
mount_tag = Digest::MD5.new.update(folder_opts[:hostpath]).to_s[0, 31]
|
45
|
-
folder_opts[:mount_tag] = mount_tag
|
46
|
-
|
47
|
-
machine.ui.info "================\nMachine id: #{machine.id}\nShould be mounting folders\n #{id}, opts: #{folder_opts}"
|
48
|
-
|
49
|
-
#xml = to_xml('filesystem', folder_opts)
|
50
|
-
xml = Nokogiri::XML::Builder.new do |xml|
|
51
|
-
xml.filesystem(type: 'mount', accessmode: folder_opts[:accessmode]) do
|
52
|
-
xml.driver(type: 'path', wrpolicy: 'immediate')
|
53
|
-
xml.source(dir: folder_opts[:hostpath])
|
54
|
-
xml.target(dir: mount_tag)
|
55
|
-
xml.readonly unless folder_opts[:readonly].nil?
|
56
|
-
end
|
57
|
-
end.to_xml(
|
58
|
-
save_with: Nokogiri::XML::Node::SaveOptions::NO_DECLARATION |
|
59
|
-
Nokogiri::XML::Node::SaveOptions::NO_EMPTY_TAGS |
|
60
|
-
Nokogiri::XML::Node::SaveOptions::FORMAT
|
61
|
-
)
|
62
|
-
# puts "<<<<< XML:\n #{xml}\n >>>>>"
|
63
|
-
@conn.lookup_domain_by_uuid(machine.id).attach_device(xml, 0)
|
64
|
-
end
|
65
|
-
rescue => e
|
66
|
-
machine.ui.error("could not attach device because: #{e}")
|
67
|
-
raise VagrantPlugins::ProviderLibvirt::Errors::AttachDeviceError,
|
68
|
-
error_message: e.message
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
# TODO: once up, mount folders
|
73
|
-
def enable(machine, folders, _opts)
|
74
|
-
# Go through each folder and mount
|
75
|
-
machine.ui.info('mounting p9 share in guest')
|
76
|
-
# Only mount folders that have a guest path specified.
|
77
|
-
mount_folders = {}
|
78
|
-
folders.each do |id, opts|
|
79
|
-
next unless opts[:mount] && opts[:guestpath] && !opts[:guestpath].empty?
|
80
|
-
mount_folders[id] = opts.dup
|
81
|
-
# merge common options if not given
|
82
|
-
mount_folders[id].merge!(version: '9p2000.L') { |_k, ov, _nv| ov }
|
83
|
-
end
|
84
|
-
# Mount the actual folder
|
85
|
-
machine.guest.capability(
|
86
|
-
:mount_p9_shared_folder, mount_folders
|
87
|
-
)
|
88
|
-
end
|
89
|
-
|
90
|
-
def cleanup(machine, _opts)
|
91
|
-
if machine.provider.driver.connection.nil?
|
92
|
-
raise Vagrant::Errors::Error('No libvirt connection')
|
93
|
-
end
|
94
|
-
@conn = machine.provider.driver.connection.client
|
95
|
-
begin
|
96
|
-
if machine.id && machine.id != ''
|
97
|
-
dom = @conn.lookup_domain_by_uuid(machine.id)
|
98
|
-
Nokogiri::XML(dom.xml_desc).xpath(
|
99
|
-
'/domain/devices/filesystem'
|
100
|
-
).each do |xml|
|
101
|
-
dom.detach_device(xml.to_s)
|
102
|
-
machine.ui.info 'Cleaned up shared folders'
|
103
|
-
end
|
104
|
-
end
|
105
|
-
rescue => e
|
106
|
-
machine.ui.error("could not detach device because: #{e}")
|
107
|
-
raise VagrantPlugins::ProviderLibvirt::Errors::DetachDeviceError,
|
108
|
-
error_message: e.message
|
109
|
-
end
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|
113
|
-
end
|
@@ -1,698 +0,0 @@
|
|
1
|
-
require 'vagrant'
|
2
|
-
|
3
|
-
class Numeric
|
4
|
-
Alphabet = ('a'..'z').to_a
|
5
|
-
def vdev
|
6
|
-
s = ''
|
7
|
-
q = self
|
8
|
-
(q, r = (q - 1).divmod(26)) && s.prepend(Alphabet[r]) until q.zero?
|
9
|
-
'vd' + s
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
module VagrantPlugins
|
14
|
-
module ProviderLibvirt
|
15
|
-
class Config < Vagrant.plugin('2', :config)
|
16
|
-
# manually specify URI
|
17
|
-
# will supercede most other options if provided
|
18
|
-
attr_accessor :uri
|
19
|
-
|
20
|
-
# A hypervisor name to access via Libvirt.
|
21
|
-
attr_accessor :driver
|
22
|
-
|
23
|
-
# The name of the server, where libvirtd is running.
|
24
|
-
attr_accessor :host
|
25
|
-
|
26
|
-
# If use ssh tunnel to connect to Libvirt.
|
27
|
-
attr_accessor :connect_via_ssh
|
28
|
-
# Path towards the libvirt socket
|
29
|
-
attr_accessor :socket
|
30
|
-
|
31
|
-
# The username to access Libvirt.
|
32
|
-
attr_accessor :username
|
33
|
-
|
34
|
-
# Password for Libvirt connection.
|
35
|
-
attr_accessor :password
|
36
|
-
|
37
|
-
# ID SSH key file
|
38
|
-
attr_accessor :id_ssh_key_file
|
39
|
-
|
40
|
-
# Libvirt storage pool name, where box image and instance snapshots will
|
41
|
-
# be stored.
|
42
|
-
attr_accessor :storage_pool_name
|
43
|
-
|
44
|
-
# Turn on to prevent hostname conflicts
|
45
|
-
attr_accessor :random_hostname
|
46
|
-
|
47
|
-
# Libvirt default network
|
48
|
-
attr_accessor :management_network_name
|
49
|
-
attr_accessor :management_network_address
|
50
|
-
attr_accessor :management_network_mode
|
51
|
-
attr_accessor :management_network_mac
|
52
|
-
attr_accessor :management_network_guest_ipv6
|
53
|
-
attr_accessor :management_network_autostart
|
54
|
-
|
55
|
-
# Default host prefix (alternative to use project folder name)
|
56
|
-
attr_accessor :default_prefix
|
57
|
-
|
58
|
-
# Domain specific settings used while creating new domain.
|
59
|
-
attr_accessor :uuid
|
60
|
-
attr_accessor :memory
|
61
|
-
attr_accessor :channel
|
62
|
-
attr_accessor :cpus
|
63
|
-
attr_accessor :cpu_mode
|
64
|
-
attr_accessor :cpu_model
|
65
|
-
attr_accessor :cpu_fallback
|
66
|
-
attr_accessor :cpu_features
|
67
|
-
attr_accessor :features
|
68
|
-
attr_accessor :numa_nodes
|
69
|
-
attr_accessor :loader
|
70
|
-
attr_accessor :boot_order
|
71
|
-
attr_accessor :machine_type
|
72
|
-
attr_accessor :machine_arch
|
73
|
-
attr_accessor :machine_virtual_size
|
74
|
-
attr_accessor :disk_bus
|
75
|
-
attr_accessor :disk_device
|
76
|
-
attr_accessor :nic_model_type
|
77
|
-
attr_accessor :nested
|
78
|
-
attr_accessor :volume_cache
|
79
|
-
attr_accessor :kernel
|
80
|
-
attr_accessor :cmd_line
|
81
|
-
attr_accessor :initrd
|
82
|
-
attr_accessor :dtb
|
83
|
-
attr_accessor :emulator_path
|
84
|
-
attr_accessor :graphics_type
|
85
|
-
attr_accessor :graphics_autoport
|
86
|
-
attr_accessor :graphics_port
|
87
|
-
attr_accessor :graphics_passwd
|
88
|
-
attr_accessor :graphics_ip
|
89
|
-
attr_accessor :video_type
|
90
|
-
attr_accessor :video_vram
|
91
|
-
attr_accessor :keymap
|
92
|
-
attr_accessor :kvm_hidden
|
93
|
-
attr_accessor :sound_type
|
94
|
-
|
95
|
-
# Sets the information for connecting to a host TPM device
|
96
|
-
# Only supports socket-based TPMs
|
97
|
-
attr_accessor :tpm_model
|
98
|
-
attr_accessor :tpm_type
|
99
|
-
attr_accessor :tpm_path
|
100
|
-
|
101
|
-
# Sets the max number of NICs that can be created
|
102
|
-
# Default set to 8. Don't change the default unless you know
|
103
|
-
# what are doing
|
104
|
-
attr_accessor :nic_adapter_count
|
105
|
-
|
106
|
-
# Storage
|
107
|
-
attr_accessor :disks
|
108
|
-
attr_accessor :cdroms
|
109
|
-
|
110
|
-
# Inputs
|
111
|
-
attr_accessor :inputs
|
112
|
-
|
113
|
-
# Channels
|
114
|
-
attr_accessor :channels
|
115
|
-
|
116
|
-
# PCI device passthrough
|
117
|
-
attr_accessor :pcis
|
118
|
-
|
119
|
-
# Random number device passthrough
|
120
|
-
attr_accessor :rng
|
121
|
-
|
122
|
-
# Watchdog device
|
123
|
-
attr_accessor :watchdog_dev
|
124
|
-
|
125
|
-
# USB device passthrough
|
126
|
-
attr_accessor :usbs
|
127
|
-
|
128
|
-
# Redirected devices
|
129
|
-
attr_accessor :redirdevs
|
130
|
-
attr_accessor :redirfilters
|
131
|
-
|
132
|
-
# smartcard device
|
133
|
-
attr_accessor :smartcard_dev
|
134
|
-
|
135
|
-
# Suspend mode
|
136
|
-
attr_accessor :suspend_mode
|
137
|
-
|
138
|
-
# Autostart
|
139
|
-
attr_accessor :autostart
|
140
|
-
|
141
|
-
# Attach mgmt network
|
142
|
-
attr_accessor :mgmt_attach
|
143
|
-
|
144
|
-
# Additional qemuargs arguments
|
145
|
-
attr_accessor :qemu_args
|
146
|
-
|
147
|
-
def initialize
|
148
|
-
@uri = UNSET_VALUE
|
149
|
-
@driver = UNSET_VALUE
|
150
|
-
@host = UNSET_VALUE
|
151
|
-
@connect_via_ssh = UNSET_VALUE
|
152
|
-
@username = UNSET_VALUE
|
153
|
-
@password = UNSET_VALUE
|
154
|
-
@id_ssh_key_file = UNSET_VALUE
|
155
|
-
@storage_pool_name = UNSET_VALUE
|
156
|
-
@random_hostname = UNSET_VALUE
|
157
|
-
@management_network_name = UNSET_VALUE
|
158
|
-
@management_network_address = UNSET_VALUE
|
159
|
-
@management_network_mode = UNSET_VALUE
|
160
|
-
@management_network_mac = UNSET_VALUE
|
161
|
-
@management_network_guest_ipv6 = UNSET_VALUE
|
162
|
-
@management_network_autostart = UNSET_VALUE
|
163
|
-
|
164
|
-
# Domain specific settings.
|
165
|
-
@uuid = UNSET_VALUE
|
166
|
-
@memory = UNSET_VALUE
|
167
|
-
@cpus = UNSET_VALUE
|
168
|
-
@cpu_mode = UNSET_VALUE
|
169
|
-
@cpu_model = UNSET_VALUE
|
170
|
-
@cpu_fallback = UNSET_VALUE
|
171
|
-
@cpu_features = UNSET_VALUE
|
172
|
-
@features = UNSET_VALUE
|
173
|
-
@numa_nodes = UNSET_VALUE
|
174
|
-
@loader = UNSET_VALUE
|
175
|
-
@machine_type = UNSET_VALUE
|
176
|
-
@machine_arch = UNSET_VALUE
|
177
|
-
@machine_virtual_size = UNSET_VALUE
|
178
|
-
@disk_bus = UNSET_VALUE
|
179
|
-
@disk_device = UNSET_VALUE
|
180
|
-
@nic_model_type = UNSET_VALUE
|
181
|
-
@nested = UNSET_VALUE
|
182
|
-
@volume_cache = UNSET_VALUE
|
183
|
-
@kernel = UNSET_VALUE
|
184
|
-
@initrd = UNSET_VALUE
|
185
|
-
@dtb = UNSET_VALUE
|
186
|
-
@cmd_line = UNSET_VALUE
|
187
|
-
@emulator_path = UNSET_VALUE
|
188
|
-
@graphics_type = UNSET_VALUE
|
189
|
-
@graphics_autoport = UNSET_VALUE
|
190
|
-
@graphics_port = UNSET_VALUE
|
191
|
-
@graphics_ip = UNSET_VALUE
|
192
|
-
@graphics_passwd = UNSET_VALUE
|
193
|
-
@video_type = UNSET_VALUE
|
194
|
-
@video_vram = UNSET_VALUE
|
195
|
-
@sound_type = UNSET_VALUE
|
196
|
-
@keymap = UNSET_VALUE
|
197
|
-
@kvm_hidden = UNSET_VALUE
|
198
|
-
|
199
|
-
@tpm_model = UNSET_VALUE
|
200
|
-
@tpm_type = UNSET_VALUE
|
201
|
-
@tpm_path = UNSET_VALUE
|
202
|
-
|
203
|
-
@nic_adapter_count = UNSET_VALUE
|
204
|
-
|
205
|
-
# Boot order
|
206
|
-
@boot_order = []
|
207
|
-
# Storage
|
208
|
-
@disks = []
|
209
|
-
@cdroms = []
|
210
|
-
|
211
|
-
# Inputs
|
212
|
-
@inputs = UNSET_VALUE
|
213
|
-
|
214
|
-
# Channels
|
215
|
-
@channels = UNSET_VALUE
|
216
|
-
|
217
|
-
# PCI device passthrough
|
218
|
-
@pcis = UNSET_VALUE
|
219
|
-
|
220
|
-
# Random number device passthrough
|
221
|
-
@rng = UNSET_VALUE
|
222
|
-
|
223
|
-
# Watchdog device
|
224
|
-
@watchdog_dev = UNSET_VALUE
|
225
|
-
|
226
|
-
# USB device passthrough
|
227
|
-
@usbs = UNSET_VALUE
|
228
|
-
|
229
|
-
# Redirected devices
|
230
|
-
@redirdevs = UNSET_VALUE
|
231
|
-
@redirfilters = UNSET_VALUE
|
232
|
-
|
233
|
-
# smartcard device
|
234
|
-
@smartcard_dev = UNSET_VALUE
|
235
|
-
|
236
|
-
# Suspend mode
|
237
|
-
@suspend_mode = UNSET_VALUE
|
238
|
-
|
239
|
-
# Autostart
|
240
|
-
@autostart = UNSET_VALUE
|
241
|
-
|
242
|
-
# Attach mgmt network
|
243
|
-
@mgmt_attach = UNSET_VALUE
|
244
|
-
|
245
|
-
@qemu_args = []
|
246
|
-
end
|
247
|
-
|
248
|
-
def boot(device)
|
249
|
-
@boot_order << device # append
|
250
|
-
end
|
251
|
-
|
252
|
-
def _get_device(disks)
|
253
|
-
# skip existing devices and also the first one (vda)
|
254
|
-
exist = disks.collect { |x| x[:device] } + [1.vdev.to_s]
|
255
|
-
skip = 1 # we're 1 based, not 0 based...
|
256
|
-
loop do
|
257
|
-
dev = skip.vdev # get lettered device
|
258
|
-
return dev unless exist.include?(dev)
|
259
|
-
skip += 1
|
260
|
-
end
|
261
|
-
end
|
262
|
-
|
263
|
-
def _get_cdrom_dev(cdroms)
|
264
|
-
exist = Hash[cdroms.collect { |x| [x[:dev], true] }]
|
265
|
-
# hda - hdc
|
266
|
-
curr = 'a'.ord
|
267
|
-
while curr <= 'd'.ord
|
268
|
-
dev = 'hd' + curr.chr
|
269
|
-
if exist[dev]
|
270
|
-
curr += 1
|
271
|
-
next
|
272
|
-
else
|
273
|
-
return dev
|
274
|
-
end
|
275
|
-
end
|
276
|
-
|
277
|
-
# is it better to raise our own error, or let libvirt cause the exception?
|
278
|
-
raise 'Only four cdroms may be attached at a time'
|
279
|
-
end
|
280
|
-
|
281
|
-
def _generate_numa
|
282
|
-
raise 'NUMA nodes must be a factor of CPUs' if @cpus % @numa_nodes != 0
|
283
|
-
|
284
|
-
if @memory % @numa_nodes != 0
|
285
|
-
raise 'NUMA nodes must be a factor of memory'
|
286
|
-
end
|
287
|
-
|
288
|
-
numa = []
|
289
|
-
|
290
|
-
(1..@numa_nodes).each do |node|
|
291
|
-
numa_cpu_start = (@cpus / @numa_nodes) * (node - 1)
|
292
|
-
numa_cpu_end = (@cpus / @numa_nodes) * node - 1
|
293
|
-
numa_cpu = Array(numa_cpu_start..numa_cpu_end).join(',')
|
294
|
-
numa_mem = @memory / @numa_nodes
|
295
|
-
|
296
|
-
numa.push(id: node,
|
297
|
-
cpu: numa_cpu,
|
298
|
-
mem: numa_mem)
|
299
|
-
end
|
300
|
-
|
301
|
-
@numa_nodes = numa
|
302
|
-
end
|
303
|
-
|
304
|
-
def cpu_feature(options = {})
|
305
|
-
if options[:name].nil? || options[:policy].nil?
|
306
|
-
raise 'CPU Feature name AND policy must be specified'
|
307
|
-
end
|
308
|
-
|
309
|
-
@cpu_features = [] if @cpu_features == UNSET_VALUE
|
310
|
-
|
311
|
-
@cpu_features.push(name: options[:name],
|
312
|
-
policy: options[:policy])
|
313
|
-
end
|
314
|
-
|
315
|
-
def input(options = {})
|
316
|
-
if options[:type].nil? || options[:bus].nil?
|
317
|
-
raise 'Input type AND bus must be specified'
|
318
|
-
end
|
319
|
-
|
320
|
-
@inputs = [] if @inputs == UNSET_VALUE
|
321
|
-
|
322
|
-
@inputs.push(type: options[:type],
|
323
|
-
bus: options[:bus])
|
324
|
-
end
|
325
|
-
|
326
|
-
def channel(options = {})
|
327
|
-
if options[:type].nil?
|
328
|
-
raise 'Channel type must be specified.'
|
329
|
-
elsif options[:type] == 'unix' && options[:target_type] == 'guestfwd'
|
330
|
-
# Guest forwarding requires a target (ip address) and a port
|
331
|
-
if options[:target_address].nil? || options[:target_port].nil? ||
|
332
|
-
options[:source_path].nil?
|
333
|
-
raise 'guestfwd requires target_address, target_port and source_path'
|
334
|
-
end
|
335
|
-
end
|
336
|
-
|
337
|
-
@channels = [] if @channels == UNSET_VALUE
|
338
|
-
|
339
|
-
@channels.push(type: options[:type],
|
340
|
-
source_mode: options[:source_mode],
|
341
|
-
source_path: options[:source_path],
|
342
|
-
target_address: options[:target_address],
|
343
|
-
target_name: options[:target_name],
|
344
|
-
target_port: options[:target_port],
|
345
|
-
target_type: options[:target_type])
|
346
|
-
end
|
347
|
-
|
348
|
-
def random(options = {})
|
349
|
-
if !options[:model].nil? && options[:model] != 'random'
|
350
|
-
raise 'The only supported rng backend is "random".'
|
351
|
-
end
|
352
|
-
|
353
|
-
@rng = {} if @rng == UNSET_VALUE
|
354
|
-
|
355
|
-
@rng[:model] = options[:model]
|
356
|
-
end
|
357
|
-
|
358
|
-
def pci(options = {})
|
359
|
-
if options[:bus].nil? || options[:slot].nil? || options[:function].nil?
|
360
|
-
raise 'Bus AND slot AND function must be specified. Check `lspci` for that numbers.'
|
361
|
-
end
|
362
|
-
|
363
|
-
@pcis = [] if @pcis == UNSET_VALUE
|
364
|
-
|
365
|
-
@pcis.push(bus: options[:bus],
|
366
|
-
slot: options[:slot],
|
367
|
-
function: options[:function])
|
368
|
-
end
|
369
|
-
|
370
|
-
def watchdog(options = {})
|
371
|
-
if options[:model].nil?
|
372
|
-
raise 'Model must be specified.'
|
373
|
-
end
|
374
|
-
|
375
|
-
if @watchdog_dev == UNSET_VALUE
|
376
|
-
@watchdog_dev = {}
|
377
|
-
end
|
378
|
-
|
379
|
-
@watchdog_dev[:model] = options[:model]
|
380
|
-
@watchdog_dev[:action] = options[:action] || 'reset'
|
381
|
-
end
|
382
|
-
|
383
|
-
|
384
|
-
def usb(options = {})
|
385
|
-
if (options[:bus].nil? || options[:device].nil?) && options[:vendor].nil? && options[:product].nil?
|
386
|
-
raise 'Bus and device and/or vendor and/or product must be specified. Check `lsusb` for these.'
|
387
|
-
end
|
388
|
-
|
389
|
-
@usbs = [] if @usbs == UNSET_VALUE
|
390
|
-
|
391
|
-
@usbs.push(bus: options[:bus],
|
392
|
-
device: options[:device],
|
393
|
-
vendor: options[:vendor],
|
394
|
-
product: options[:product],
|
395
|
-
startupPolicy: options[:startupPolicy])
|
396
|
-
end
|
397
|
-
|
398
|
-
def redirdev(options = {})
|
399
|
-
raise 'Type must be specified.' if options[:type].nil?
|
400
|
-
|
401
|
-
@redirdevs = [] if @redirdevs == UNSET_VALUE
|
402
|
-
|
403
|
-
@redirdevs.push(type: options[:type])
|
404
|
-
end
|
405
|
-
|
406
|
-
def redirfilter(options = {})
|
407
|
-
raise 'Option allow must be specified.' if options[:allow].nil?
|
408
|
-
|
409
|
-
@redirfilters = [] if @redirfilters == UNSET_VALUE
|
410
|
-
|
411
|
-
@redirfilters.push(class: options[:class] || -1,
|
412
|
-
vendor: options[:class] || -1,
|
413
|
-
product: options[:class] || -1,
|
414
|
-
version: options[:class] || -1,
|
415
|
-
allow: options[:allow])
|
416
|
-
end
|
417
|
-
|
418
|
-
def smartcard(options = {})
|
419
|
-
if options[:mode].nil?
|
420
|
-
raise 'Option mode must be specified.'
|
421
|
-
elsif options[:mode] != 'passthrough'
|
422
|
-
raise 'Currently only passthrough mode is supported!'
|
423
|
-
elsif options[:type] == 'tcp' && (options[:source_mode].nil? || options[:source_host].nil? || options[:source_service].nil?)
|
424
|
-
raise 'If using type "tcp", option "source_mode", "source_host" and "source_service" must be specified.'
|
425
|
-
end
|
426
|
-
|
427
|
-
if @smartcard_dev == UNSET_VALUE
|
428
|
-
@smartcard_dev = {}
|
429
|
-
end
|
430
|
-
|
431
|
-
@smartcard_dev[:mode] = options[:mode]
|
432
|
-
@smartcard_dev[:type] = options[:type] || 'spicevmc'
|
433
|
-
@smartcard_dev[:source_mode] = options[:source_mode] if @smartcard_dev[:type] == 'tcp'
|
434
|
-
@smartcard_dev[:source_host] = options[:source_host] if @smartcard_dev[:type] == 'tcp'
|
435
|
-
@smartcard_dev[:source_service] = options[:source_service] if @smartcard_dev[:type] == 'tcp'
|
436
|
-
end
|
437
|
-
|
438
|
-
# NOTE: this will run twice for each time it's needed- keep it idempotent
|
439
|
-
def storage(storage_type, options = {})
|
440
|
-
if storage_type == :file
|
441
|
-
if options[:device] == :cdrom
|
442
|
-
_handle_cdrom_storage(options)
|
443
|
-
else
|
444
|
-
_handle_disk_storage(options)
|
445
|
-
end
|
446
|
-
end
|
447
|
-
end
|
448
|
-
|
449
|
-
def _handle_cdrom_storage(options = {})
|
450
|
-
# <disk type="file" device="cdrom">
|
451
|
-
# <source file="/home/user/virtio-win-0.1-100.iso"/>
|
452
|
-
# <target dev="hdc"/>
|
453
|
-
# <readonly/>
|
454
|
-
# <address type='drive' controller='0' bus='1' target='0' unit='0'/>
|
455
|
-
# </disk>
|
456
|
-
#
|
457
|
-
# note the target dev will need to be changed with each cdrom drive (hdc, hdd, etc),
|
458
|
-
# as will the address unit number (unit=0, unit=1, etc)
|
459
|
-
|
460
|
-
options = {
|
461
|
-
bus: 'ide',
|
462
|
-
path: nil
|
463
|
-
}.merge(options)
|
464
|
-
|
465
|
-
cdrom = {
|
466
|
-
dev: options[:dev],
|
467
|
-
bus: options[:bus],
|
468
|
-
path: options[:path]
|
469
|
-
}
|
470
|
-
|
471
|
-
@cdroms << cdrom
|
472
|
-
end
|
473
|
-
|
474
|
-
def _handle_disk_storage(options = {})
|
475
|
-
options = {
|
476
|
-
type: 'qcow2',
|
477
|
-
size: '10G', # matches the fog default
|
478
|
-
path: nil,
|
479
|
-
bus: 'virtio'
|
480
|
-
}.merge(options)
|
481
|
-
|
482
|
-
disk = {
|
483
|
-
device: options[:device],
|
484
|
-
type: options[:type],
|
485
|
-
size: options[:size],
|
486
|
-
path: options[:path],
|
487
|
-
bus: options[:bus],
|
488
|
-
cache: options[:cache] || 'default',
|
489
|
-
allow_existing: options[:allow_existing],
|
490
|
-
shareable: options[:shareable],
|
491
|
-
serial: options[:serial]
|
492
|
-
}
|
493
|
-
|
494
|
-
@disks << disk # append
|
495
|
-
end
|
496
|
-
|
497
|
-
def qemuargs(options = {})
|
498
|
-
@qemu_args << options if options[:value]
|
499
|
-
end
|
500
|
-
|
501
|
-
# code to generate URI from a config moved out of the connect action
|
502
|
-
def _generate_uri
|
503
|
-
# builds the libvirt connection URI from the given driver config
|
504
|
-
# Setup connection uri.
|
505
|
-
uri = @driver.dup
|
506
|
-
virt_path = case uri
|
507
|
-
when 'qemu', 'openvz', 'uml', 'phyp', 'parallels', 'kvm'
|
508
|
-
'/system'
|
509
|
-
when '@en', 'esx'
|
510
|
-
'/'
|
511
|
-
when 'vbox', 'vmwarews', 'hyperv'
|
512
|
-
'/session'
|
513
|
-
else
|
514
|
-
raise "Require specify driver #{uri}"
|
515
|
-
end
|
516
|
-
if uri == 'kvm'
|
517
|
-
uri = 'qemu' # use qemu uri for kvm domain type
|
518
|
-
end
|
519
|
-
|
520
|
-
if @connect_via_ssh
|
521
|
-
uri << '+ssh://'
|
522
|
-
uri << @username + '@' if @username
|
523
|
-
|
524
|
-
uri << if @host
|
525
|
-
@host
|
526
|
-
else
|
527
|
-
'localhost'
|
528
|
-
end
|
529
|
-
else
|
530
|
-
uri << '://'
|
531
|
-
uri << @host if @host
|
532
|
-
end
|
533
|
-
|
534
|
-
uri << virt_path
|
535
|
-
uri << '?no_verify=1'
|
536
|
-
|
537
|
-
if @id_ssh_key_file
|
538
|
-
# set ssh key for access to libvirt host
|
539
|
-
uri << "\&keyfile="
|
540
|
-
# if no slash, prepend $HOME/.ssh/
|
541
|
-
@id_ssh_key_file.prepend("#{`echo ${HOME}`.chomp}/.ssh/") if @id_ssh_key_file !~ /\A\//
|
542
|
-
uri << @id_ssh_key_file
|
543
|
-
end
|
544
|
-
# set path to libvirt socket
|
545
|
-
uri << "\&socket=" + @socket if @socket
|
546
|
-
uri
|
547
|
-
end
|
548
|
-
|
549
|
-
def finalize!
|
550
|
-
@driver = 'kvm' if @driver == UNSET_VALUE
|
551
|
-
@host = nil if @host == UNSET_VALUE
|
552
|
-
@connect_via_ssh = false if @connect_via_ssh == UNSET_VALUE
|
553
|
-
@username = nil if @username == UNSET_VALUE
|
554
|
-
@password = nil if @password == UNSET_VALUE
|
555
|
-
@id_ssh_key_file = 'id_rsa' if @id_ssh_key_file == UNSET_VALUE
|
556
|
-
@storage_pool_name = 'default' if @storage_pool_name == UNSET_VALUE
|
557
|
-
@random_hostname = false if @random_hostname == UNSET_VALUE
|
558
|
-
@management_network_name = 'vagrant-libvirt' if @management_network_name == UNSET_VALUE
|
559
|
-
@management_network_address = '192.168.121.0/24' if @management_network_address == UNSET_VALUE
|
560
|
-
@management_network_mode = 'nat' if @management_network_mode == UNSET_VALUE
|
561
|
-
@management_network_mac = nil if @management_network_mac == UNSET_VALUE
|
562
|
-
@management_network_guest_ipv6 = 'yes' if @management_network_guest_ipv6 == UNSET_VALUE
|
563
|
-
@management_network_autostart = false if @management_network_autostart == UNSET_VALUE
|
564
|
-
|
565
|
-
# generate a URI if none is supplied
|
566
|
-
@uri = _generate_uri if @uri == UNSET_VALUE
|
567
|
-
|
568
|
-
# Domain specific settings.
|
569
|
-
@uuid = '' if @uuid == UNSET_VALUE
|
570
|
-
@memory = 512 if @memory == UNSET_VALUE
|
571
|
-
@cpus = 1 if @cpus == UNSET_VALUE
|
572
|
-
@cpu_mode = 'host-model' if @cpu_mode == UNSET_VALUE
|
573
|
-
@cpu_model = if (@cpu_model == UNSET_VALUE) && (@cpu_mode == 'custom')
|
574
|
-
'qemu64'
|
575
|
-
elsif @cpu_mode != 'custom'
|
576
|
-
''
|
577
|
-
end
|
578
|
-
@cpu_fallback = 'allow' if @cpu_fallback == UNSET_VALUE
|
579
|
-
@cpu_features = [] if @cpu_features == UNSET_VALUE
|
580
|
-
@features = ['acpi','apic','pae'] if @features == UNSET_VALUE
|
581
|
-
@numa_nodes = @numa_nodes == UNSET_VALUE ? nil : _generate_numa
|
582
|
-
@loader = nil if @loader == UNSET_VALUE
|
583
|
-
@machine_type = nil if @machine_type == UNSET_VALUE
|
584
|
-
@machine_arch = nil if @machine_arch == UNSET_VALUE
|
585
|
-
@machine_virtual_size = nil if @machine_virtual_size == UNSET_VALUE
|
586
|
-
@disk_bus = 'virtio' if @disk_bus == UNSET_VALUE
|
587
|
-
@disk_device = 'vda' if @disk_device == UNSET_VALUE
|
588
|
-
@nic_model_type = nil if @nic_model_type == UNSET_VALUE
|
589
|
-
@nested = false if @nested == UNSET_VALUE
|
590
|
-
@volume_cache = 'default' if @volume_cache == UNSET_VALUE
|
591
|
-
@kernel = nil if @kernel == UNSET_VALUE
|
592
|
-
@cmd_line = '' if @cmd_line == UNSET_VALUE
|
593
|
-
@initrd = '' if @initrd == UNSET_VALUE
|
594
|
-
@dtb = nil if @dtb == UNSET_VALUE
|
595
|
-
@graphics_type = 'vnc' if @graphics_type == UNSET_VALUE
|
596
|
-
@graphics_autoport = 'yes' if @graphics_port == UNSET_VALUE
|
597
|
-
@graphics_autoport = 'no' if @graphics_port != UNSET_VALUE
|
598
|
-
if (@graphics_type != 'vnc' && @graphics_type != 'spice') ||
|
599
|
-
@graphics_passwd == UNSET_VALUE
|
600
|
-
@graphics_passwd = nil
|
601
|
-
end
|
602
|
-
@graphics_port = 5900 if @graphics_port == UNSET_VALUE
|
603
|
-
@graphics_ip = '127.0.0.1' if @graphics_ip == UNSET_VALUE
|
604
|
-
@video_type = 'cirrus' if @video_type == UNSET_VALUE
|
605
|
-
@video_vram = 9216 if @video_vram == UNSET_VALUE
|
606
|
-
@sound_type = nil if @sound_type == UNSET_VALUE
|
607
|
-
@keymap = 'en-us' if @keymap == UNSET_VALUE
|
608
|
-
@kvm_hidden = false if @kvm_hidden == UNSET_VALUE
|
609
|
-
@tpm_model = 'tpm-tis' if @tpm_model == UNSET_VALUE
|
610
|
-
@tpm_type = 'passthrough' if @tpm_type == UNSET_VALUE
|
611
|
-
@tpm_path = nil if @tpm_path == UNSET_VALUE
|
612
|
-
@nic_adapter_count = 8 if @nic_adapter_count == UNSET_VALUE
|
613
|
-
@emulator_path = nil if @emulator_path == UNSET_VALUE
|
614
|
-
|
615
|
-
# Boot order
|
616
|
-
@boot_order = [] if @boot_order == UNSET_VALUE
|
617
|
-
|
618
|
-
# Storage
|
619
|
-
@disks = [] if @disks == UNSET_VALUE
|
620
|
-
@disks.map! do |disk|
|
621
|
-
disk[:device] = _get_device(@disks) if disk[:device].nil?
|
622
|
-
disk
|
623
|
-
end
|
624
|
-
@cdroms = [] if @cdroms == UNSET_VALUE
|
625
|
-
@cdroms.map! do |cdrom|
|
626
|
-
cdrom[:dev] = _get_cdrom_dev(@cdroms) if cdrom[:dev].nil?
|
627
|
-
cdrom
|
628
|
-
end
|
629
|
-
|
630
|
-
# Inputs
|
631
|
-
@inputs = [{ type: 'mouse', bus: 'ps2' }] if @inputs == UNSET_VALUE
|
632
|
-
|
633
|
-
# Channels
|
634
|
-
@channels = [] if @channels == UNSET_VALUE
|
635
|
-
|
636
|
-
# PCI device passthrough
|
637
|
-
@pcis = [] if @pcis == UNSET_VALUE
|
638
|
-
|
639
|
-
# Random number generator passthrough
|
640
|
-
@rng = {} if @rng == UNSET_VALUE
|
641
|
-
|
642
|
-
# Watchdog device
|
643
|
-
@watchdog_dev = {} if @watchdog_dev == UNSET_VALUE
|
644
|
-
|
645
|
-
# USB device passthrough
|
646
|
-
@usbs = [] if @usbs == UNSET_VALUE
|
647
|
-
|
648
|
-
# Redirected devices
|
649
|
-
@redirdevs = [] if @redirdevs == UNSET_VALUE
|
650
|
-
@redirfilters = [] if @redirfilters == UNSET_VALUE
|
651
|
-
|
652
|
-
# smartcard device
|
653
|
-
@smartcard_dev = {} if @smartcard_dev == UNSET_VALUE
|
654
|
-
|
655
|
-
# Suspend mode
|
656
|
-
@suspend_mode = 'pause' if @suspend_mode == UNSET_VALUE
|
657
|
-
|
658
|
-
# Autostart
|
659
|
-
@autostart = false if @autostart == UNSET_VALUE
|
660
|
-
|
661
|
-
# Attach mgmt network
|
662
|
-
@mgmt_attach = true if @mgmt_attach == UNSET_VALUE
|
663
|
-
|
664
|
-
@qemu_args = [] if @qemu_args == UNSET_VALUE
|
665
|
-
end
|
666
|
-
|
667
|
-
def validate(machine)
|
668
|
-
errors = _detected_errors
|
669
|
-
|
670
|
-
machine.provider_config.disks.each do |disk|
|
671
|
-
if disk[:path] && (disk[:path][0] == '/')
|
672
|
-
errors << "absolute volume paths like '#{disk[:path]}' not yet supported"
|
673
|
-
end
|
674
|
-
end
|
675
|
-
|
676
|
-
machine.config.vm.networks.each do |_type, opts|
|
677
|
-
if opts[:mac] && opts[:mac].downcase! && !(opts[:mac] =~ /\A([0-9a-f]{2}:){5}([0-9a-f]{2})\z/)
|
678
|
-
errors << "Configured NIC MAC '#{opts[:mac]}' is not in 'xx:xx:xx:xx:xx:xx' format"
|
679
|
-
end
|
680
|
-
end
|
681
|
-
|
682
|
-
{ 'Libvirt Provider' => errors }
|
683
|
-
end
|
684
|
-
|
685
|
-
def merge(other)
|
686
|
-
super.tap do |result|
|
687
|
-
c = disks.dup
|
688
|
-
c += other.disks
|
689
|
-
result.disks = c
|
690
|
-
|
691
|
-
c = cdroms.dup
|
692
|
-
c += other.cdroms
|
693
|
-
result.cdroms = c
|
694
|
-
end
|
695
|
-
end
|
696
|
-
end
|
697
|
-
end
|
698
|
-
end
|