vagrant-parallels 1.5.1 → 1.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.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +7 -4
  3. data/CHANGELOG.md +33 -0
  4. data/Gemfile +2 -2
  5. data/README.md +1 -1
  6. data/debug.log +1237 -1
  7. data/lib/vagrant-parallels/action.rb +8 -0
  8. data/lib/vagrant-parallels/action/box_register.rb +113 -0
  9. data/lib/vagrant-parallels/action/box_unregister.rb +43 -0
  10. data/lib/vagrant-parallels/action/export.rb +36 -35
  11. data/lib/vagrant-parallels/action/forward_ports.rb +32 -18
  12. data/lib/vagrant-parallels/action/import.rb +59 -106
  13. data/lib/vagrant-parallels/action/network.rb +17 -13
  14. data/lib/vagrant-parallels/action/prepare_clone_snapshot.rb +67 -0
  15. data/lib/vagrant-parallels/action/set_name.rb +1 -1
  16. data/lib/vagrant-parallels/action/snapshot_delete.rb +25 -0
  17. data/lib/vagrant-parallels/action/snapshot_restore.rb +23 -0
  18. data/lib/vagrant-parallels/action/snapshot_save.rb +23 -0
  19. data/lib/vagrant-parallels/cap.rb +63 -0
  20. data/lib/vagrant-parallels/config.rb +7 -3
  21. data/lib/vagrant-parallels/driver/base.rb +61 -28
  22. data/lib/vagrant-parallels/driver/meta.rb +20 -10
  23. data/lib/vagrant-parallels/driver/pd_11.rb +0 -21
  24. data/lib/vagrant-parallels/errors.rb +14 -6
  25. data/lib/vagrant-parallels/guest_cap/darwin/install_parallels_tools.rb +34 -0
  26. data/lib/vagrant-parallels/plugin.rb +23 -8
  27. data/lib/vagrant-parallels/version.rb +1 -1
  28. data/locales/en.yml +31 -17
  29. data/test/acceptance/provider/linked_clone_spec.rb +6 -2
  30. data/test/acceptance/skeletons/linked_clone/Vagrantfile +1 -1
  31. data/test/unit/base.rb +1 -0
  32. data/test/unit/cap_test.rb +96 -0
  33. data/test/unit/support/shared/pd_driver_examples.rb +7 -10
  34. metadata +12 -6
  35. data/lib/vagrant-parallels/cap/forwarded_ports.rb +0 -22
  36. data/lib/vagrant-parallels/cap/host_address.rb +0 -15
  37. data/lib/vagrant-parallels/cap/nic_mac_addresses.rb +0 -17
  38. data/lib/vagrant-parallels/cap/public_address.rb +0 -15
@@ -167,6 +167,7 @@ module VagrantPlugins
167
167
  b1.use HandleForwardedPortCollisions
168
168
  b1.use ForwardPorts
169
169
  b1.use Resume
170
+ b1.use Provision
170
171
  b1.use WaitForCommunicator, [:resuming, :running]
171
172
  end
172
173
  end
@@ -276,7 +277,11 @@ module VagrantPlugins
276
277
  # If the VM is NOT created yet, then do the setup steps
277
278
  if env1[:result]
278
279
  b1.use Customize, 'pre-import'
280
+ b1.use BoxRegister
281
+ b1.use PrepareClone
282
+ b1.use PrepareCloneSnapshot
279
283
  b1.use Import
284
+ b1.use BoxUnregister
280
285
  b1.use SaneDefaults
281
286
  b1.use Customize, 'post-import'
282
287
  end
@@ -330,6 +335,8 @@ module VagrantPlugins
330
335
 
331
336
 
332
337
  autoload :Boot, File.expand_path('../action/boot', __FILE__)
338
+ autoload :BoxRegister, File.expand_path('../action/box_register', __FILE__)
339
+ autoload :BoxUnregister, File.expand_path('../action/box_unregister', __FILE__)
333
340
  autoload :HandleGuestTools, File.expand_path('../action/handle_guest_tools', __FILE__)
334
341
  autoload :HandleForwardedPortCollisions, File.expand_path('../action/handle_forwarded_port_collisions.rb', __FILE__)
335
342
  autoload :ClearNetworkInterfaces, File.expand_path('../action/clear_network_interfaces', __FILE__)
@@ -344,6 +351,7 @@ module VagrantPlugins
344
351
  autoload :Network, File.expand_path('../action/network', __FILE__)
345
352
  autoload :Package, File.expand_path('../action/package', __FILE__)
346
353
  autoload :PackageConfigFiles, File.expand_path('../action/package_config_files', __FILE__)
354
+ autoload :PrepareCloneSnapshot, File.expand_path('../action/prepare_clone_snapshot', __FILE__)
347
355
  autoload :PrepareForwardedPortCollisionParams, File.expand_path('../action/prepare_forwarded_port_collision_params', __FILE__)
348
356
  autoload :PrepareNFSSettings, File.expand_path('../action/prepare_nfs_settings', __FILE__)
349
357
  autoload :PrepareNFSValidIds, File.expand_path('../action/prepare_nfs_valid_ids', __FILE__)
@@ -0,0 +1,113 @@
1
+ require 'log4r'
2
+
3
+ module VagrantPlugins
4
+ module Parallels
5
+ module Action
6
+ class BoxRegister
7
+ @@lock = Mutex.new
8
+
9
+ def initialize(app, env)
10
+ @app = app
11
+ @logger = Log4r::Logger.new('vagrant_parallels::action::box_register')
12
+ end
13
+
14
+ def call(env)
15
+ # If we don't have a box, nothing to do
16
+ if !env[:machine].box
17
+ return @app.call(env)
18
+ end
19
+
20
+ # Do the register while locked so that nobody else register
21
+ # a box at the same time.
22
+ @@lock.synchronize do
23
+ lock_key = Digest::MD5.hexdigest(env[:machine].box.name)
24
+ env[:machine].env.lock(lock_key, retry: true) do
25
+ register_box(env)
26
+ end
27
+ end
28
+
29
+ # If we got interrupted, then the import could have been
30
+ # interrupted and its not a big deal. Just return out.
31
+ return if env[:interrupted]
32
+
33
+ # Register completed successfully. Continue the chain
34
+ @app.call(env)
35
+ end
36
+
37
+ protected
38
+
39
+ def box_path(env)
40
+ pvm = Dir.glob(env[:machine].box.directory.join('*.pvm')).first
41
+
42
+ if !pvm
43
+ raise Errors::BoxImageNotFound, name: env[:machine].box.name
44
+ end
45
+
46
+ pvm
47
+ end
48
+
49
+ def box_id(env, box_path)
50
+ # Get the box image UUID from XML-based configuration file
51
+ tpl_config = File.join(box_path, 'config.pvs')
52
+ xml = Nokogiri::XML(File.open(tpl_config))
53
+ id = xml.xpath('//ParallelsVirtualMachine/Identification/VmUuid').text
54
+
55
+ if !id
56
+ raise Errors::BoxIDNotFound,
57
+ name: env[:machine].box.name,
58
+ config: tpl_config
59
+ end
60
+
61
+ id
62
+ end
63
+
64
+ def register_box(env)
65
+ box_id_file = env[:machine].box.directory.join('box_id')
66
+
67
+ # Read the master ID if we have it in the file.
68
+ env[:clone_id] = box_id_file.read.chomp if box_id_file.file?
69
+
70
+ # If we have the ID and the VM exists already, then we
71
+ # have nothing to do. Success!
72
+ if env[:clone_id] && env[:machine].provider.driver.vm_exists?(env[:clone_id])
73
+ @logger.info(
74
+ "Box image '#{env[:machine].box.name}' is already registered " +
75
+ "(id=#{env[:clone_id]}) - skipping register step.")
76
+ return
77
+ end
78
+
79
+ env[:ui].info I18n.t('vagrant_parallels.actions.vm.box.register',
80
+ name: env[:machine].box.name)
81
+
82
+ pvm = box_path(env)
83
+
84
+ # We need the box ID to be the same for all parallel runs
85
+ options = ['--preserve-uuid']
86
+
87
+ if env[:machine].provider_config.regen_src_uuid \
88
+ && env[:machine].provider.pd_version_satisfies?('>= 10.1.2')
89
+ options << '--regenerate-src-uuid'
90
+ end
91
+
92
+ # Register the box VM image
93
+ env[:machine].provider.driver.register(pvm, options)
94
+ env[:clone_id] = box_id(env, pvm)
95
+
96
+ @logger.info(
97
+ "Registered box #{env[:machine].box.name} with id #{env[:clone_id]}")
98
+
99
+ @logger.debug("Writing box id '#{env[:clone_id]}' to #{box_id_file}")
100
+ box_id_file.open('w+') do |f|
101
+ f.write(env[:clone_id])
102
+ end
103
+
104
+ if env[:machine].provider.pd_version_satisfies?('>= 10')
105
+ # Convert template to VM (compatibility with old-styled boxes)
106
+ env[:machine].provider.driver.execute_prlctl(
107
+ 'set', env[:clone_id], '--template', 'off')
108
+ end
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,43 @@
1
+ require 'log4r'
2
+
3
+ module VagrantPlugins
4
+ module Parallels
5
+ module Action
6
+ class BoxUnregister
7
+ def initialize(app, env)
8
+ @app = app
9
+ @logger = Log4r::Logger.new('vagrant_parallels::action::box_unregister')
10
+ end
11
+
12
+ def call(env)
13
+ # If we don't have a box, nothing to do
14
+ if !env[:machine].box
15
+ return @app.call(env)
16
+ end
17
+
18
+ unregister_box(env)
19
+
20
+ # If we got interrupted, then the import could have been
21
+ # interrupted and its not a big deal. Just return out.
22
+ return if env[:interrupted]
23
+
24
+ # Register completed successfully. Continue the chain
25
+ @app.call(env)
26
+ end
27
+
28
+ def recover(env)
29
+ unregister_box(env)
30
+ end
31
+
32
+ private
33
+
34
+ def unregister_box(env)
35
+ if env[:clone_id] && env[:machine].provider.driver.vm_exists?(env[:clone_id])
36
+ env[:ui].info I18n.t('vagrant_parallels.actions.vm.box.unregister')
37
+ env[:machine].provider.driver.unregister(env[:clone_id])
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -8,84 +8,85 @@ module VagrantPlugins
8
8
  end
9
9
 
10
10
  def call(env)
11
- @env = env
12
11
  if env[:machine].state.id != :stopped
13
12
  raise Vagrant::Errors::VMPowerOffToPackage
14
13
  end
15
14
 
16
- @tpl_name = gen_template_name
17
-
18
- export
19
- compact_template
20
- unregister_template
15
+ clone(env)
16
+ compact(env)
17
+ unregister_vm(env)
21
18
 
22
19
  @app.call(env)
23
20
  end
24
21
 
25
22
  def recover(env)
26
- @env = env
27
- unregister_template
23
+ unregister_vm(env)
28
24
  end
29
25
 
30
26
  private
31
27
 
32
- def gen_template_name
28
+ def box_vm_name(env)
33
29
  # Use configured name if it is specified, or generate the new one
34
- name = @env[:machine].provider_config.name
30
+ name = env[:machine].provider_config.name
35
31
  if !name
36
- name = "#{@env[:root_path].basename.to_s}_#{@env[:machine].name}"
32
+ name = "#{env[:root_path].basename.to_s}_#{env[:machine].name}"
37
33
  name.gsub!(/[^-a-z0-9_]/i, '')
38
34
  end
39
35
 
40
- tpl_name = "#{name}_box"
36
+ vm_name = "#{name}_box"
41
37
 
42
38
  # Ensure that the name is not in use
43
39
  ind = 0
44
- while @env[:machine].provider.driver.read_vms.has_key?(tpl_name)
40
+ while env[:machine].provider.driver.read_vms.has_key?(vm_name)
45
41
  ind += 1
46
- tpl_name = "#{name}_box_#{ind}"
42
+ vm_name = "#{name}_box_#{ind}"
47
43
  end
48
44
 
49
- tpl_name
45
+ vm_name
50
46
  end
51
47
 
52
- def export
53
- @env[:ui].info I18n.t('vagrant.actions.vm.export.exporting')
48
+ def clone(env)
49
+ env[:ui].info I18n.t('vagrant.actions.vm.export.exporting')
54
50
 
55
51
  options = {
56
- template: true,
57
- dst: @env['export.temp_dir'].to_s
52
+ dst: env['export.temp_dir'].to_s
58
53
  }
59
54
 
60
- @env[:machine].provider.driver.clone_vm(@env[:machine].id, @tpl_name, options) do |progress|
61
- @env[:ui].clear_line
62
- @env[:ui].report_progress(progress, 100, false)
55
+ env[:package_box_id] = env[:machine].provider.driver.clone_vm(
56
+ env[:machine].id, options) do |progress|
57
+ env[:ui].clear_line
58
+ env[:ui].report_progress(progress, 100, false)
63
59
 
64
- # # If we got interrupted, then the import could have been interrupted.
65
- # Just rise an exception and then 'recover' will be called to cleanup.
66
- raise Vagrant::Errors::VagrantInterrupt if @env[:interrupted]
60
+ # If we got interrupted, then rise an exception and 'recover'
61
+ # will be called to cleanup.
62
+ raise Vagrant::Errors::VagrantInterrupt if env[:interrupted]
67
63
  end
68
64
 
65
+ # Set the box VM name
66
+ name = box_vm_name(env)
67
+ env[:machine].provider.driver.set_name(env[:package_box_id], name)
68
+
69
69
  # Clear the line a final time so the next data can appear
70
70
  # alone on the line.
71
- @env[:ui].clear_line
71
+ env[:ui].clear_line
72
72
  end
73
73
 
74
- def compact_template
75
- @env[:ui].info I18n.t('vagrant_parallels.actions.vm.export.compacting')
76
- @env[:machine].provider.driver.compact(@tpl_name) do |progress|
77
- @env[:ui].clear_line
78
- @env[:ui].report_progress(progress, 100, false)
74
+ def compact(env)
75
+ env[:ui].info I18n.t('vagrant_parallels.actions.vm.export.compacting')
76
+ env[:machine].provider.driver.compact(env[:package_box_id]) do |progress|
77
+ env[:ui].clear_line
78
+ env[:ui].report_progress(progress, 100, false)
79
79
  end
80
80
 
81
81
  # Clear the line a final time so the next data can appear
82
82
  # alone on the line.
83
- @env[:ui].clear_line
83
+ env[:ui].clear_line
84
84
  end
85
85
 
86
- def unregister_template
87
- @logger.info("Unregister the box template: '#{@tpl_name}'")
88
- @env[:machine].provider.driver.unregister(@tpl_name)
86
+ def unregister_vm(env)
87
+ return if !env[:package_box_id]
88
+ @logger.info("Unregister the box VM: '#{env[:package_box_id]}'")
89
+ env[:machine].provider.driver.unregister(env[:package_box_id])
89
90
  end
90
91
  end
91
92
  end
@@ -3,6 +3,7 @@ module VagrantPlugins
3
3
  module Action
4
4
  class ForwardPorts
5
5
  include VagrantPlugins::Parallels::Util::CompileForwardedPorts
6
+ @@lock = Mutex.new
6
7
 
7
8
  def initialize(app, env)
8
9
  @app = app
@@ -21,13 +22,30 @@ module VagrantPlugins
21
22
 
22
23
  # Get the ports we're forwarding
23
24
  env[:forwarded_ports] ||= compile_forwarded_ports(env[:machine].config)
24
- env[:ui].output(I18n.t('vagrant.actions.vm.forward_ports.forwarding'))
25
- forward_ports
25
+
26
+ # Exit if there are no ports to forward
27
+ return @app.call(env) if env[:forwarded_ports].empty?
28
+
29
+ # Acquire both of class- and process-level locks so that we don't
30
+ # forward ports simultaneousely with someone else.
31
+ @@lock.synchronize do
32
+ begin
33
+ env[:machine].env.lock('forward_ports') do
34
+ env[:ui].output(I18n.t('vagrant.actions.vm.forward_ports.forwarding'))
35
+ forward_ports
36
+ end
37
+ rescue Errors::EnvironmentLockedError
38
+ sleep 1
39
+ retry
40
+ end
41
+ end
26
42
 
27
43
  @app.call(env)
28
44
  end
29
45
 
30
46
  def forward_ports
47
+ all_rules = @env[:machine].provider.driver.read_forwarded_ports(true)
48
+ names_in_use = all_rules.collect { |r| r[:rule_name] }
31
49
  ports = []
32
50
 
33
51
  @env[:forwarded_ports].each do |fp|
@@ -43,11 +61,22 @@ module VagrantPlugins
43
61
  @env[:ui].detail(I18n.t('vagrant_parallels.actions.vm.forward_ports.forwarding_entry',
44
62
  message_attributes))
45
63
 
64
+ # In Parallels Desktop the scope port forwarding rules is global,
65
+ # so we have to keep their names unique.
66
+ unique_id = fp.id
67
+ # Append random suffix to get the unique rule name
68
+ while names_in_use.include?(unique_id)
69
+ suffix = (0...4).map { ('a'..'z').to_a[rand(26)] }.join
70
+ unique_id = "#{fp.id}_#{suffix}"
71
+ end
72
+ # Mark this rule name as in use
73
+ names_in_use << unique_id
74
+
46
75
  # Add the options to the ports array to send to the driver later
47
76
  ports << {
48
77
  guestport: fp.guest_port,
49
78
  hostport: fp.host_port,
50
- name: get_unique_name(fp.id),
79
+ name: unique_id,
51
80
  protocol: fp.protocol
52
81
  }
53
82
  end
@@ -57,21 +86,6 @@ module VagrantPlugins
57
86
  @env[:machine].provider.driver.forward_ports(ports)
58
87
  end
59
88
  end
60
-
61
- private
62
-
63
- def get_unique_name(id)
64
- all_rules = @env[:machine].provider.driver.read_forwarded_ports(true)
65
- names_in_use = all_rules.collect { |r| r[:rule_name] }
66
-
67
- # Append random suffix to get unique rule name
68
- while names_in_use.include?(id)
69
- suffix = (0...4).map { ('a'..'z').to_a[rand(26)] }.join
70
- id = "#{id}_#{suffix}"
71
- end
72
-
73
- id
74
- end
75
89
  end
76
90
  end
77
91
  end
@@ -1,17 +1,19 @@
1
1
  require 'nokogiri'
2
2
 
3
+ require 'digest/md5'
4
+
3
5
  module VagrantPlugins
4
6
  module Parallels
5
7
  module Action
6
8
  class Import
9
+ @@lock = Mutex.new
10
+
7
11
  def initialize(app, env)
8
12
  @app = app
9
13
  @logger = Log4r::Logger.new('vagrant_parallels::action::import')
10
14
  end
11
15
 
12
16
  def call(env)
13
- @machine = env[:machine]
14
-
15
17
  # Disable requiring password for register and clone actions [GH-67].
16
18
  # It is available only since PD 10.
17
19
  if env[:machine].provider.pd_version_satisfies?('>= 10')
@@ -20,32 +22,54 @@ module VagrantPlugins
20
22
  env[:machine].provider.driver.disable_password_restrictions(acts)
21
23
  end
22
24
 
23
- # Register template to be able to clone it further
24
- register_template(template_path.to_s)
25
+ # Linked clones are supported only for PD 11 and higher
26
+ if env[:machine].provider_config.linked_clone \
27
+ && env[:machine].provider.pd_version_satisfies?('>= 11')
28
+ # Linked clone creation should not be concurrent [GH-206]
29
+ @@lock.synchronize do
30
+ lock_key = Digest::MD5.hexdigest("#{env[:clone_id]}-linked-clone")
31
+ env[:machine].env.lock(lock_key, retry: true) do
32
+ clone_linked(env)
33
+ end
34
+ end
35
+ else
36
+ clone_full(env)
37
+ end
25
38
 
26
- # Get template name. It might be changed during registration if name
27
- # collision has been occurred
28
- tpl_name = template_name(template_path)
39
+ # If we got interrupted, then the import could have been
40
+ # interrupted and its not a big deal. Just return out.
41
+ return if env[:interrupted]
29
42
 
30
- # Import VM, e.q. clone it from registered template
31
- import(env, tpl_name)
43
+ # Flag as erroneous and return if import failed
44
+ raise Errors::VMCloneFailure if !env[:machine].id
32
45
 
33
- # Hide template since we dont need it anymore
34
- unregister_template(tpl_name)
46
+ if env[:machine].provider_config.regen_src_uuid \
47
+ && env[:machine].provider.pd_version_satisfies?('< 11')
48
+ @logger.info('Regenerate SourceVmUuid by editing config.pvs file')
49
+ env[:machine].provider.driver.regenerate_src_uuid
50
+ end
35
51
 
36
- # Flag as erroneous and return if import failed
37
- raise Errors::VMImportFailure if !@machine.id
52
+ # Remove 'Icon\r' file from VM home (bug in PD 11.0.0)
53
+ if env[:machine].provider.pd_version_satisfies?('= 11.0.0')
54
+ vm_home = env[:machine].provider.driver.read_settings.fetch('Home')
55
+ broken_icns = Dir[File.join(vm_home, 'Icon*')]
56
+ FileUtils.rm(broken_icns, :force => true)
57
+ end
58
+
59
+ # Copy the SSH key from the clone machine if we can
60
+ if env[:clone_machine]
61
+ key_path = env[:clone_machine].data_dir.join('private_key')
62
+ if key_path.file?
63
+ FileUtils.cp(key_path, env[:machine].data_dir.join('private_key'))
64
+ end
65
+ end
38
66
 
39
67
  # Import completed successfully. Continue the chain
40
68
  @app.call(env)
41
69
  end
42
70
 
43
71
  def recover(env)
44
- # We should to unregister template
45
- tpl_name = template_name(template_path)
46
- unregister_template(tpl_name)
47
-
48
- if @machine.state.id != :not_created
72
+ if env[:machine] && env[:machine].state.id != :not_created
49
73
  return if env['vagrant.error'].is_a?(Vagrant::Errors::VagrantError)
50
74
  return if env['vagrant_parallels.error'].is_a?(Errors::VagrantParallelsError)
51
75
 
@@ -64,78 +88,12 @@ module VagrantPlugins
64
88
 
65
89
  protected
66
90
 
67
- def register_template(tpl_path_s)
68
- @logger.info("Register the box template: '#{tpl_path_s}'")
69
- @machine.provider.driver.register(tpl_path_s)
70
- end
71
-
72
- def template_path
73
- Pathname.glob(@machine.box.directory.join('*.pvm')).first
74
- end
75
-
76
- def template_name(tpl_path)
77
- # Get template name from XML-based configuration file
78
- tpl_config = tpl_path.join('config.pvs')
79
- xml = Nokogiri::XML(File.open(tpl_config))
80
- name = xml.xpath('//ParallelsVirtualMachine/Identification/VmName').text
81
-
82
- if !name
83
- raise Errors::ParallelsTplNameNotFound, config_path: tpl_config
84
- end
85
-
86
- name
87
- end
88
-
89
- def import(env, tpl_name)
90
- # Linked clones are supported only for PD 11 and higher
91
- if @machine.provider_config.use_linked_clone \
92
- && @machine.provider.pd_version_satisfies?('>= 11')
93
-
94
- env[:ui].info I18n.t('vagrant_parallels.actions.vm.import.importing_linked',
95
- :name => @machine.box.name)
96
- opts = {
97
- snapshot_id: snapshot_id(tpl_name),
98
- linked: true
99
- }
100
- # Linked clone creation should not be concurrent [GH-206]
101
- begin
102
- @machine.env.lock("parallels_linked_clone") do
103
- clone(env, tpl_name, opts)
104
- end
105
- rescue Vagrant::Errors::EnvironmentLockedError
106
- sleep 1
107
- retry
108
- end
109
- else
110
- env[:ui].info I18n.t('vagrant.actions.vm.import.importing',
111
- :name => @machine.box.name)
112
- clone(env, tpl_name)
113
- end
114
-
115
- if @machine.provider_config.regen_src_uuid
116
- @logger.info('Regenerate SourceVmUuid')
117
- @machine.provider.driver.regenerate_src_uuid
118
- end
119
-
120
- # Remove 'Icon\r' file from VM home (bug in PD 11.0.0)
121
- if @machine.provider.pd_version_satisfies?('= 11.0.0')
122
- vm_home = @machine.provider.driver.read_settings.fetch('Home')
123
- broken_icns = Dir[File.join(vm_home, 'Icon*')]
124
- FileUtils.rm(broken_icns, :force => true)
125
- end
126
- end
127
-
128
- def clone(env, tpl_name, opts={})
129
- # Generate virtual machine name
130
- vm_name = "#{tpl_name}_#{(Time.now.to_f * 1000.0).to_i}_#{rand(100000)}"
131
-
132
- @machine.id = @machine.provider.driver.clone_vm(tpl_name, vm_name, opts) do |progress|
91
+ def clone_full(env)
92
+ env[:ui].info I18n.t('vagrant_parallels.actions.vm.clone.full')
93
+ env[:machine].id = env[:machine].provider.driver.clone_vm(
94
+ env[:clone_id]) do |progress|
133
95
  env[:ui].clear_line
134
96
  env[:ui].report_progress(progress, 100, false)
135
-
136
- # # If we got interrupted, then the import could have been interrupted.
137
- # Just rise an exception and then 'recover' will be called to cleanup.
138
- raise Vagrant::Errors::VagrantInterrupt if env[:interrupted]
139
97
  end
140
98
 
141
99
  # Clear the line one last time since the progress meter doesn't disappear
@@ -143,26 +101,21 @@ module VagrantPlugins
143
101
  env[:ui].clear_line
144
102
  end
145
103
 
146
- def snapshot_id(tpl_name)
147
- snap_id = @machine.provider.driver.read_current_snapshot(tpl_name)
148
-
149
- # If there is no current snapshot, just create the new one.
150
- if !snap_id
151
- @logger.info('Create a new snapshot')
152
- opts = {
153
- name: 'vagrant_linked_clone',
154
- desc: 'Snapshot to create linked clones for Vagrant'
155
- }
156
- snap_id = @machine.provider.driver.create_snapshot(tpl_name, opts)
104
+ def clone_linked(env)
105
+ opts = {
106
+ snapshot_id: env[:clone_snapshot_id],
107
+ linked: true
108
+ }
109
+ env[:ui].info I18n.t('vagrant_parallels.actions.vm.clone.linked')
110
+ env[:machine].id = env[:machine].provider.driver.clone_vm(
111
+ env[:clone_id], opts) do |progress|
112
+ env[:ui].clear_line
113
+ env[:ui].report_progress(progress, 100, false)
157
114
  end
158
115
 
159
- @logger.info("User this snapshot ID to create a linked clone: #{snap_id}")
160
- snap_id
161
- end
162
-
163
- def unregister_template(tpl_name)
164
- @logger.info("Unregister the box template: '#{tpl_name}'")
165
- @machine.provider.driver.unregister(tpl_name)
116
+ # Clear the line one last time since the progress meter doesn't disappear
117
+ # immediately.
118
+ env[:ui].clear_line
166
119
  end
167
120
  end
168
121
  end