vagrant-libvirt 0.5.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- 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'
|