vagrant-libvirt 0.9.0 → 0.10.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.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +51 -2079
  3. data/lib/vagrant-libvirt/action/create_domain.rb +39 -4
  4. data/lib/vagrant-libvirt/action/create_network_interfaces.rb +1 -1
  5. data/lib/vagrant-libvirt/action/create_networks.rb +3 -3
  6. data/lib/vagrant-libvirt/action/destroy_domain.rb +1 -1
  7. data/lib/vagrant-libvirt/action/destroy_networks.rb +1 -1
  8. data/lib/vagrant-libvirt/action/handle_box_image.rb +1 -1
  9. data/lib/vagrant-libvirt/action/package_domain.rb +1 -5
  10. data/lib/vagrant-libvirt/action/remove_libvirt_image.rb +3 -1
  11. data/lib/vagrant-libvirt/action/resolve_disk_settings.rb +15 -8
  12. data/lib/vagrant-libvirt/action/snapshot_delete.rb +26 -0
  13. data/lib/vagrant-libvirt/action/snapshot_restore.rb +22 -0
  14. data/lib/vagrant-libvirt/action/snapshot_save.rb +27 -0
  15. data/lib/vagrant-libvirt/action/start_domain.rb +43 -14
  16. data/lib/vagrant-libvirt/action.rb +49 -1
  17. data/lib/vagrant-libvirt/cap/snapshots.rb +12 -0
  18. data/lib/vagrant-libvirt/cap/synced_folder_9p.rb +4 -4
  19. data/lib/vagrant-libvirt/cap/synced_folder_virtiofs.rb +4 -4
  20. data/lib/vagrant-libvirt/config.rb +101 -6
  21. data/lib/vagrant-libvirt/driver.rb +108 -46
  22. data/lib/vagrant-libvirt/errors.rb +23 -3
  23. data/lib/vagrant-libvirt/plugin.rb +7 -3
  24. data/lib/vagrant-libvirt/provider.rb +1 -1
  25. data/lib/vagrant-libvirt/templates/domain.xml.erb +30 -4
  26. data/lib/vagrant-libvirt/util/byte_number.rb +0 -1
  27. data/lib/vagrant-libvirt/util/compat.rb +23 -0
  28. data/lib/vagrant-libvirt/util/unindent.rb +7 -0
  29. data/lib/vagrant-libvirt/version +1 -1
  30. data/locales/en.yml +24 -2
  31. data/spec/acceptance/additional_storage_spec.rb +32 -0
  32. data/spec/acceptance/package_domain_spec.rb +90 -0
  33. data/spec/acceptance/provider_settings_spec.rb +54 -0
  34. data/spec/acceptance/simple_vm_provision_via_shell_spec.rb +31 -0
  35. data/spec/acceptance/snapshots_spec.rb +41 -0
  36. data/spec/acceptance/support-skeletons/package_complex/Vagrantfile.testbox +14 -0
  37. data/spec/acceptance/support-skeletons/package_complex/scripts/sysprep.sh +32 -0
  38. data/spec/acceptance/support-skeletons/package_simple/Vagrantfile.testbox +10 -0
  39. data/spec/acceptance/two_disks_spec.rb +29 -0
  40. data/spec/acceptance/use_qemu_agent_for_connectivity_spec.rb +35 -0
  41. data/spec/spec_helper.rb +3 -0
  42. data/spec/support/acceptance/configuration.rb +21 -0
  43. data/spec/support/acceptance/context.rb +70 -0
  44. data/spec/support/acceptance/isolated_environment.rb +41 -0
  45. data/spec/support/libvirt_acceptance_context.rb +64 -0
  46. data/spec/support/sharedcontext.rb +1 -0
  47. data/spec/unit/action/create_domain_spec/sysinfo.xml +66 -0
  48. data/spec/unit/action/create_domain_spec/sysinfo_only_required.xml +49 -0
  49. data/spec/unit/action/create_domain_spec.rb +82 -0
  50. data/spec/unit/action/forward_ports_spec.rb +0 -1
  51. data/spec/unit/action/handle_box_image_spec.rb +18 -1
  52. data/spec/unit/action/remove_libvirt_image_spec.rb +43 -0
  53. data/spec/unit/action/resolve_disk_settings_spec.rb +24 -0
  54. data/spec/unit/action/start_domain_spec/clock_timer_removed.xml +38 -0
  55. data/spec/unit/action/start_domain_spec/clock_timer_rtc_tsc.xml +39 -0
  56. data/spec/unit/action/start_domain_spec/nvram_domain_other_setting.xml +2 -2
  57. data/spec/unit/action/start_domain_spec.rb +72 -30
  58. data/spec/unit/action_spec.rb +88 -0
  59. data/spec/unit/cap/synced_folder_9p_spec.rb +120 -0
  60. data/spec/unit/cap/synced_folder_virtiofs_spec.rb +120 -0
  61. data/spec/unit/config_spec.rb +133 -6
  62. data/spec/unit/driver_spec.rb +1 -1
  63. data/spec/unit/plugin_spec.rb +42 -0
  64. data/spec/unit/templates/domain_all_settings.xml +13 -4
  65. data/spec/unit/templates/domain_scsi_bus_storage.xml +44 -0
  66. data/spec/unit/templates/domain_scsi_device_storage.xml +44 -0
  67. data/spec/unit/templates/domain_scsi_multiple_controllers_storage.xml +130 -0
  68. data/spec/unit/templates/domain_spec.rb +105 -21
  69. data/spec/unit/util/byte_number_spec.rb +1 -1
  70. metadata +155 -87
  71. data/spec/unit/provider_spec.rb +0 -11
@@ -44,6 +44,7 @@ module VagrantPlugins
44
44
  @nvram = config.nvram
45
45
  @machine_type = config.machine_type
46
46
  @machine_arch = config.machine_arch
47
+ @disk_controller_model = config.disk_controller_model
47
48
  @disk_driver_opts = config.disk_driver_opts
48
49
  @nested = config.nested
49
50
  @memory_size = config.memory.to_i * 1024
@@ -73,6 +74,22 @@ module VagrantPlugins
73
74
  @tpm_path = config.tpm_path
74
75
  @tpm_version = config.tpm_version
75
76
 
77
+ @sysinfo = config.sysinfo.dup
78
+ @sysinfo.each do |section, _v|
79
+ if @sysinfo[section].respond_to?(:each_pair)
80
+ @sysinfo[section].delete_if { |_k, v| v.to_s.empty? }
81
+ else
82
+ @sysinfo[section].reject! { |e| e.to_s.empty? }
83
+ end
84
+ end.reject! { |_k, v| v.empty? }
85
+ @sysinfo_blocks = {
86
+ 'bios' => {:ui => "BIOS", :xml => "bios"},
87
+ 'system' => {:ui => "System", :xml => "system"},
88
+ 'base board' => {:ui => "Base Board", :xml => "baseBoard"},
89
+ 'chassis' => {:ui => "Chassis", :xml => "chassis"},
90
+ 'oem strings' => {:ui => "OEM Strings", :xml => "oemStrings"},
91
+ }
92
+
76
93
  # Boot order
77
94
  @boot_order = config.boot_order
78
95
 
@@ -151,9 +168,11 @@ module VagrantPlugins
151
168
  rescue Libvirt::Error => e
152
169
  # It is hard to believe that e contains just a string
153
170
  # and no useful error code!
154
- msg = "Call to virStorageVolCreateXML failed: " +
155
- "storage volume '#{disk[:absolute_path]}' exists already"
156
- if e.message == msg and disk[:allow_existing]
171
+ msgs = [disk[:name], disk[:absolute_path]].map do |name|
172
+ "Call to virStorageVolCreateXML failed: " +
173
+ "storage volume '#{name}' exists already"
174
+ end
175
+ if msgs.include?(e.message) and disk[:allow_existing]
157
176
  disk[:preexisting] = true
158
177
  else
159
178
  raise Errors::FogCreateDomainVolumeError,
@@ -243,7 +262,7 @@ module VagrantPlugins
243
262
  env[:ui].info(" -- Video Type: #{@video_type}")
244
263
  env[:ui].info(" -- Video VRAM: #{@video_vram}")
245
264
  env[:ui].info(" -- Video 3D accel: #{@video_accel3d}")
246
- env[:ui].info(" -- Sound Type: #{@sound_type}")
265
+ env[:ui].info(" -- Sound Type: #{@sound_type}")
247
266
  env[:ui].info(" -- Keymap: #{@keymap}")
248
267
  env[:ui].info(" -- TPM Backend: #{@tpm_type}")
249
268
  if @tpm_type == 'emulator'
@@ -253,6 +272,22 @@ module VagrantPlugins
253
272
  env[:ui].info(" -- TPM Path: #{@tpm_path}")
254
273
  end
255
274
 
275
+ unless @sysinfo.empty?
276
+ env[:ui].info(" -- Sysinfo:")
277
+ @sysinfo.each_pair do |block, values|
278
+ env[:ui].info(" -- #{@sysinfo_blocks[block.to_s][:ui]}:")
279
+ if values.respond_to?(:each_pair)
280
+ values.each_pair do |name, value|
281
+ env[:ui].info(" -> #{name}: #{value}")
282
+ end
283
+ else
284
+ values.each do |value|
285
+ env[:ui].info(" -> #{value}")
286
+ end
287
+ end
288
+ end
289
+ end
290
+
256
291
  if @memballoon_enabled
257
292
  env[:ui].info(" -- Memballoon model: #{@memballoon_model}")
258
293
  env[:ui].info(" -- Memballoon bus: #{@memballoon_pci_bus}")
@@ -41,7 +41,7 @@ module VagrantPlugins
41
41
  # Vagrant gives you adapter 0 by default
42
42
  # Assign interfaces to slots.
43
43
  configured_networks(env, @logger).each do |options|
44
- # dont need to create interface for this type
44
+ # don't need to create interface for this type
45
45
  next if options[:iface_type] == :forwarded_port
46
46
 
47
47
  # TODO: fill first ifaces with adapter option specified.
@@ -44,7 +44,7 @@ module VagrantPlugins
44
44
  end
45
45
 
46
46
  # only one vm at a time should try to set up networks
47
- # otherwise they'll have inconsitent views of current state
47
+ # otherwise they'll have inconsistent views of current state
48
48
  # and conduct redundant operations that cause errors
49
49
  @@lock.synchronize do
50
50
  # Iterate over networks If some network is not
@@ -124,7 +124,7 @@ module VagrantPlugins
124
124
  # Throw an error if dhcp setting for an existing network does not
125
125
  # match what was configured in the vagrantfile
126
126
  # since we always enable dhcp for the management network
127
- # this ensures we wont start a vm vagrant cant reach
127
+ # this ensures we won't start a vm vagrant can't reach
128
128
  # Allow the situation where DHCP is not requested (:libvirt__dhcp_enabled == false)
129
129
  # but where it is enabled on the virtual network
130
130
  def verify_dhcp
@@ -321,7 +321,7 @@ module VagrantPlugins
321
321
 
322
322
  @network_ipv6_address = @interface_network[:ipv6_address]
323
323
  @network_ipv6_prefix = @interface_network[:ipv6_prefix]
324
-
324
+
325
325
  @network_bridge_stp = @options[:bridge_stp].nil? || @options[:bridge_stp] ? 'on' : 'off'
326
326
  @network_bridge_delay = @options[:bridge_delay] ? @options[:bridge_delay] : 0
327
327
 
@@ -34,7 +34,7 @@ module VagrantPlugins
34
34
  begin
35
35
  libvirt_domain.lookup_snapshot_by_name(name).delete
36
36
  rescue => e
37
- raise Errors::DeleteSnapshotError, error_message: e.message
37
+ raise Errors::SnapshotDeletionError, error_message: e.message
38
38
  end
39
39
  end
40
40
  rescue
@@ -50,7 +50,7 @@ module VagrantPlugins
50
50
  if e.libvirt_code == ProviderLibvirt::Util::ErrorCodes::VIR_ERR_NO_NETWORK
51
51
  @logger.info 'It is already undefined'
52
52
  next
53
- # some other error occured, so raise it again
53
+ # some other error occurred, so raise it again
54
54
  else
55
55
  raise e
56
56
  end
@@ -134,7 +134,7 @@ module VagrantPlugins
134
134
  ''
135
135
  end
136
136
 
137
- if version.empty?
137
+ if version.empty? || version == '0'
138
138
  ui.warn(I18n.t('vagrant_libvirt.box_version_missing', name: box.name.to_s))
139
139
 
140
140
  version = "0_#{File.mtime(path).to_i}"
@@ -3,11 +3,7 @@
3
3
  require 'fileutils'
4
4
  require 'log4r'
5
5
 
6
- class String
7
- def unindent
8
- gsub(/^#{scan(/^\s*/).min_by{|l|l.length}}/, "")
9
- end
10
- end
6
+ require 'vagrant-libvirt/util/unindent'
11
7
 
12
8
  module VagrantPlugins
13
9
  module ProviderLibvirt
@@ -12,7 +12,9 @@ module VagrantPlugins
12
12
  end
13
13
 
14
14
  def call(env)
15
- env[:ui].info('Vagrant-libvirt plugin removed box only from your LOCAL ~/.vagrant/boxes directory')
15
+ return @app.call(env) unless env[:box_removed].provider == :libvirt
16
+
17
+ env[:ui].info("Vagrant-libvirt plugin removed box only from #{env[:env].boxes.directory} directory")
16
18
  env[:ui].info('From Libvirt storage pool you have to delete image manually(virsh, virt-manager or by any other tool)')
17
19
  @app.call(env)
18
20
  end
@@ -1,7 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'log4r'
4
- require 'rexml'
4
+
5
+ begin
6
+ require 'rexml'
7
+ rescue LoadError
8
+ require 'rexml/rexml'
9
+ end
5
10
 
6
11
  require 'vagrant-libvirt/util/resolvers'
7
12
 
@@ -97,13 +102,15 @@ module VagrantPlugins
97
102
  # the default storage prefix is typically: /var/lib/libvirt/images/
98
103
  storage_prefix = "#{File.dirname(domain_volumes[0][:absolute_path])}/" # steal
99
104
  else
100
- # Ensure domain name is set for subsequent steps if restarting a machine without a box
101
- libvirt_domain = env[:machine].provider.driver.connection.client.lookup_domain_by_uuid(
102
- env[:machine].id
103
- )
104
- domain_xml = libvirt_domain.xml_desc(1)
105
- xml_descr = REXML::Document.new(domain_xml)
106
- domain_name = xml_descr.elements['domain'].elements['name'].text
105
+ if domain_name.nil?
106
+ # Ensure domain name is set for subsequent steps if restarting a machine without a box
107
+ libvirt_domain = env[:machine].provider.driver.connection.client.lookup_domain_by_uuid(
108
+ env[:machine].id
109
+ )
110
+ domain_xml = libvirt_domain.xml_desc(1)
111
+ xml_descr = REXML::Document.new(domain_xml)
112
+ domain_name = xml_descr.elements['domain'].elements['name'].text
113
+ end
107
114
 
108
115
  storage_prefix = get_disk_storage_prefix(env[:machine], storage_pool_name)
109
116
  end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module VagrantPlugins
4
+ module ProviderLibvirt
5
+ module Action
6
+ class SnapshotDelete
7
+ def initialize(app, env)
8
+ @app = app
9
+ end
10
+
11
+ def call(env)
12
+ env[:ui].info(I18n.t(
13
+ "vagrant.actions.vm.snapshot.deleting",
14
+ name: env[:snapshot_name]))
15
+ env[:machine].provider.driver.delete_snapshot(env[:machine], env[:snapshot_name])
16
+
17
+ env[:ui].success(I18n.t(
18
+ "vagrant.actions.vm.snapshot.deleted",
19
+ name: env[:snapshot_name]))
20
+
21
+ @app.call(env)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module VagrantPlugins
4
+ module ProviderLibvirt
5
+ module Action
6
+ class SnapshotRestore
7
+ def initialize(app, env)
8
+ @app = app
9
+ end
10
+
11
+ def call(env)
12
+ env[:ui].info(I18n.t(
13
+ "vagrant.actions.vm.snapshot.restoring",
14
+ name: env[:snapshot_name]))
15
+ env[:machine].provider.driver.restore_snapshot(env[:machine], env[:snapshot_name])
16
+
17
+ @app.call(env)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module VagrantPlugins
4
+ module ProviderLibvirt
5
+ module Action
6
+ class SnapshotSave
7
+ def initialize(app, env)
8
+ @app = app
9
+ end
10
+
11
+ def call(env)
12
+ env[:ui].info(I18n.t(
13
+ "vagrant.actions.vm.snapshot.saving",
14
+ name: env[:snapshot_name]))
15
+ env[:machine].provider.driver.create_snapshot(
16
+ env[:machine], env[:snapshot_name])
17
+
18
+ env[:ui].success(I18n.t(
19
+ "vagrant.actions.vm.snapshot.saved",
20
+ name: env[:snapshot_name]))
21
+
22
+ @app.call(env)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'diffy'
3
4
  require 'log4r'
4
5
  require 'rexml/document'
5
6
 
@@ -14,8 +15,6 @@ module VagrantPlugins
14
15
  end
15
16
 
16
17
  def call(env)
17
- env[:ui].info(I18n.t('vagrant_libvirt.starting_domain'))
18
-
19
18
  domain = env[:machine].provider.driver.connection.servers.get(env[:machine].id.to_s)
20
19
  raise Errors::NoDomainError if domain.nil?
21
20
  config = env[:machine].provider_config
@@ -33,6 +32,7 @@ module VagrantPlugins
33
32
  libvirt_domain.memory = libvirt_domain.max_memory
34
33
  end
35
34
  end
35
+
36
36
  begin
37
37
  # XML definition manipulation
38
38
  descr = libvirt_domain.xml_desc(1)
@@ -64,7 +64,7 @@ module VagrantPlugins
64
64
  disk_target.parent.delete_element("#{disk_target.parent.xpath}/address")
65
65
  end
66
66
 
67
- # Iterface type
67
+ # Interface type
68
68
  unless config.nic_model_type.nil?
69
69
  REXML::XPath.each(xml_descr, '/domain/devices/interface/model') do |iface_model|
70
70
  if iface_model.attributes['type'] != config.nic_model_type
@@ -248,7 +248,7 @@ module VagrantPlugins
248
248
  # TPM
249
249
  if [config.tpm_path, config.tpm_version].any?
250
250
  if config.tpm_path
251
- raise Errors::FogCreateServerError, 'The TPM Path must be fully qualified' unless config.tpm_path[0].chr == '/'
251
+ raise Errors::UpdateServerError, 'The TPM Path must be fully qualified' unless config.tpm_path[0].chr == '/'
252
252
  end
253
253
 
254
254
  # just build the tpm element every time
@@ -394,7 +394,6 @@ module VagrantPlugins
394
394
  loader.parent.delete_element(loader)
395
395
  end
396
396
 
397
- undefine_flags = 0
398
397
  nvram = REXML::XPath.first(xml_descr, '/domain/os/nvram')
399
398
  if config.nvram
400
399
  if nvram.nil?
@@ -407,28 +406,57 @@ module VagrantPlugins
407
406
  descr_changed = true
408
407
  nvram.text = config.nvram
409
408
  end
410
- undefine_flags |= ProviderLibvirt::Util::DomainFlags::VIR_DOMAIN_UNDEFINE_KEEP_NVRAM
411
409
  end
412
410
  elsif !nvram.nil?
413
411
  descr_changed = true
414
- undefine_flags |= ProviderLibvirt::Util::DomainFlags::VIR_DOMAIN_UNDEFINE_NVRAM
415
412
  nvram.parent.delete_element(nvram)
416
413
  end
417
414
 
418
415
  # Apply
419
416
  if descr_changed
417
+ env[:ui].info(I18n.t('vagrant_libvirt.updating_domain'))
418
+ new_xml = String.new
419
+ xml_descr.write(new_xml)
420
+ begin
421
+ # providing XML for the same name and UUID will update the existing domain
422
+ libvirt_domain = env[:machine].provider.driver.connection.define_domain(new_xml)
423
+ rescue ::Libvirt::Error => e
424
+ raise Errors::UpdateServerError, error_message: e.message
425
+ end
426
+
420
427
  begin
421
- libvirt_domain.undefine(undefine_flags)
422
- new_descr = String.new
423
- xml_descr.write new_descr
424
- env[:machine].provider.driver.connection.servers.create(xml: new_descr)
425
- rescue Fog::Errors::Error => e
426
- env[:machine].provider.driver.connection.servers.create(xml: descr)
427
- raise Errors::FogCreateServerError, error_message: e.message
428
+ proposed = Nokogiri::XML(new_xml, &:noblanks)
429
+
430
+ # This normalizes the attribute order to be consistent across both XML docs to eliminate differences
431
+ # for subsequent comparison by diffy
432
+ updated_xml_descr = REXML::Document.new(libvirt_domain.xml_desc(1))
433
+ updated_xml = String.new
434
+ updated_xml_descr.write(updated_xml)
435
+
436
+ updated = Nokogiri::XML(updated_xml, &:noblanks)
437
+
438
+ pretty_proposed = StringIO.new
439
+ pretty_updated = StringIO.new
440
+ proposed.write_xml_to(pretty_proposed, indent: 2)
441
+ updated.write_xml_to(pretty_updated, indent: 2)
442
+
443
+ diff = Diffy::Diff.new(pretty_proposed.string, pretty_updated.string, :context => 3).to_s(:text)
444
+
445
+ unless diff.empty?
446
+ error_msg = "Libvirt failed to fully update the domain with the specified XML. Result differs from requested:\n" +
447
+ "--- requested\n+++ result\n#{diff}\n" +
448
+ "Typically this means there is a bug in the XML being sent, please log an issue"
449
+
450
+ raise Errors::UpdateServerError, error_message: error_msg
451
+ end
452
+ rescue Exception => e
453
+ env[:machine].provider.driver.connection.define_domain(descr)
454
+ raise
428
455
  end
429
456
  end
430
457
  rescue Errors::VagrantLibvirtError => e
431
458
  env[:ui].error("Error when updating domain settings: #{e.message}")
459
+ raise
432
460
  end
433
461
  # Autostart with host if enabled in Vagrantfile
434
462
  libvirt_domain.autostart = config.autostart
@@ -436,6 +464,7 @@ module VagrantPlugins
436
464
  "Starting Domain with XML:\n#{libvirt_domain.xml_desc}"
437
465
  }
438
466
  # Actually start the domain
467
+ env[:ui].info(I18n.t('vagrant_libvirt.starting_domain'))
439
468
  domain.start
440
469
  rescue Fog::Errors::Error, Errors::VagrantLibvirtError => e
441
470
  raise Errors::FogError, message: e.message
@@ -40,6 +40,12 @@ module VagrantPlugins
40
40
  autoload :SetNameOfDomain, action_root.join('set_name_of_domain')
41
41
  autoload :SetBootOrder, action_root.join('set_boot_order')
42
42
  autoload :SetupComplete, action_root.join('cleanup_on_failure')
43
+ # Snapshot autoload
44
+ autoload :SnapshotDelete, action_root.join('snapshot_delete')
45
+ autoload :SnapshotSave, action_root.join('snapshot_save')
46
+ autoload :SnapshotRestore, action_root.join('snapshot_restore')
47
+
48
+
43
49
  # I don't think we need it anymore
44
50
  autoload :ShareFolders, action_root.join('share_folders')
45
51
  autoload :ShutdownDomain, action_root.join('shutdown_domain')
@@ -156,7 +162,7 @@ module VagrantPlugins
156
162
  # Start it..
157
163
  b3.use StartDomain
158
164
 
159
- # Machine should gain IP address when comming up,
165
+ # Machine should gain IP address when coming up,
160
166
  # so wait for dhcp lease and store IP into machines data_dir.
161
167
  b3.use WaitTillUp
162
168
  require 'vagrant/action/builtin/wait_for_communicator'
@@ -392,6 +398,48 @@ module VagrantPlugins
392
398
  end
393
399
  end
394
400
 
401
+ # This is the action that is primarily responsible for deleting a snapshot
402
+ def self.action_snapshot_delete
403
+ Vagrant::Action::Builder.new.tap do |b|
404
+ b.use ConfigValidate
405
+ b.use Call, IsCreated do |env, b2|
406
+ unless env[:result]
407
+ raise Vagrant::Errors::VMNotCreatedError
408
+ end
409
+
410
+ b2.use SnapshotDelete
411
+ end
412
+ end
413
+ end
414
+
415
+ # This is the action that is primarily responsible for restoring a snapshot
416
+ def self.action_snapshot_restore
417
+ Vagrant::Action::Builder.new.tap do |b|
418
+ b.use ConfigValidate
419
+ b.use Call, IsCreated do |env, b2|
420
+ unless env[:result]
421
+ raise Vagrant::Errors::VMNotCreatedError
422
+ end
423
+
424
+ b2.use SnapshotRestore
425
+ end
426
+ end
427
+ end
428
+
429
+ # This is the action that is primarily responsible for saving a snapshot
430
+ def self.action_snapshot_save
431
+ Vagrant::Action::Builder.new.tap do |b|
432
+ b.use ConfigValidate
433
+ b.use Call, IsCreated do |env, b2|
434
+ unless env[:result]
435
+ raise Vagrant::Errors::VMNotCreatedError
436
+ end
437
+
438
+ b2.use SnapshotSave
439
+ end
440
+ end
441
+ end
442
+
395
443
  end
396
444
  end
397
445
  end
@@ -0,0 +1,12 @@
1
+ module VagrantPlugins
2
+ module ProviderLibvirt
3
+ module Cap
4
+ class Snapshots
5
+ def self.snapshot_list(machine)
6
+ return if machine.state.id == :not_created
7
+ machine.provider.driver.list_snapshots(machine)
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
@@ -34,6 +34,8 @@ module VagrantPlugins
34
34
  raise Vagrant::Errors::Error('No Libvirt connection') if machine.provider.driver.connection.nil?
35
35
  @conn = machine.provider.driver.connection.client
36
36
 
37
+ machine.ui.info I18n.t("vagrant_libvirt.cap.9p.preparing")
38
+
37
39
  begin
38
40
  # loop through folders
39
41
  folders.each do |id, folder_opts|
@@ -45,8 +47,6 @@ module VagrantPlugins
45
47
  mount_tag = Digest::MD5.new.update(folder_opts[:hostpath]).to_s[0, 31]
46
48
  folder_opts[:mount_tag] = mount_tag
47
49
 
48
- machine.ui.info "================\nMachine id: #{machine.id}\nShould be mounting folders\n #{id}, opts: #{folder_opts}"
49
-
50
50
  xml = Nokogiri::XML::Builder.new do |xml|
51
51
  xml.filesystem(type: 'mount', accessmode: folder_opts[:accessmode]) do
52
52
  xml.driver(type: 'path', wrpolicy: 'immediate')
@@ -74,7 +74,7 @@ module VagrantPlugins
74
74
  # once up, mount folders
75
75
  def enable(machine, folders, _opts)
76
76
  # Go through each folder and mount
77
- machine.ui.info('mounting 9p share in guest')
77
+ machine.ui.info I18n.t("vagrant_libvirt.cap.9p.mounting")
78
78
  # Only mount folders that have a guest path specified.
79
79
  mount_folders = {}
80
80
  folders.each do |id, opts|
@@ -94,6 +94,7 @@ module VagrantPlugins
94
94
  raise Vagrant::Errors::Error('No Libvirt connection')
95
95
  end
96
96
  @conn = machine.provider.driver.connection.client
97
+ machine.ui.info I18n.t("vagrant_libvirt.cap.9p.cleanup")
97
98
  begin
98
99
  if machine.id && machine.id != ''
99
100
  dom = @conn.lookup_domain_by_uuid(machine.id)
@@ -101,7 +102,6 @@ module VagrantPlugins
101
102
  '/domain/devices/filesystem'
102
103
  ).each do |xml|
103
104
  dom.detach_device(xml.to_s)
104
- machine.ui.info 'Cleaned up shared folders'
105
105
  end
106
106
  end
107
107
  rescue => e
@@ -34,6 +34,8 @@ module VagrantPlugins
34
34
  raise Vagrant::Errors::Error('No Libvirt connection') if machine.provider.driver.connection.nil?
35
35
  @conn = machine.provider.driver.connection.client
36
36
 
37
+ machine.ui.info I18n.t("vagrant_libvirt.cap.virtiofs.preparing")
38
+
37
39
  begin
38
40
  # loop through folders
39
41
  folders.each do |id, folder_opts|
@@ -44,8 +46,6 @@ module VagrantPlugins
44
46
  mount_tag = Digest::MD5.new.update(folder_opts[:hostpath]).to_s[0, 31]
45
47
  folder_opts[:mount_tag] = mount_tag
46
48
 
47
- machine.ui.info "================\nMachine id: #{machine.id}\nShould be mounting folders\n #{id}, opts: #{folder_opts}"
48
-
49
49
  xml = Nokogiri::XML::Builder.new do |xml|
50
50
  xml.filesystem(type: 'mount', accessmode: 'passthrough') do
51
51
  xml.driver(type: 'virtiofs')
@@ -73,7 +73,7 @@ module VagrantPlugins
73
73
  # once up, mount folders
74
74
  def enable(machine, folders, _opts)
75
75
  # Go through each folder and mount
76
- machine.ui.info('mounting virtiofs share in guest')
76
+ machine.ui.info I18n.t("vagrant_libvirt.cap.virtiofs.mounting")
77
77
  # Only mount folders that have a guest path specified.
78
78
  mount_folders = {}
79
79
  folders.each do |id, opts|
@@ -91,6 +91,7 @@ module VagrantPlugins
91
91
  raise Vagrant::Errors::Error('No Libvirt connection')
92
92
  end
93
93
  @conn = machine.provider.driver.connection.client
94
+ machine.ui.info I18n.t("vagrant_libvirt.cap.virtiofs.cleanup")
94
95
  begin
95
96
  if machine.id && machine.id != ''
96
97
  dom = @conn.lookup_domain_by_uuid(machine.id)
@@ -98,7 +99,6 @@ module VagrantPlugins
98
99
  '/domain/devices/filesystem'
99
100
  ).each do |xml|
100
101
  dom.detach_device(xml.to_s)
101
- machine.ui.info 'Cleaned up shared folders'
102
102
  end
103
103
  end
104
104
  rescue => e