vagrant-parallels 1.2.2 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5f3bf1ad034ff3a2348dd22548ffb3d28659a88b
4
- data.tar.gz: 87d833100c9d729fce001d72797e482a06702e1d
3
+ metadata.gz: f3e2eafea3e2e0ae509943e4ebb2cb4a130b3d56
4
+ data.tar.gz: 9b0786ae6319a6de87a44177dc6d71a38092a2bb
5
5
  SHA512:
6
- metadata.gz: 4bddae6096c51c901b09c06b7cadc0e276de1ee1d7324bc1f74e8ebb28a4ce0fbd7eddf1e744594e7d62cf282240a6254e23613b10cbe47e275f0d88dbb16811
7
- data.tar.gz: 3f830fd2bb2b74d2fa1ae312ae7c233f34aaf3e8e4b9328482d86e366a149f9be386f020157391c4b05fd6e6886bf3e9c6d3c50eecdcb435b188e1b62310f8b6
6
+ metadata.gz: c99c4916c89822602b2436c56be351cd4ac2d796f89fefee4d0a08caeb7eac55a30a18504a2c4f7b3f670d9d26e06a537c37e06798f279026aff921885ff0eb4
7
+ data.tar.gz: 87a0f541244f1cf52d8d74e52c86ee7c7b5dab6653a9d2c8c2a967e0319c2fa753cb3057fb01e8b6d2c951e656685af85f1c94d65de032fcf0c90b85d5e75681
data/.travis.yml CHANGED
@@ -1,8 +1,6 @@
1
1
  language: ruby
2
2
  before_install:
3
- - sudo apt-get update -qq
4
- - sudo apt-get install -qq -y bsdtar
5
- - gem install bundler -v '1.5.2'
3
+ - gem install bundler -v '1.6.6'
6
4
  rvm:
7
5
  - 2.0.0
8
6
  script: rake test:unit
data/LICENSE.txt CHANGED
@@ -1,4 +1,5 @@
1
1
  Copyright (c) 2013 Youssef Shahin
2
+ Copyright (c) 2013-2014 Parallels IP Holdings GmbH.
2
3
 
3
4
  MIT License
4
5
 
@@ -304,6 +304,31 @@ module VagrantPlugins
304
304
  end
305
305
  end
306
306
 
307
+ # This action sync folders on a running provider. It is used by the docker provider
308
+ # to link synced folders on the host machine as volumes into the docker containers
309
+ def self.action_sync_folders
310
+ Vagrant::Action::Builder.new.tap do |b|
311
+ b.use ConfigValidate
312
+ b.use Call, IsState, :not_created do |env1, b1|
313
+ if env1[:result]
314
+ b1.use Message, I18n.t("vagrant.commands.common.vm_not_created")
315
+ next
316
+ end
317
+
318
+ b1.use Call, IsState, :running do |env2, b2|
319
+ if !env2[:result]
320
+ b2.use Message, I18n.t("vagrant.commands.common.vm_not_running")
321
+ next
322
+ end
323
+
324
+ b2.use SyncedFolders
325
+ b2.use PrepareNFSSettings
326
+ end
327
+ end
328
+ end
329
+ end
330
+
331
+
307
332
  autoload :Boot, File.expand_path("../action/boot", __FILE__)
308
333
  autoload :HandleGuestTools, File.expand_path("../action/handle_guest_tools", __FILE__)
309
334
  autoload :HandleForwardedPortCollisions, File.expand_path("../action/handle_forwarded_port_collisions.rb", __FILE__)
@@ -13,17 +13,9 @@ module VagrantPlugins
13
13
  raise Vagrant::Errors::VMPowerOffToPackage
14
14
  end
15
15
 
16
- name = "#{env[:root_path].basename.to_s}_#{env[:machine].name}"
17
- name.gsub!(/[^-a-z0-9_]/i, "")
16
+ @tpl_name = gen_template_name
18
17
 
19
- # Check the name is not in use
20
- if @env[:machine].provider.driver.read_vms.has_key?(@template_name)
21
- @template_name << rand(100000).to_s
22
- end
23
-
24
-
25
- @template_name = gen_template_name
26
- @template_uuid = export
18
+ export
27
19
  compact_template
28
20
  unregister_template
29
21
 
@@ -42,21 +34,24 @@ module VagrantPlugins
42
34
  name = @env[:machine].provider_config.name
43
35
  if !name
44
36
  name = "#{@env[:root_path].basename.to_s}_#{@env[:machine].name}"
45
- name.gsub!(/[^-a-z0-9_]/i, "")
37
+ name.gsub!(/[^-a-z0-9_]/i, '')
46
38
  end
39
+
47
40
  tpl_name = "#{name}_box"
48
41
 
49
42
  # Ensure that the name is not in use
50
- if @env[:machine].provider.driver.read_vms.has_key?(tpl_name)
51
- tpl_name << "_#{rand(1000)}"
43
+ ind = 0
44
+ while @env[:machine].provider.driver.read_vms.has_key?(tpl_name)
45
+ ind += 1
46
+ tpl_name = "#{name}_box_#{ind}"
52
47
  end
53
48
 
54
49
  tpl_name
55
50
  end
56
51
 
57
52
  def export
58
- @env[:ui].info I18n.t("vagrant.actions.vm.export.exporting")
59
- tpl_uuid = @env[:machine].provider.driver.export(@env["export.temp_dir"], @template_name) do |progress|
53
+ @env[:ui].info I18n.t('vagrant.actions.vm.export.exporting')
54
+ @env[:machine].provider.driver.export(@env['export.temp_dir'], @tpl_name) do |progress|
60
55
  @env[:ui].clear_line
61
56
  @env[:ui].report_progress(progress, 100, false)
62
57
 
@@ -68,13 +63,11 @@ module VagrantPlugins
68
63
  # Clear the line a final time so the next data can appear
69
64
  # alone on the line.
70
65
  @env[:ui].clear_line
71
-
72
- tpl_uuid
73
66
  end
74
67
 
75
68
  def compact_template
76
- @env[:ui].info I18n.t("vagrant_parallels.actions.vm.export.compacting")
77
- @env[:machine].provider.driver.compact(@template_uuid) do |progress|
69
+ @env[:ui].info I18n.t('vagrant_parallels.actions.vm.export.compacting')
70
+ @env[:machine].provider.driver.compact(@tpl_name) do |progress|
78
71
  @env[:ui].clear_line
79
72
  @env[:ui].report_progress(progress, 100, false)
80
73
  end
@@ -85,10 +78,8 @@ module VagrantPlugins
85
78
  end
86
79
 
87
80
  def unregister_template
88
- if @env[:machine].provider.driver.registered?(@template_uuid)
89
- @logger.info("Unregister the box template: '#{@template_uuid}'")
90
- @env[:machine].provider.driver.unregister(@template_uuid)
91
- end
81
+ @logger.info("Unregister the box template: '#{@tpl_name}'")
82
+ @env[:machine].provider.driver.unregister(@tpl_name)
92
83
  end
93
84
  end
94
85
  end
@@ -13,7 +13,7 @@ module VagrantPlugins
13
13
  if env[:machine].provider.pd_version_satisfies?('>= 10')
14
14
  super
15
15
  else
16
- # Just continue if port forwarding is not supporting
16
+ # Just continue if port forwarding is not supported
17
17
  @app.call(env)
18
18
  end
19
19
  end
@@ -22,7 +22,7 @@ module VagrantPlugins
22
22
  if env[:machine].provider.pd_version_satisfies?('>= 10')
23
23
  super
24
24
  end
25
- # Do nothing if port forwarding is not supporting
25
+ # Do nothing if port forwarding is not supported
26
26
  end
27
27
  end
28
28
  end
@@ -1,3 +1,5 @@
1
+ require 'nokogiri'
2
+
1
3
  module VagrantPlugins
2
4
  module Parallels
3
5
  module Action
@@ -8,27 +10,36 @@ module VagrantPlugins
8
10
  end
9
11
 
10
12
  def call(env)
11
- @env = env
12
- @template_path = File.realpath(Pathname.glob(env[:machine].box.directory.join('*.pvm')).first)
13
- @template_uuid = register_template
14
- import
15
- unregister_template
13
+ @machine = env[:machine]
14
+
15
+ # Register template to be able to clone it further
16
+ register_template(template_path.to_s)
17
+
18
+ # Get template name. It might be changed during registration if name
19
+ # collision has been occurred
20
+ tpl_name = template_name(template_path)
21
+
22
+ # Import VM, e.q. clone it from registered template
23
+ import(env, tpl_name)
24
+
25
+ # Hide template since we dont need it anymore
26
+ unregister_template(tpl_name)
16
27
 
17
28
  # Flag as erroneous and return if import failed
18
- raise VagrantPlugins::Parallels::Errors::VMImportFailure if !env[:machine].id
29
+ raise Errors::VMImportFailure if !@machine.id
19
30
 
20
31
  # Import completed successfully. Continue the chain
21
32
  @app.call(env)
22
33
  end
23
34
 
24
35
  def recover(env)
25
- @env = env
26
36
  # We should to unregister template
27
- unregister_template
37
+ tpl_name = template_name(template_path)
38
+ unregister_template(tpl_name)
28
39
 
29
- if env[:machine].state.id != :not_created
40
+ if @machine.state.id != :not_created
30
41
  return if env["vagrant.error"].is_a?(Vagrant::Errors::VagrantError)
31
- return if env["vagrant_parallels.error"].is_a?(VagrantPlugins::Parallels::Errors::VagrantParallelsError)
42
+ return if env["vagrant_parallels.error"].is_a?(Errors::VagrantParallelsError)
32
43
 
33
44
  # If we're not supposed to destroy on error then just return
34
45
  return if !env[:destroy_on_error]
@@ -45,42 +56,51 @@ module VagrantPlugins
45
56
 
46
57
  protected
47
58
 
48
- def register_template
49
- if !@env[:machine].provider.driver.read_vms_paths.has_key?(@template_path)
50
- @logger.info("Register the box template: '#{@template_path}'")
51
- regen_uuid = @env[:machine].provider_config.regen_box_uuid
59
+ def register_template(tpl_path_s)
60
+ @logger.info("Register the box template: '#{tpl_path_s}'")
61
+ regen_uuid = @machine.provider_config.regen_box_uuid
52
62
 
53
- @env[:machine].provider.driver.register(@template_path, regen_uuid)
54
- end
63
+ @machine.provider.driver.register(tpl_path_s, regen_uuid)
64
+ end
55
65
 
56
- # Return the uuid of registered template
57
- @env[:machine].provider.driver.read_vms_paths[@template_path]
66
+ def template_path
67
+ Pathname.glob(@machine.box.directory.join('*.pvm')).first
58
68
  end
59
69
 
60
- def import
61
- @env[:ui].info I18n.t("vagrant.actions.vm.import.importing",
62
- :name => @env[:machine].box.name)
70
+ def template_name(tpl_path)
71
+ # Get template name from XML-based configuration file
72
+ tpl_config = tpl_path.join('config.pvs')
73
+ xml = Nokogiri::XML(File.open(tpl_config))
74
+ name = xml.xpath('//ParallelsVirtualMachine/Identification/VmName').text
75
+
76
+ if !name
77
+ raise Errors::ParallelsTplNameNotFound, config_path: tpl_config
78
+ end
79
+
80
+ name
81
+ end
63
82
 
83
+ def import(env, tpl_name)
84
+ env[:ui].info I18n.t("vagrant.actions.vm.import.importing",
85
+ :name => @machine.box.name)
64
86
  # Import the virtual machine
65
- @env[:machine].id = @env[:machine].provider.driver.import(@template_uuid) do |progress|
66
- @env[:ui].clear_line
67
- @env[:ui].report_progress(progress, 100, false)
87
+ @machine.id = @machine.provider.driver.import(tpl_name) do |progress|
88
+ env[:ui].clear_line
89
+ env[:ui].report_progress(progress, 100, false)
68
90
 
69
91
  # # If we got interrupted, then the import could have been interrupted.
70
92
  # Just rise an exception and then 'recover' will be called to cleanup.
71
- raise Vagrant::Errors::VagrantInterrupt if @env[:interrupted]
93
+ raise Vagrant::Errors::VagrantInterrupt if env[:interrupted]
72
94
  end
73
95
 
74
96
  # Clear the line one last time since the progress meter doesn't disappear
75
97
  # immediately.
76
- @env[:ui].clear_line
98
+ env[:ui].clear_line
77
99
  end
78
100
 
79
- def unregister_template
80
- if @env[:machine].provider.driver.registered?(@template_uuid)
81
- @logger.info("Unregister the box template: '#{@template_uuid}'")
82
- @env[:machine].provider.driver.unregister(@template_uuid)
83
- end
101
+ def unregister_template(tpl_name)
102
+ @logger.info("Unregister the box template: '#{tpl_name}'")
103
+ @machine.provider.driver.unregister(tpl_name)
84
104
  end
85
105
  end
86
106
  end
@@ -234,6 +234,7 @@ module VagrantPlugins
234
234
  options = {
235
235
  auto_config: true,
236
236
  mac: nil,
237
+ name: nil,
237
238
  nic_type: nil,
238
239
  netmask: "255.255.255.0",
239
240
  type: :static
@@ -293,6 +294,7 @@ module VagrantPlugins
293
294
  auto_config: options[:auto_config],
294
295
  ip: options[:ip],
295
296
  mac: options[:mac],
297
+ name: options[:name],
296
298
  netmask: options[:netmask],
297
299
  nic_type: options[:nic_type],
298
300
  type: options[:type]
@@ -306,12 +308,6 @@ module VagrantPlugins
306
308
  if !interface
307
309
  @logger.info("Network not found. Creating if we can.")
308
310
 
309
- # It is an error if a specific host only network name was specified
310
- # but the network wasn't found.
311
- if config[:name]
312
- raise Vagrant::Errors::NetworkNotFound, :name => config[:name]
313
- end
314
-
315
311
  # Create a new network
316
312
  interface = hostonly_create_network(config)
317
313
  @logger.info("Created network: #{interface[:name]}")
@@ -414,7 +410,7 @@ module VagrantPlugins
414
410
  # This creates a host only network for the given configuration.
415
411
  def hostonly_create_network(config)
416
412
  options = {
417
- network_id: next_network_id,
413
+ network_id: config[:name] || next_network_id,
418
414
  adapter_ip: config[:adapter_ip],
419
415
  netmask: config[:netmask],
420
416
  }
@@ -432,15 +428,20 @@ module VagrantPlugins
432
428
 
433
429
  # This finds a matching host only network for the given configuration.
434
430
  def hostonly_find_matching_network(config)
435
- this_netaddr = network_address(config[:ip], config[:netmask])
431
+ existing = @env[:machine].provider.driver.read_host_only_interfaces
436
432
 
437
- @env[:machine].provider.driver.read_host_only_interfaces.each do |interface|
438
- return interface if config[:name] && config[:name] == interface[:name]
439
- return interface if this_netaddr == \
440
- network_address(interface[:ip], interface[:netmask])
433
+ if config[:name]
434
+ # Search networks strongly by specified name
435
+ matched_iface = existing.detect { |i| config[:name] == i[:name] }
436
+ else
437
+ # Name is not specified - search by network address
438
+ this_netaddr = network_address(config[:ip], config[:netmask])
439
+ matched_iface = existing.detect do |i|
440
+ this_netaddr == network_address(i[:ip], i[:netmask])
441
+ end
441
442
  end
442
443
 
443
- nil
444
+ matched_iface || nil
444
445
  end
445
446
  end
446
447
  end
@@ -11,7 +11,7 @@ module VagrantPlugins
11
11
  @machine = env[:machine]
12
12
  @app.call(env)
13
13
 
14
- if using_nfs?
14
+ if using_nfs?(@machine.config.vm) || using_nfs?(env[:synced_folders_config])
15
15
  @logger.info("Using NFS, preparing NFS settings by reading host IP and machine IP")
16
16
  add_ips_to_env!(env)
17
17
  end
@@ -20,8 +20,8 @@ module VagrantPlugins
20
20
  # We're using NFS if we have any synced folder with NFS configured. If
21
21
  # we are not using NFS we don't need to do the extra work to
22
22
  # populate these fields in the environment.
23
- def using_nfs?
24
- @machine.config.vm.synced_folders.any? { |_, opts| opts[:type] == :nfs }
23
+ def using_nfs?(env)
24
+ env && env.synced_folders.any? { |_, opts| opts[:type] == :nfs }
25
25
  end
26
26
 
27
27
  # Extracts the proper host and guest IPs for NFS mounts and stores them
@@ -30,9 +30,8 @@ module VagrantPlugins
30
30
  #
31
31
  # The ! indicates that this method modifies its argument.
32
32
  def add_ips_to_env!(env)
33
- adapter, host_ip = find_host_only_adapter
34
- machine_ip = nil
35
- machine_ip = read_machine_ip if adapter
33
+ host_ip = find_host_only_adapter
34
+ machine_ip = read_machine_ip
36
35
 
37
36
  raise Vagrant::Errors::NFSNoHostonlyNetwork if !host_ip || !machine_ip
38
37
 
@@ -40,18 +39,23 @@ module VagrantPlugins
40
39
  env[:nfs_machine_ip] = machine_ip
41
40
  end
42
41
 
43
- # Finds first host only network adapter and returns its adapter number
44
- # and IP address
42
+ # Finds first host only network adapter and returns its IP address
45
43
  #
46
- # @return [Integer, String] adapter number, ip address of found host-only adapter
44
+ # @return [String] ip address of found host-only adapter
47
45
  def find_host_only_adapter
48
- @machine.provider.driver.read_network_interfaces.each do |adapter, opts|
49
- if opts[:type] == :hostonly
50
- @machine.provider.driver.read_host_only_interfaces.each do |interface|
51
- if interface[:name] == opts[:hostonly]
52
- return adapter, interface[:ip]
53
- end
46
+ host_only_all = @machine.provider.driver.read_host_only_interfaces
47
+ host_only_used = @machine.provider.driver.read_network_interfaces.
48
+ select { |_, opts| opts[:type] == :hostonly }
49
+
50
+ host_only_used.each do |_, opts|
51
+ host_only_all.each do |interface|
52
+ if @machine.provider.pd_version_satisfies?('>= 10')
53
+ name_matched = interface[:name] == opts[:hostonly]
54
+ else
55
+ name_matched = interface[:bound_to] == opts[:hostonly]
54
56
  end
57
+
58
+ return interface[:ip] if name_matched
55
59
  end
56
60
  end
57
61
 
@@ -177,6 +177,14 @@ module VagrantPlugins
177
177
  def read_state
178
178
  end
179
179
 
180
+ # Returns a value of specified VM option
181
+ #
182
+ # @param [String] option Name of option (See all: `prlctl list -L`)
183
+ # @param [String] uuid Virtual machine UUID
184
+ # @return [String]
185
+ def read_vm_option(option, uuid=@uuid)
186
+ end
187
+
180
188
  # Returns a list of all registered
181
189
  # virtual machines and templates.
182
190
  #
@@ -105,7 +105,6 @@ module VagrantPlugins
105
105
  :read_vms_info,
106
106
  :read_vms_paths,
107
107
  :register,
108
- :registered?,
109
108
  :resume,
110
109
  :set_power_consumption_mode,
111
110
  :set_mac_address,
@@ -155,8 +155,8 @@ module VagrantPlugins
155
155
  net_list.each do |iface|
156
156
  info = {}
157
157
  net_info = json { execute_prlsrvctl('net', 'info', iface['Network ID'], '--json') }
158
- # Really we need to work with bounded virtual interface
159
158
  info[:name] = net_info['Network ID']
159
+ info[:bound_to] = net_info['Bound To']
160
160
  info[:ip] = net_info['Parallels adapter']['IP address']
161
161
  info[:netmask] = net_info['Parallels adapter']['Subnet mask']
162
162
  # Such interfaces are always in 'Up'
@@ -237,18 +237,6 @@ module VagrantPlugins
237
237
  info
238
238
  end
239
239
 
240
- # Parse the JSON from *all* VMs and templates.
241
- # Then return an array of objects (without duplicates)
242
- def read_vms_info
243
- vms_arr = json([]) do
244
- execute_prlctl('list', '--all','--info', '--json')
245
- end
246
- templates_arr = json([]) do
247
- execute_prlctl('list', '--all','--info', '--json', '--template')
248
- end
249
- vms_arr | templates_arr
250
- end
251
-
252
240
  def read_used_ports
253
241
  # Ignore our own used ports
254
242
  read_forwarded_ports(true).reject { |r| r[:guest].include?(@uuid) }