vagrant-libvirt 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +134 -23
- data/lib/vagrant-libvirt/action/clean_machine_folder.rb +4 -0
- data/lib/vagrant-libvirt/action/create_domain.rb +11 -3
- data/lib/vagrant-libvirt/action/create_domain_volume.rb +7 -2
- data/lib/vagrant-libvirt/action/create_network_interfaces.rb +8 -2
- data/lib/vagrant-libvirt/action/create_networks.rb +12 -8
- data/lib/vagrant-libvirt/action/destroy_domain.rb +2 -0
- data/lib/vagrant-libvirt/action/destroy_networks.rb +2 -0
- data/lib/vagrant-libvirt/action/forward_ports.rb +7 -5
- data/lib/vagrant-libvirt/action/halt_domain.rb +4 -34
- data/lib/vagrant-libvirt/action/handle_box_image.rb +18 -13
- data/lib/vagrant-libvirt/action/handle_storage_pool.rb +7 -1
- data/lib/vagrant-libvirt/action/is_created.rb +2 -0
- data/lib/vagrant-libvirt/action/is_running.rb +2 -0
- data/lib/vagrant-libvirt/action/is_suspended.rb +2 -0
- data/lib/vagrant-libvirt/action/message_already_created.rb +2 -0
- data/lib/vagrant-libvirt/action/message_not_created.rb +2 -0
- data/lib/vagrant-libvirt/action/message_not_running.rb +2 -0
- data/lib/vagrant-libvirt/action/message_not_suspended.rb +2 -0
- data/lib/vagrant-libvirt/action/message_will_not_destroy.rb +2 -0
- data/lib/vagrant-libvirt/action/package_domain.rb +133 -68
- data/lib/vagrant-libvirt/action/prepare_nfs_settings.rb +2 -0
- data/lib/vagrant-libvirt/action/prepare_nfs_valid_ids.rb +2 -0
- data/lib/vagrant-libvirt/action/prune_nfs_exports.rb +2 -0
- data/lib/vagrant-libvirt/action/read_mac_addresses.rb +2 -0
- data/lib/vagrant-libvirt/action/remove_libvirt_image.rb +2 -0
- data/lib/vagrant-libvirt/action/remove_stale_volume.rb +2 -0
- data/lib/vagrant-libvirt/action/resume_domain.rb +2 -0
- data/lib/vagrant-libvirt/action/set_boot_order.rb +8 -2
- data/lib/vagrant-libvirt/action/set_name_of_domain.rb +3 -1
- data/lib/vagrant-libvirt/action/share_folders.rb +2 -0
- data/lib/vagrant-libvirt/action/shutdown_domain.rb +49 -0
- data/lib/vagrant-libvirt/action/start_domain.rb +26 -17
- data/lib/vagrant-libvirt/action/suspend_domain.rb +2 -0
- data/lib/vagrant-libvirt/action/wait_till_up.rb +2 -0
- data/lib/vagrant-libvirt/action.rb +34 -4
- data/lib/vagrant-libvirt/cap/mount_9p.rb +2 -0
- data/lib/vagrant-libvirt/cap/mount_virtiofs.rb +2 -0
- data/lib/vagrant-libvirt/cap/nic_mac_addresses.rb +2 -0
- data/lib/vagrant-libvirt/cap/public_address.rb +2 -0
- data/lib/vagrant-libvirt/cap/synced_folder_9p.rb +5 -2
- data/lib/vagrant-libvirt/cap/synced_folder_virtiofs.rb +5 -2
- data/lib/vagrant-libvirt/config.rb +58 -24
- data/lib/vagrant-libvirt/driver.rb +67 -12
- data/lib/vagrant-libvirt/errors.rb +2 -0
- data/lib/vagrant-libvirt/plugin.rb +2 -0
- data/lib/vagrant-libvirt/provider.rb +2 -0
- data/lib/vagrant-libvirt/templates/domain.xml.erb +4 -2
- data/lib/vagrant-libvirt/templates/public_interface.xml.erb +1 -0
- data/lib/vagrant-libvirt/util/byte_number.rb +71 -0
- data/lib/vagrant-libvirt/util/collection.rb +2 -0
- data/lib/vagrant-libvirt/util/erb_template.rb +2 -0
- data/lib/vagrant-libvirt/util/error_codes.rb +2 -0
- data/lib/vagrant-libvirt/util/network_util.rb +3 -0
- data/lib/vagrant-libvirt/util/nfs.rb +2 -0
- data/lib/vagrant-libvirt/util/storage_util.rb +1 -0
- data/lib/vagrant-libvirt/util/timer.rb +2 -0
- data/lib/vagrant-libvirt/util/ui.rb +1 -0
- data/lib/vagrant-libvirt/util.rb +2 -0
- data/lib/vagrant-libvirt/version +1 -1
- data/lib/vagrant-libvirt/version.rb +2 -0
- data/lib/vagrant-libvirt.rb +2 -0
- data/locales/en.yml +2 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/support/binding_proc.rb +2 -0
- data/spec/support/environment_helper.rb +2 -0
- data/spec/support/libvirt_context.rb +2 -0
- data/spec/support/matchers/have_file_content.rb +2 -0
- data/spec/support/sharedcontext.rb +3 -0
- data/spec/support/temporary_dir.rb +12 -0
- data/spec/unit/action/clean_machine_folder_spec.rb +16 -4
- data/spec/unit/action/create_domain_spec/additional_disks_domain.xml +61 -0
- data/spec/unit/action/create_domain_spec/default_domain.xml +55 -0
- data/spec/unit/action/create_domain_spec.rb +68 -32
- data/spec/unit/action/create_domain_volume_spec/one_disk_in_storage.xml +1 -1
- data/spec/unit/action/create_domain_volume_spec/three_disks_in_storage_disk_0.xml +1 -1
- data/spec/unit/action/create_domain_volume_spec/three_disks_in_storage_disk_1.xml +1 -1
- data/spec/unit/action/create_domain_volume_spec/three_disks_in_storage_disk_2.xml +1 -1
- data/spec/unit/action/create_domain_volume_spec.rb +10 -4
- data/spec/unit/action/destroy_domain_spec.rb +8 -2
- data/spec/unit/action/forward_ports_spec.rb +2 -0
- data/spec/unit/action/halt_domain_spec.rb +30 -57
- data/spec/unit/action/handle_box_image_spec.rb +104 -24
- data/spec/unit/action/package_domain_spec.rb +304 -0
- data/spec/unit/action/set_name_of_domain_spec.rb +2 -0
- data/spec/unit/action/shutdown_domain_spec.rb +131 -0
- data/spec/unit/action/start_domain_spec/existing.xml +62 -0
- data/spec/unit/action/start_domain_spec.rb +18 -28
- data/spec/unit/action/wait_till_up_spec.rb +2 -0
- data/spec/unit/action_spec.rb +96 -0
- data/spec/unit/config_spec.rb +56 -3
- data/spec/unit/driver_spec.rb +155 -0
- data/spec/unit/templates/domain_all_settings.xml +4 -0
- data/spec/unit/templates/domain_spec.rb +2 -0
- data/spec/unit/util/byte_number_spec.rb +28 -0
- metadata +59 -38
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'log4r'
|
2
4
|
|
3
5
|
module VagrantPlugins
|
@@ -42,8 +44,12 @@ module VagrantPlugins
|
|
42
44
|
@storage_pool_path = storage_pool_path(env)
|
43
45
|
@storage_pool_uid = storage_uid(env)
|
44
46
|
@storage_pool_gid = storage_gid(env)
|
47
|
+
xml = to_xml('default_storage_pool')
|
48
|
+
@logger.debug {
|
49
|
+
"Creating Storage Pool with XML:\n#{xml}"
|
50
|
+
}
|
45
51
|
libvirt_pool = env[:machine].provider.driver.connection.client.define_storage_pool_xml(
|
46
|
-
|
52
|
+
xml
|
47
53
|
)
|
48
54
|
libvirt_pool.build
|
49
55
|
libvirt_pool.create
|
@@ -1,6 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'fileutils'
|
2
4
|
require 'log4r'
|
3
5
|
|
6
|
+
class String
|
7
|
+
def unindent
|
8
|
+
gsub(/^#{scan(/^\s*/).min_by{|l|l.length}}/, "")
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
4
12
|
module VagrantPlugins
|
5
13
|
module ProviderLibvirt
|
6
14
|
module Action
|
@@ -12,8 +20,9 @@ module VagrantPlugins
|
|
12
20
|
def initialize(app, env)
|
13
21
|
@logger = Log4r::Logger.new('vagrant_libvirt::action::package_domain')
|
14
22
|
@app = app
|
15
|
-
|
16
|
-
|
23
|
+
|
24
|
+
@options = ENV.fetch('VAGRANT_LIBVIRT_VIRT_SYSPREP_OPTIONS', '')
|
25
|
+
@operations = ENV.fetch('VAGRANT_LIBVIRT_VIRT_SYSPREP_OPERATIONS', 'defaults,-ssh-userdir,-ssh-hostkeys,-customize')
|
17
26
|
end
|
18
27
|
|
19
28
|
def call(env)
|
@@ -22,90 +31,100 @@ module VagrantPlugins
|
|
22
31
|
env[:machine].id
|
23
32
|
)
|
24
33
|
domain = env[:machine].provider.driver.connection.servers.get(env[:machine].id.to_s)
|
25
|
-
|
34
|
+
|
35
|
+
volumes = domain.volumes.select { |x| !x.nil? }
|
36
|
+
root_disk = volumes.select do |x|
|
26
37
|
x.name == libvirt_domain.name + '.img'
|
27
38
|
end.first
|
28
39
|
raise Errors::NoDomainVolume if root_disk.nil?
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
rewriting(env[:ui]) {|ui| ui.clear_line}
|
45
|
-
backing = `qemu-img info "#{@tmp_img}" | grep 'backing file:' | cut -d ':' -f2`.chomp
|
46
|
-
if backing
|
47
|
-
env[:ui].info('Image has backing image, copying image and rebasing ...')
|
48
|
-
`qemu-img rebase -p -b "" #{@tmp_img}`
|
49
|
-
end
|
50
|
-
# remove hw association with interface
|
51
|
-
# working for centos with lvs default disks
|
52
|
-
options = ENV.fetch('VAGRANT_LIBVIRT_VIRT_SYSPREP_OPTIONS', '')
|
53
|
-
operations = ENV.fetch('VAGRANT_LIBVIRT_VIRT_SYSPREP_OPERATIONS', 'defaults,-ssh-userdir,-customize')
|
54
|
-
`virt-sysprep --no-logfile --operations #{operations} -a #{@tmp_img} #{options}`
|
55
|
-
`virt-sparsify --in-place #{@tmp_img}`
|
56
|
-
# add any user provided file
|
57
|
-
extra = ''
|
58
|
-
@tmp_include = @tmp_dir + '/_include'
|
59
|
-
if env['package.include']
|
60
|
-
extra = './_include'
|
61
|
-
Dir.mkdir(@tmp_include)
|
62
|
-
env['package.include'].each do |f|
|
63
|
-
env[:ui].info("Including user file: #{f}")
|
64
|
-
FileUtils.cp(f, @tmp_include)
|
40
|
+
|
41
|
+
package_func = method(:package_v1)
|
42
|
+
|
43
|
+
box_format = ENV.fetch('VAGRANT_LIBVIRT_BOX_FORMAT_VERSION', nil)
|
44
|
+
|
45
|
+
case box_format
|
46
|
+
when nil
|
47
|
+
if volumes.length() > 1
|
48
|
+
msg = "Detected more than one volume for machine, in the future this will switch to using the v2 "
|
49
|
+
msg += "box format v2 automatically."
|
50
|
+
msg += "\nIf you want to include the additional disks attached when packaging please set the "
|
51
|
+
msg += "env variable VAGRANT_LIBVIRT_BOX_FORMAT_VERSION=v2 to use the new format. If you want "
|
52
|
+
msg += "to ensure that your box uses the old format for single disk only, please set the "
|
53
|
+
msg += "environment variable explicitly to 'v1'"
|
54
|
+
env[:ui].warn(msg)
|
65
55
|
end
|
56
|
+
when 'v2'
|
57
|
+
package_func = method(:package_v2)
|
58
|
+
when 'v1'
|
59
|
+
else
|
60
|
+
env[:ui].warn("Unrecognized value for 'VAGRANT_LIBVIRT_BOX_FORMAT_VERSION', defaulting to v1")
|
66
61
|
end
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
img_size = (Float(info['virtual-size'])/(1024**3)).ceil
|
76
|
-
File.write(@tmp_dir + '/metadata.json', metadata_content(img_size))
|
77
|
-
File.write(@tmp_dir + '/Vagrantfile', vagrantfile_content)
|
78
|
-
assemble_box(boxname, extra)
|
79
|
-
FileUtils.mv(@tmp_dir + '/' + boxname, '../' + boxname)
|
80
|
-
FileUtils.rm_rf(@tmp_dir)
|
81
|
-
env[:ui].info('Box created')
|
82
|
-
env[:ui].info('You can now add the box:')
|
83
|
-
env[:ui].info("vagrant box add #{boxname} --name any_comfortable_name")
|
62
|
+
|
63
|
+
metadata = package_func.call(env, volumes)
|
64
|
+
|
65
|
+
# metadata / Vagrantfile
|
66
|
+
package_directory = env["package.directory"]
|
67
|
+
File.write(package_directory + '/metadata.json', metadata)
|
68
|
+
File.write(package_directory + '/Vagrantfile', vagrantfile_content(env))
|
69
|
+
|
84
70
|
@app.call(env)
|
85
71
|
end
|
86
72
|
|
87
|
-
def
|
88
|
-
|
73
|
+
def package_v1(env, volumes)
|
74
|
+
domain_img = download_volume(env, volumes.first, 'box.img')
|
75
|
+
|
76
|
+
sysprep_domain(domain_img)
|
77
|
+
sparsify_volume(domain_img)
|
78
|
+
|
79
|
+
info = JSON.parse(`qemu-img info --output=json #{domain_img}`)
|
80
|
+
img_size = (Float(info['virtual-size'])/(1024**3)).ceil
|
81
|
+
|
82
|
+
return metadata_content_v1(img_size)
|
83
|
+
end
|
84
|
+
|
85
|
+
def package_v2(env, volumes)
|
86
|
+
disks = []
|
87
|
+
volumes.each_with_index do |vol, idx|
|
88
|
+
disk = {:path => "box_#{idx+1}.img"}
|
89
|
+
volume_img = download_volume(env, vol, disk[:path])
|
90
|
+
|
91
|
+
if idx == 0
|
92
|
+
sysprep_domain(volume_img)
|
93
|
+
end
|
94
|
+
|
95
|
+
sparsify_volume(volume_img)
|
96
|
+
|
97
|
+
disks.push(disk)
|
98
|
+
end
|
99
|
+
|
100
|
+
return metadata_content_v2(disks)
|
89
101
|
end
|
90
102
|
|
91
|
-
def vagrantfile_content
|
92
|
-
|
103
|
+
def vagrantfile_content(env)
|
104
|
+
include_vagrantfile = ""
|
105
|
+
|
106
|
+
if env["package.vagrantfile"]
|
107
|
+
include_vagrantfile = <<-EOF
|
108
|
+
|
109
|
+
# Load include vagrant file if it exists after the auto-generated
|
110
|
+
# so it can override any of the settings
|
111
|
+
include_vagrantfile = File.expand_path("../include/_Vagrantfile", __FILE__)
|
112
|
+
load include_vagrantfile if File.exist?(include_vagrantfile)
|
113
|
+
EOF
|
114
|
+
end
|
115
|
+
|
116
|
+
<<-EOF.unindent
|
93
117
|
Vagrant.configure("2") do |config|
|
94
118
|
config.vm.provider :libvirt do |libvirt|
|
95
119
|
libvirt.driver = "kvm"
|
96
|
-
libvirt.host = ""
|
97
|
-
libvirt.connect_via_ssh = false
|
98
|
-
libvirt.storage_pool_name = "default"
|
99
120
|
end
|
121
|
+
#{include_vagrantfile}
|
100
122
|
end
|
101
|
-
|
102
|
-
user_vagrantfile = File.expand_path('../_include/Vagrantfile', __FILE__)
|
103
|
-
load user_vagrantfile if File.exists?(user_vagrantfile)
|
104
123
|
EOF
|
105
124
|
end
|
106
125
|
|
107
|
-
def
|
108
|
-
<<-EOF
|
126
|
+
def metadata_content_v1(filesize)
|
127
|
+
<<-EOF.unindent
|
109
128
|
{
|
110
129
|
"provider": "libvirt",
|
111
130
|
"format": "qcow2",
|
@@ -114,8 +133,54 @@ module VagrantPlugins
|
|
114
133
|
EOF
|
115
134
|
end
|
116
135
|
|
136
|
+
def metadata_content_v2(disks)
|
137
|
+
data = {
|
138
|
+
"provider": "libvirt",
|
139
|
+
"format": "qcow2",
|
140
|
+
"disks": disks.each do |disk|
|
141
|
+
{'path': disk[:path]}
|
142
|
+
end
|
143
|
+
}
|
144
|
+
JSON.pretty_generate(data)
|
145
|
+
end
|
146
|
+
|
117
147
|
protected
|
118
148
|
|
149
|
+
def sparsify_volume(volume_img)
|
150
|
+
`virt-sparsify --in-place #{volume_img}`
|
151
|
+
end
|
152
|
+
|
153
|
+
def sysprep_domain(domain_img)
|
154
|
+
# remove hw association with interface
|
155
|
+
# working for centos with lvs default disks
|
156
|
+
`virt-sysprep --no-logfile --operations #{@operations} -a #{domain_img} #{@options}`
|
157
|
+
end
|
158
|
+
|
159
|
+
def download_volume(env, volume, disk_path)
|
160
|
+
package_directory = env["package.directory"]
|
161
|
+
volume_img = package_directory + '/' + disk_path
|
162
|
+
env[:ui].info("Downloading #{volume.name} to #{volume_img}")
|
163
|
+
download_image(volume_img, env[:machine].provider_config.storage_pool_name,
|
164
|
+
volume.name, env) do |progress,image_size|
|
165
|
+
rewriting(env[:ui]) do |ui|
|
166
|
+
ui.clear_line
|
167
|
+
ui.report_progress(progress, image_size, false)
|
168
|
+
end
|
169
|
+
end
|
170
|
+
# Clear the line one last time since the progress meter doesn't
|
171
|
+
# disappear immediately.
|
172
|
+
rewriting(env[:ui]) {|ui| ui.clear_line}
|
173
|
+
|
174
|
+
# Prep domain disk
|
175
|
+
backing = `qemu-img info "#{volume_img}" | grep 'backing file:' | cut -d ':' -f2`.chomp
|
176
|
+
if backing
|
177
|
+
env[:ui].info('Image has backing image, copying image and rebasing ...')
|
178
|
+
`qemu-img rebase -p -b "" #{volume_img}`
|
179
|
+
end
|
180
|
+
|
181
|
+
return volume_img
|
182
|
+
end
|
183
|
+
|
119
184
|
# Fog libvirt currently doesn't support downloading images from storage
|
120
185
|
# pool volumes. Use ruby-libvirt client instead.
|
121
186
|
def download_image(image_file, pool_name, volume_name, env)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'log4r'
|
2
4
|
require 'nokogiri'
|
3
5
|
|
@@ -86,9 +88,13 @@ module VagrantPlugins
|
|
86
88
|
|
87
89
|
def search_network(nets, xml)
|
88
90
|
str = '/domain/devices/interface'
|
89
|
-
str += "[(@type='network' or @type='udp' or @type='bridge')"
|
91
|
+
str += "[(@type='network' or @type='udp' or @type='bridge' or @type='direct')"
|
90
92
|
unless nets.empty?
|
91
|
-
|
93
|
+
net = nets.first
|
94
|
+
network = net['network']
|
95
|
+
dev = net['dev']
|
96
|
+
str += " and source[@network='#{network}']" if network
|
97
|
+
str += " and source[@dev='#{dev}']" if dev
|
92
98
|
end
|
93
99
|
str += ']'
|
94
100
|
@logger.debug(str)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'securerandom'
|
2
4
|
module VagrantPlugins
|
3
5
|
module ProviderLibvirt
|
@@ -46,7 +48,7 @@ module VagrantPlugins
|
|
46
48
|
env[:root_path].basename.to_s.dup.concat('_')
|
47
49
|
elsif config.default_prefix.empty?
|
48
50
|
# don't have any prefix, not even "_"
|
49
|
-
|
51
|
+
String.new
|
50
52
|
else
|
51
53
|
config.default_prefix.to_s.dup
|
52
54
|
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'log4r'
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module ProviderLibvirt
|
5
|
+
module Action
|
6
|
+
# Shutdown the domain.
|
7
|
+
class ShutdownDomain
|
8
|
+
def initialize(app, _env, target_state, source_state)
|
9
|
+
@logger = Log4r::Logger.new('vagrant_libvirt::action::shutdown_domain')
|
10
|
+
@target_state = target_state
|
11
|
+
@source_state = source_state
|
12
|
+
@app = app
|
13
|
+
end
|
14
|
+
|
15
|
+
def call(env)
|
16
|
+
timeout = env[:machine].config.vm.graceful_halt_timeout
|
17
|
+
|
18
|
+
start_time = Time.now
|
19
|
+
|
20
|
+
# call nested action first under the assumption it should try to
|
21
|
+
# handle shutdown via client capabilities
|
22
|
+
@app.call(env)
|
23
|
+
|
24
|
+
# return if successful, otherwise will ensure result is set to false
|
25
|
+
env[:result] = env[:machine].state.id == @target_state
|
26
|
+
|
27
|
+
return if env[:result]
|
28
|
+
|
29
|
+
current_time = Time.now
|
30
|
+
|
31
|
+
# if we've already exceeded the timeout
|
32
|
+
return if current_time - start_time >= timeout
|
33
|
+
|
34
|
+
# otherwise construct a new timeout.
|
35
|
+
timeout = timeout - (current_time - start_time)
|
36
|
+
|
37
|
+
domain = env[:machine].provider.driver.connection.servers.get(env[:machine].id.to_s)
|
38
|
+
if env[:machine].state.id == @source_state
|
39
|
+
env[:ui].info(I18n.t('vagrant_libvirt.shutdown_domain'))
|
40
|
+
domain.shutdown
|
41
|
+
domain.wait_for(timeout) { !ready? }
|
42
|
+
end
|
43
|
+
|
44
|
+
env[:result] = env[:machine].state.id == @target_state
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'log4r'
|
2
4
|
require 'rexml/document'
|
3
5
|
|
@@ -56,7 +58,7 @@ module VagrantPlugins
|
|
56
58
|
# disk_bus
|
57
59
|
REXML::XPath.each(xml_descr, '/domain/devices/disk[@device="disk"]/target[@dev="vda"]') do |disk_target|
|
58
60
|
next unless disk_target.attributes['bus'] != config.disk_bus
|
59
|
-
@logger.debug "domain disk bus updated from '#{disk_target.attributes['bus']}' to '#{
|
61
|
+
@logger.debug "domain disk bus updated from '#{disk_target.attributes['bus']}' to '#{config.disk_bus}'"
|
60
62
|
descr_changed = true
|
61
63
|
disk_target.attributes['bus'] = config.disk_bus
|
62
64
|
disk_target.parent.delete_element("#{disk_target.parent.xpath}/address")
|
@@ -99,11 +101,13 @@ module VagrantPlugins
|
|
99
101
|
if config.cpu_mode != 'host-passthrough'
|
100
102
|
cpu_model = REXML::XPath.first(xml_descr, '/domain/cpu/model')
|
101
103
|
if cpu_model.nil?
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
104
|
+
if config.cpu_model.strip != ''
|
105
|
+
@logger.debug "cpu_model updated from not set to '#{config.cpu_model}'"
|
106
|
+
descr_changed = true
|
107
|
+
cpu_model = REXML::Element.new('model', REXML::XPath.first(xml_descr, '/domain/cpu'))
|
108
|
+
cpu_model.attributes['fallback'] = 'allow'
|
109
|
+
cpu_model.text = config.cpu_model
|
110
|
+
end
|
107
111
|
else
|
108
112
|
if (cpu_model.text or '').strip != config.cpu_model.strip
|
109
113
|
@logger.debug "cpu_model text updated from #{cpu_model.text} to '#{config.cpu_model}'"
|
@@ -165,7 +169,7 @@ module VagrantPlugins
|
|
165
169
|
|
166
170
|
# clock timers - because timers can be added/removed, just rebuild and then compare
|
167
171
|
if !config.clock_timers.empty? || clock.has_elements?
|
168
|
-
oldclock =
|
172
|
+
oldclock = String.new
|
169
173
|
formatter.write(REXML::XPath.first(xml_descr, '/domain/clock'), oldclock)
|
170
174
|
clock.delete_element('//timer')
|
171
175
|
config.clock_timers.each do |clock_timer|
|
@@ -175,7 +179,7 @@ module VagrantPlugins
|
|
175
179
|
end
|
176
180
|
end
|
177
181
|
|
178
|
-
newclock =
|
182
|
+
newclock = String.new
|
179
183
|
formatter.write(clock, newclock)
|
180
184
|
unless newclock.eql? oldclock
|
181
185
|
@logger.debug "clock timers config changed"
|
@@ -320,10 +324,12 @@ module VagrantPlugins
|
|
320
324
|
if config.initrd
|
321
325
|
initrd = REXML::XPath.first(xml_descr, '/domain/os/initrd')
|
322
326
|
if initrd.nil?
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
+
if config.initrd.strip != ''
|
328
|
+
@logger.debug "initrd updated from not set to '#{config.initrd}'"
|
329
|
+
descr_changed = true
|
330
|
+
initrd = REXML::Element.new('initrd', REXML::XPath.first(xml_descr, '/domain/os'))
|
331
|
+
initrd.text = config.initrd
|
332
|
+
end
|
327
333
|
else
|
328
334
|
if (initrd.text or '').strip != config.initrd
|
329
335
|
@logger.debug "initrd updated from '#{initrd.text}' to '#{config.initrd}'"
|
@@ -337,22 +343,25 @@ module VagrantPlugins
|
|
337
343
|
if descr_changed
|
338
344
|
begin
|
339
345
|
libvirt_domain.undefine
|
340
|
-
new_descr =
|
346
|
+
new_descr = String.new
|
341
347
|
xml_descr.write new_descr
|
342
|
-
|
348
|
+
env[:machine].provider.driver.connection.servers.create(xml: new_descr)
|
343
349
|
rescue Fog::Errors::Error => e
|
344
|
-
|
350
|
+
env[:machine].provider.driver.connection.servers.create(xml: descr)
|
345
351
|
raise Errors::FogCreateServerError, error_message: e.message
|
346
352
|
end
|
347
353
|
end
|
348
|
-
rescue => e
|
354
|
+
rescue Errors::VagrantLibvirtError => e
|
349
355
|
env[:ui].error("Error when updating domain settings: #{e.message}")
|
350
356
|
end
|
351
357
|
# Autostart with host if enabled in Vagrantfile
|
352
358
|
libvirt_domain.autostart = config.autostart
|
359
|
+
@logger.debug {
|
360
|
+
"Starting Domain with XML:\n#{libvirt_domain.xml_desc}"
|
361
|
+
}
|
353
362
|
# Actually start the domain
|
354
363
|
domain.start
|
355
|
-
rescue => e
|
364
|
+
rescue Fog::Errors::Error, Errors::VagrantLibvirtError => e
|
356
365
|
raise Errors::FogError, message: e.message
|
357
366
|
end
|
358
367
|
|
@@ -1,11 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'vagrant/action/builder'
|
2
4
|
require 'log4r'
|
3
5
|
|
4
6
|
module VagrantPlugins
|
5
7
|
module ProviderLibvirt
|
6
8
|
module Action
|
7
|
-
# Include the built-in modules so we can use them as top-level things.
|
9
|
+
# Include the built-in & general modules so we can use them as top-level things.
|
8
10
|
include Vagrant::Action::Builtin
|
11
|
+
include Vagrant::Action::General
|
9
12
|
@logger = Log4r::Logger.new('vagrant_libvirt::action')
|
10
13
|
|
11
14
|
# remove image from Libvirt storage pool
|
@@ -136,11 +139,23 @@ module VagrantPlugins
|
|
136
139
|
b3.use ResumeDomain if env2[:result]
|
137
140
|
end
|
138
141
|
|
142
|
+
# only perform shutdown if VM is running
|
139
143
|
b2.use Call, IsRunning do |env2, b3|
|
140
144
|
next unless env2[:result]
|
141
145
|
|
142
|
-
|
143
|
-
|
146
|
+
b3.use Call, Message, "Attempting nice shutdowns..." do |_, b4|
|
147
|
+
# ShutdownDomain will perform the domain shutdown on the out calls
|
148
|
+
# so it runs after the remaining actions in the same action builder.
|
149
|
+
b4.use ShutdownDomain, :shutoff, :running
|
150
|
+
b4.use GracefulHalt, :shutoff, :running
|
151
|
+
end
|
152
|
+
|
153
|
+
# Only force halt if previous actions insufficient.
|
154
|
+
b3.use Call, IsRunning do |env3, b4|
|
155
|
+
next unless env3[:result]
|
156
|
+
|
157
|
+
b4.use HaltDomain
|
158
|
+
end
|
144
159
|
end
|
145
160
|
end
|
146
161
|
end
|
@@ -167,7 +182,18 @@ module VagrantPlugins
|
|
167
182
|
def self.action_package
|
168
183
|
Vagrant::Action::Builder.new.tap do |b|
|
169
184
|
b.use ConfigValidate
|
170
|
-
b.use
|
185
|
+
b.use Call, IsCreated do |env, b2|
|
186
|
+
unless env[:result]
|
187
|
+
b2.use MessageNotCreated
|
188
|
+
next
|
189
|
+
end
|
190
|
+
|
191
|
+
b2.use PackageSetupFolders
|
192
|
+
b2.use PackageSetupFiles
|
193
|
+
b2.use action_halt
|
194
|
+
b2.use Package
|
195
|
+
b2.use PackageDomain
|
196
|
+
end
|
171
197
|
end
|
172
198
|
end
|
173
199
|
|
@@ -334,6 +360,7 @@ module VagrantPlugins
|
|
334
360
|
autoload :ForwardPorts, action_root.join('forward_ports')
|
335
361
|
autoload :ClearForwardedPorts, action_root.join('forward_ports')
|
336
362
|
autoload :HaltDomain, action_root.join('halt_domain')
|
363
|
+
autoload :ShutdownDomain, action_root.join('shutdown_domain')
|
337
364
|
autoload :HandleBoxImage, action_root.join('handle_box_image')
|
338
365
|
autoload :HandleStoragePool, action_root.join('handle_storage_pool')
|
339
366
|
autoload :RemoveLibvirtImage, action_root.join('remove_libvirt_image')
|
@@ -366,6 +393,9 @@ module VagrantPlugins
|
|
366
393
|
autoload :WaitTillUp, action_root.join('wait_till_up')
|
367
394
|
autoload :PrepareNFSValidIds, action_root.join('prepare_nfs_valid_ids')
|
368
395
|
|
396
|
+
autoload :Package, 'vagrant/action/general/package'
|
397
|
+
autoload :PackageSetupFiles, 'vagrant/action/general/package_setup_files'
|
398
|
+
autoload :PackageSetupFolders, 'vagrant/action/general/package_setup_folders'
|
369
399
|
autoload :SSHRun, 'vagrant/action/builtin/ssh_run'
|
370
400
|
autoload :HandleBox, 'vagrant/action/builtin/handle_box'
|
371
401
|
autoload :SyncedFolders, 'vagrant/action/builtin/synced_folders'
|