vagrant-parallels 1.6.3 → 1.7.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 96a1ffdfb9901688a2af90776e4c7f86c1ea5d27
4
- data.tar.gz: dedfe0e23fbcaf6b429f31f422bb96b32ad2c7da
3
+ metadata.gz: 0e014ab2a7c2e81aebb3325f22e60334982cceed
4
+ data.tar.gz: 180a1225025aa7b162173b7f46ab7eb695db30ce
5
5
  SHA512:
6
- metadata.gz: 20bc34e6060d31b4af5656c360146104f90fad6d967797c2f6d674f50f5ab5da2c9505dd97cb6c9f919f79e9fe6309412e7a1582ffe8f5587b4c52a1c05e574c
7
- data.tar.gz: 9ced0b39362f1f48a7bffb36f7b5477ddac77ef37ff475fc1dd836f066aefd5912a146e729962a7658ffe6222dd8dc0723b64993cd24a5bee73ef8e4095a3529
6
+ metadata.gz: 3c932834e0ef5d2e4ae6cc91b17569b0f56c9c6246b23e228a966ffbd1932bb9a0760383382331b9bb985f5f226b4f96a75025f2b5f762a33d40c8732fb45c5b
7
+ data.tar.gz: 5c55c0dd9852a23133bd4dce45fd395e19790529f1de6b486ccf6cd07737606f170a7fd929af07f1e7b8eeaf8524f77bcc9e659c762221b3c73a507823275dcb
data/CHANGELOG.md CHANGED
@@ -1,6 +1,22 @@
1
+ ## 1.7.0 (November 15, 2016)
2
+ BREAKING CHANGES:
3
+ - **Dropped support of Parallels Desktop 8 and 9**. These versions have
4
+ reached their [End-of-Life and End-of-Support](http://kb.parallels.com/eu/122533).
5
+ - **Removed customization options, which were previously deprecated:**
6
+ [[GH-271](https://github.com/Parallels/vagrant-parallels/pull/271)]
7
+ - "use_linked_clone" - use `linked_clone` instead.
8
+ - "regen_box_uuid" - use `regen_src_uuid` instead.
9
+ - "optimize_power_consumption".
10
+
11
+ FEATURES:
12
+ - **IPv6 Private Networks:** Private networking now supports IPv6.
13
+ This only works with Parallels Desktop 12 and higher.
14
+ [[GH-273](https://github.com/Parallels/vagrant-parallels/pull/273)]
15
+
16
+
1
17
  ## 1.6.3 (July 11, 2016)
2
18
  DEPRECATIONS:
3
- - The following provider options was renamed:
19
+ - The following provider options were renamed:
4
20
  - `regen_box_uuid` was renamed to `regen_src_uuid`
5
21
  - `use_linked_clone` was renamed to `linked clone`
6
22
 
data/README.md CHANGED
@@ -4,15 +4,15 @@
4
4
  [![Code Climate](https://codeclimate.com/github/Parallels/vagrant-parallels.png)](https://codeclimate.com/github/Parallels/vagrant-parallels)
5
5
 
6
6
  This is a plugin for [Vagrant](http://www.vagrantup.com),
7
- allowing to power [Parallels Desktop for Mac](http://www.parallels.com/products/desktop/)
8
- based virtual machines.
7
+ allowing to manage [Parallels Desktop](http://www.parallels.com/products/desktop/)
8
+ virtual machines on OS X hosts.
9
9
 
10
10
  ### Requirements
11
11
  - [Vagrant v1.8](http://www.vagrantup.com) or higher
12
- - [Parallels Desktop 8 for Mac](http://www.parallels.com/products/desktop/) or higher
12
+ - [Parallels Desktop 10 for Mac](http://www.parallels.com/products/desktop/) or higher
13
13
 
14
- *Note:* In [**Parallels Desktop 11 for Mac**](http://www.parallels.com/products/desktop/),
15
- only **Pro** and **Business** editions are compatible with this Vagrant provider.
14
+ *Note:* Only **Pro** and **Business** editions of **Parallels Desktop for Mac**
15
+ are compatible with this Vagrant provider.
16
16
  Standard edition doesn't have a command line functionality and can not be used
17
17
  with Vagrant.
18
18
 
@@ -55,17 +55,6 @@ please report it on the [Issue Tracker](https://github.com/Parallels/vagrant-par
55
55
 
56
56
  * Author: Youssef Shahin <yshahin@gmail.com>
57
57
  * Author: Mikhail Zholobov <legal90@gmail.com>
58
- * Copyright 2013-2015, Parallels IP Holdings GmbH.
58
+ * Copyright 2013-2016, Parallels IP Holdings GmbH.
59
59
 
60
- ```text
61
- Licensed under the Apache License, Version 2.0 (the "License");
62
- you may not use this file except in compliance with the License.
63
- You may obtain a copy of the License at
64
-
65
- http://www.apache.org/licenses/LICENSE-2.0
66
-
67
- Unless required by applicable law or agreed to in writing, software
68
- distributed under the License is distributed on an "AS IS" BASIS,
69
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
70
- See the License for the specific language governing permissions and
71
- ```
60
+ Vagrant Parallels Provider is open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT).
@@ -119,11 +119,9 @@ module VagrantPlugins
119
119
  f.write(env[:clone_id])
120
120
  end
121
121
 
122
- if env[:machine].provider.pd_version_satisfies?('>= 10')
123
- # Convert template to VM (compatibility with old-styled boxes)
124
- env[:machine].provider.driver.execute_prlctl(
125
- 'set', env[:clone_id], '--template', 'off')
126
- end
122
+ # Convert template to VM (compatibility with old-styled boxes)
123
+ env[:machine].provider.driver.execute_prlctl(
124
+ 'set', env[:clone_id], '--template', 'off')
127
125
  end
128
126
  end
129
127
  end
@@ -7,11 +7,6 @@ module VagrantPlugins
7
7
  end
8
8
 
9
9
  def call(env)
10
- # Port Forwarding feature is available only with PD >= 10
11
- if !env[:machine].provider.pd_version_satisfies?('>= 10')
12
- return @app.call(env)
13
- end
14
-
15
10
  ports = env[:machine].provider.driver.read_forwarded_ports
16
11
  if !ports.empty?
17
12
  env[:ui].info I18n.t('vagrant.actions.vm.clear_forward_ports.deleting')
@@ -8,12 +8,8 @@ module VagrantPlugins
8
8
  end
9
9
 
10
10
  def call(env)
11
- # Disable requiring password for delete action [GH-67].
12
- # It is available only since PD 10.
13
- if env[:machine].provider.pd_version_satisfies?('>= 10')
14
- @logger.info('Disabling password restrictions: remove-vm')
15
- env[:machine].provider.driver.disable_password_restrictions(['remove-vm'])
16
- end
11
+ @logger.info('Disabling password restrictions: remove-vm')
12
+ env[:machine].provider.driver.disable_password_restrictions(['remove-vm'])
17
13
 
18
14
  env[:ui].info I18n.t('vagrant.actions.vm.destroy.destroying')
19
15
  env[:machine].provider.driver.delete
@@ -13,11 +13,6 @@ module VagrantPlugins
13
13
  # Execution
14
14
  #--------------------------------------------------------------
15
15
  def call(env)
16
- # Port Forwarding feature is available only with PD >= 10
17
- if !env[:machine].provider.pd_version_satisfies?('>= 10')
18
- return @app.call(env)
19
- end
20
-
21
16
  @env = env
22
17
 
23
18
  # Get the ports we're forwarding
@@ -17,12 +17,9 @@ module VagrantPlugins
17
17
  options = {}
18
18
 
19
19
  # Disable requiring password for register and clone actions [GH-67].
20
- # It is available only since PD 10.
21
- if env[:machine].provider.pd_version_satisfies?('>= 10')
22
- acts = ['clone-vm']
23
- @logger.info("Disabling password restrictions: #{acts.join(', ')}")
24
- env[:machine].provider.driver.disable_password_restrictions(acts)
25
- end
20
+ acts = ['clone-vm']
21
+ @logger.info("Disabling password restrictions: #{acts.join(', ')}")
22
+ env[:machine].provider.driver.disable_password_restrictions(acts)
26
23
 
27
24
  if env[:machine].provider_config.regen_src_uuid \
28
25
  && env[:machine].provider.pd_version_satisfies?('>= 10.1.2')
@@ -1,8 +1,7 @@
1
+ require 'ipaddr'
1
2
  require 'set'
2
-
3
3
  require 'log4r'
4
4
 
5
- require 'vagrant/util/network_ip'
6
5
  require 'vagrant/util/scoped_hash_override'
7
6
 
8
7
  module VagrantPlugins
@@ -14,7 +13,6 @@ module VagrantPlugins
14
13
  #
15
14
  # This handles all the `config.vm.network` configurations.
16
15
  class Network
17
- include Vagrant::Util::NetworkIP
18
16
  include Vagrant::Util::ScopedHashOverride
19
17
  @@lock = Mutex.new
20
18
 
@@ -253,7 +251,6 @@ module VagrantPlugins
253
251
  mac: nil,
254
252
  name: nil,
255
253
  nic_type: nil,
256
- netmask: '255.255.255.0',
257
254
  type: :static
258
255
  }.merge(options)
259
256
 
@@ -263,47 +260,57 @@ module VagrantPlugins
263
260
  # Default IP is in the 20-bit private network block for DHCP based networks
264
261
  options[:ip] = '10.37.129.1' if options[:type] == :dhcp && !options[:ip]
265
262
 
266
- # Calculate our network address for the given IP/netmask
267
- netaddr = network_address(options[:ip], options[:netmask])
268
-
269
- # Verify that a host-only network subnet would not collide
270
- # with a bridged networking interface.
271
- #
272
- # If the subnets overlap in any way then the host only network
273
- # will not work because the routing tables will force the
274
- # traffic onto the real interface rather than the virtual
275
- # network interface.
276
- @env[:machine].provider.driver.read_bridged_interfaces.each do |interface|
277
- that_netaddr = network_address(interface[:ip], interface[:netmask])
278
- raise Vagrant::Errors::NetworkCollision if \
279
- netaddr == that_netaddr && interface[:status] != 'Down'
263
+ begin
264
+ ip = IPAddr.new(options[:ip])
265
+ if ip.ipv4?
266
+ options[:netmask] ||= '255.255.255.0'
267
+ elsif ip.ipv6?
268
+ options[:netmask] ||= 64
269
+
270
+ # Append a 6 to the end of the type
271
+ options[:type] = "#{options[:type]}6".to_sym
272
+ else
273
+ raise IPAddr::AddressFamilyError, 'unknown address family'
274
+ end
275
+
276
+ # Calculate our network address for the given IP/netmask
277
+ netaddr = IPAddr.new("#{options[:ip]}/#{options[:netmask]}")
278
+ rescue IPAddr::Error => e
279
+ raise VagrantPlugins::Parallels::Errors::NetworkInvalidAddress,
280
+ options: options, error: e.message
280
281
  end
281
282
 
282
- # Split the IP address into its components
283
- ip_parts = netaddr.split('.').map { |i| i.to_i }
283
+ if ip.ipv4?
284
+ # Verify that a host-only network subnet would not collide
285
+ # with a bridged networking interface.
286
+ #
287
+ # If the subnets overlap in any way then the host only network
288
+ # will not work because the routing tables will force the
289
+ # traffic onto the real interface rather than the virtual
290
+ # network interface.
291
+ @env[:machine].provider.driver.read_bridged_interfaces.each do |interface|
292
+ next if interface[:status] == 'Down'
293
+ that_netaddr = IPAddr.new("#{interface[:ip]}/#{interface[:netmask]}")
294
+ raise Vagrant::Errors::NetworkCollision if netaddr.include? that_netaddr
295
+ end
296
+ end
284
297
 
285
- # Calculate the adapter IP, which we assume is the IP ".1" at
286
- # the end usually.
287
- adapter_ip = ip_parts.dup
288
- adapter_ip[3] += 1
289
- options[:adapter_ip] ||= adapter_ip.join('.')
298
+ # Calculate the adapter IP which is the network address with the final
299
+ # bit group appended by 1. Usually it is "x.x.x.1" for IPv4 and
300
+ # "<prefix>::1" for IPv6
301
+ options[:adapter_ip] ||= (netaddr | 1).to_s
290
302
 
291
303
  dhcp_options = {}
292
304
  if options[:type] == :dhcp
293
- # Calculate the DHCP server IP, which is the network address
294
- # with the final octet + 1. So "172.28.0.0" turns into "172.28.0.1"
295
- dhcp_ip = ip_parts.dup
296
- dhcp_ip[3] += 1
297
- dhcp_options[:dhcp_ip] = options[:dhcp_ip] || dhcp_ip.join('.')
298
-
299
- # Calculate the lower and upper bound for the DHCP server
300
- dhcp_lower = ip_parts.dup
301
- dhcp_lower[3] += 2
302
- dhcp_options[:dhcp_lower] = options[:dhcp_lower] || dhcp_lower.join('.')
303
-
304
- dhcp_upper = ip_parts.dup
305
- dhcp_upper[3] = 254
306
- dhcp_options[:dhcp_upper] = options[:dhcp_upper] || dhcp_upper.join('.')
305
+ # Calculate the IP and lower & upper bound for the DHCP server
306
+ # Example: for "192.168.22.64/26" network range it wil be:
307
+ # dhcp_ip: "192.168.22.65",
308
+ # dhcp_lower: "192.168.22.66"
309
+ # dhcp_upper: "192.168.22.126"
310
+ ip_range = netaddr.to_range
311
+ dhcp_options[:dhcp_ip] = options[:dhcp_ip] || (ip_range.first | 1).to_s
312
+ dhcp_options[:dhcp_lower] = options[:dhcp_lower] || (ip_range.first | 2).to_s
313
+ dhcp_options[:dhcp_upper] = options[:dhcp_upper] || (ip_range.last(2).first).to_s
307
314
  end
308
315
 
309
316
  {
@@ -444,14 +451,19 @@ module VagrantPlugins
444
451
 
445
452
  # This finds a matching host only network for the given configuration.
446
453
  def hostonly_find_matching_network(config)
447
- this_netaddr = network_address(config[:ip], config[:netmask])
454
+ this_netaddr = IPAddr.new("#{config[:ip]}/#{config[:netmask]}")
448
455
 
449
456
  @env[:machine].provider.driver.read_host_only_interfaces.each do |interface|
450
457
  return interface if config[:name] && config[:name] == interface[:name]
451
458
 
452
- if interface[:ip]
453
- return interface if this_netaddr == \
454
- network_address(interface[:ip], interface[:netmask])
459
+ if interface[:ip] && this_netaddr.ipv4?
460
+ netaddr = IPAddr.new("#{interface[:ip]}/#{interface[:netmask]}")
461
+ return interface if netaddr.include? this_netaddr
462
+ end
463
+
464
+ if interface[:ipv6] && this_netaddr.ipv6?
465
+ netaddr = IPAddr.new("#{interface[:ipv6]}/#{interface[:ipv6_prefix]}")
466
+ return interface if netaddr.include? this_netaddr
455
467
  end
456
468
  end
457
469
 
@@ -7,11 +7,6 @@ module VagrantPlugins
7
7
  end
8
8
 
9
9
  def call(env)
10
- # Port Forwarding feature is available only with PD >= 10
11
- if !env[:machine].provider.pd_version_satisfies?('>= 10')
12
- return @app.call(env)
13
- end
14
-
15
10
  # Get the forwarded ports used by other virtual machines and
16
11
  # consider those in use as well.
17
12
  env[:port_collision_extra_in_use] =
@@ -30,22 +30,14 @@ module VagrantPlugins
30
30
  private
31
31
 
32
32
  def default_settings
33
- settings = {}
34
-
35
- return settings if @env[:machine].provider.pd_version_satisfies?('< 9')
36
- settings.merge!(
33
+ settings = {
37
34
  startup_view: 'same',
38
35
  on_shutdown: 'close',
39
36
  on_window_close: 'keep-running',
40
37
  auto_share_camera: 'off',
41
38
  smart_guard: 'off',
42
39
  longer_battery_life: 'on'
43
- )
44
-
45
- # Check the legacy option
46
- if !@env[:machine].provider_config.optimize_power_consumption
47
- settings[:longer_battery_life] = 'off'
48
- end
40
+ }
49
41
 
50
42
  return settings if @env[:machine].provider.pd_version_satisfies?('< 10.1.2')
51
43
  settings.merge!(
@@ -394,7 +394,6 @@ module VagrantPlugins
394
394
  autoload :BoxRegister, File.expand_path('../action/box_register', __FILE__)
395
395
  autoload :BoxUnregister, File.expand_path('../action/box_unregister', __FILE__)
396
396
  autoload :HandleGuestTools, File.expand_path('../action/handle_guest_tools', __FILE__)
397
- autoload :HandleForwardedPortCollisions, File.expand_path('../action/handle_forwarded_port_collisions.rb', __FILE__)
398
397
  autoload :CheckSharedInterface, File.expand_path('../action/check_shared_interface', __FILE__)
399
398
  autoload :ClearNetworkInterfaces, File.expand_path('../action/clear_network_interfaces', __FILE__)
400
399
  autoload :ClearForwardedPorts, File.expand_path('../action/clear_forwarded_ports', __FILE__)
@@ -13,10 +13,6 @@ module VagrantPlugins
13
13
  attr_accessor :regen_src_uuid
14
14
  attr_accessor :update_guest_tools
15
15
 
16
- # Deprecated options
17
- attr_accessor :regen_box_uuid
18
- attr_accessor :use_linked_clone
19
-
20
16
  # Compatibility with virtualbox provider's syntax
21
17
  alias :check_guest_additions= :check_guest_tools=
22
18
 
@@ -29,15 +25,10 @@ module VagrantPlugins
29
25
  @linked_clone_snapshot = UNSET_VALUE
30
26
  @network_adapters = {}
31
27
  @name = UNSET_VALUE
32
- @optimize_power_consumption = UNSET_VALUE
33
28
  @regen_src_uuid = UNSET_VALUE
34
29
  @update_guest_tools = UNSET_VALUE
35
30
 
36
31
  network_adapter(0, :shared)
37
-
38
- # Deprecated options
39
- @regen_box_uuid = UNSET_VALUE
40
- @use_linked_clone = UNSET_VALUE
41
32
  end
42
33
 
43
34
  def customize(*command)
@@ -68,16 +59,6 @@ module VagrantPlugins
68
59
  end
69
60
 
70
61
  def finalize!
71
- if @regen_box_uuid != UNSET_VALUE
72
- puts "Parallels provider: Vagrantfile option 'regen_box_uuid' is deprecated and will be removed. Please, use 'regen_src_uuid' instead"
73
- @regen_src_uuid = @regen_box_uuid if @regen_src_uuid == UNSET_VALUE
74
- end
75
-
76
- if @use_linked_clone != UNSET_VALUE
77
- puts "Parallels provider: Vagrantfile option 'use_linked_clone' is deprecated and will be removed. Please, use 'linked_clone' instead"
78
- @linked_clone = @use_linked_clone if @linked_clone == UNSET_VALUE
79
- end
80
-
81
62
  if @check_guest_tools == UNSET_VALUE
82
63
  @check_guest_tools = true
83
64
  end
@@ -118,10 +99,6 @@ module VagrantPlugins
118
99
  end
119
100
  end
120
101
 
121
- if @optimize_power_consumption != UNSET_VALUE
122
- machine.env.ui.warn I18n.t('vagrant_parallels.config.deprecate_power_consumption')
123
- end
124
-
125
102
  { 'Parallels Provider' => errors }
126
103
  end
127
104
  end
@@ -54,7 +54,14 @@ module VagrantPlugins
54
54
  # }
55
55
  #
56
56
  def clear_forwarded_ports(ports)
57
- raise NotImplementedError
57
+ args = []
58
+ ports.each do |r|
59
+ args.concat(["--nat-#{r[:protocol]}-del", r[:name]])
60
+ end
61
+
62
+ if !args.empty?
63
+ execute_prlsrvctl('net', 'set', read_shared_network_id, *args)
64
+ end
58
65
  end
59
66
 
60
67
  # Clears the shared folders that have been set on the virtual machine.
@@ -187,7 +194,25 @@ module VagrantPlugins
187
194
 
188
195
  # Deletes any host only networks that aren't being used for anything.
189
196
  def delete_unused_host_only_networks
190
- raise NotImplementedError
197
+ networks = read_virtual_networks
198
+ # 'Shared'(vnic0) and 'Host-Only'(vnic1) are default in Parallels Desktop
199
+ # They should not be deleted anyway.
200
+ networks.keep_if do |net|
201
+ net['Type'] == 'host-only' && net['Bound To'] &&
202
+ net['Bound To'].match(/^(?>vnic|Parallels Host-Only #)(\d+)$/)[1].to_i >= 2
203
+ end
204
+
205
+ read_vms_info.each do |vm|
206
+ used_nets = vm.fetch('Hardware', {}).select { |name, _| name.start_with? 'net' }
207
+ used_nets.each_value do |net_params|
208
+ networks.delete_if { |net| net['Network ID'] == net_params.fetch('iface', nil) }
209
+ end
210
+ end
211
+
212
+ networks.each do |net|
213
+ # Delete the actual host only network interface.
214
+ execute_prlsrvctl('net', 'del', net['Network ID'])
215
+ end
191
216
  end
192
217
 
193
218
  # Disables requiring password on such operations as creating, adding,
@@ -196,7 +221,10 @@ module VagrantPlugins
196
221
  # @param [Array<String>] acts List of actions. Available values:
197
222
  # ['create-vm', 'add-vm', 'remove-vm', 'clone-vm']
198
223
  def disable_password_restrictions(acts)
199
- raise NotImplementedError
224
+ server_info = json { execute_prlsrvctl('info', '--json') }
225
+ server_info.fetch('Require password to',[]).each do |act|
226
+ execute_prlsrvctl('set', '--require-pwd', "#{act}:off") if acts.include? act
227
+ end
200
228
  end
201
229
 
202
230
  # Enables network adapters on the VM.
@@ -215,7 +243,45 @@ module VagrantPlugins
215
243
  # @param [Array<Symbol => Symbol, String>] adapters
216
244
  # Array of adapters to be enabled.
217
245
  def enable_adapters(adapters)
218
- raise NotImplementedError
246
+ # Get adapters which have already configured for this VM
247
+ # Such adapters will be just overridden
248
+ existing_adapters = read_settings.fetch('Hardware', {}).keys.select do |name|
249
+ name.start_with? 'net'
250
+ end
251
+
252
+ # Disable all previously existing adapters (except shared 'vnet0')
253
+ existing_adapters.each do |adapter|
254
+ if adapter != 'vnet0'
255
+ execute_prlctl('set', @uuid, '--device-set', adapter, '--disable')
256
+ end
257
+ end
258
+
259
+ adapters.each do |adapter|
260
+ args = []
261
+ if existing_adapters.include? "net#{adapter[:adapter]}"
262
+ args.concat(['--device-set',"net#{adapter[:adapter]}", '--enable'])
263
+ else
264
+ args.concat(['--device-add', 'net'])
265
+ end
266
+
267
+ if adapter[:type] == :hostonly
268
+ args.concat(['--type', 'host', '--iface', adapter[:hostonly]])
269
+ elsif adapter[:type] == :bridged
270
+ args.concat(['--type', 'bridged', '--iface', adapter[:bridge]])
271
+ elsif adapter[:type] == :shared
272
+ args.concat(['--type', 'shared'])
273
+ end
274
+
275
+ if adapter[:mac_address]
276
+ args.concat(['--mac', adapter[:mac_address]])
277
+ end
278
+
279
+ if adapter[:nic_type]
280
+ args.concat(['--adapter-type', adapter[:nic_type].to_s])
281
+ end
282
+
283
+ execute_prlctl('set', @uuid, *args)
284
+ end
219
285
  end
220
286
 
221
287
  # Create a set of port forwarding rules for a virtual machine.
@@ -237,7 +303,20 @@ module VagrantPlugins
237
303
  # @param [Array<Hash>] ports An array of ports to set. See documentation
238
304
  # for more information on the format.
239
305
  def forward_ports(ports)
240
- raise NotImplementedError
306
+ args = []
307
+ ports.each do |options|
308
+ protocol = options[:protocol] || 'tcp'
309
+ pf_builder = [
310
+ options[:name],
311
+ options[:hostport],
312
+ @uuid,
313
+ options[:guestport]
314
+ ]
315
+
316
+ args.concat(["--nat-#{protocol}-add", pf_builder.join(',')])
317
+ end
318
+
319
+ execute_prlsrvctl('net', 'set', read_shared_network_id, *args)
241
320
  end
242
321
 
243
322
  # Lists all snapshots for the specified VM. Returns an empty hash if
@@ -328,7 +407,13 @@ module VagrantPlugins
328
407
  # Otherwise only rules related to the context VM will be returned.
329
408
  # @return [Array<Symbol => String>]
330
409
  def read_forwarded_ports(global=false)
331
- raise NotImplementedError
410
+ all_rules = read_shared_interface[:nat]
411
+
412
+ if global
413
+ all_rules
414
+ else
415
+ all_rules.select { |r| r[:guest].include?(@uuid) }
416
+ end
332
417
  end
333
418
 
334
419
  # Returns an IP of the virtual machine. It requires that Shared network
@@ -418,7 +503,37 @@ module VagrantPlugins
418
503
  #
419
504
  # @return [Array<Symbol => String>]
420
505
  def read_host_only_interfaces
421
- raise NotImplementedError
506
+ net_list = read_virtual_networks
507
+ net_list.keep_if { |net| net['Type'] == 'host-only' }
508
+
509
+ hostonly_ifaces = []
510
+ net_list.each do |iface|
511
+ net_info = json do
512
+ execute_prlsrvctl('net', 'info', iface['Network ID'], '--json')
513
+ end
514
+
515
+ iface = {
516
+ name: net_info['Network ID'],
517
+ status: 'Down'
518
+ }
519
+
520
+ adapter = net_info['Parallels adapter']
521
+ if adapter && net_info['Bound To']
522
+ # In PD >= 10.1.2 there are new field names for an IP/Subnet
523
+ iface[:ip] = adapter['IP address'] || adapter['IPv4 address']
524
+ iface[:netmask] = adapter['Subnet mask'] || adapter['IPv4 subnet mask']
525
+ iface[:bound_to] = net_info['Bound To']
526
+ iface[:status] = 'Up'
527
+
528
+ if adapter['IPv6 address'] && adapter['IPv6 subnet mask']
529
+ iface[:ipv6] = adapter['IPv6 address']
530
+ iface[:ipv6_prefix] = adapter['IPv6 subnet mask']
531
+ end
532
+ end
533
+
534
+ hostonly_ifaces << iface
535
+ end
536
+ hostonly_ifaces
422
537
  end
423
538
 
424
539
  # Returns the MAC address of the first Shared network interface.
@@ -448,7 +563,27 @@ module VagrantPlugins
448
563
  #
449
564
  # @return [<Integer => Hash>]
450
565
  def read_network_interfaces
451
- raise NotImplementedError
566
+ nics = {}
567
+
568
+ # Get enabled VM's network interfaces
569
+ ifaces = read_settings.fetch('Hardware', {}).keep_if do |dev, params|
570
+ dev.start_with?('net') and params.fetch('enabled', true)
571
+ end
572
+ ifaces.each do |name, params|
573
+ adapter = name.match(/^net(\d+)$/)[1].to_i
574
+ nics[adapter] ||= {}
575
+
576
+ if params['type'] == 'shared'
577
+ nics[adapter][:type] = :shared
578
+ elsif params['type'] == 'host'
579
+ nics[adapter][:type] = :hostonly
580
+ nics[adapter][:hostonly] = params.fetch('iface','')
581
+ elsif params['type'] == 'bridged'
582
+ nics[adapter][:type] = :bridged
583
+ nics[adapter][:bridge] = params.fetch('iface','')
584
+ end
585
+ end
586
+ nics
452
587
  end
453
588
 
454
589
  # Returns virtual machine settings
@@ -472,7 +607,45 @@ module VagrantPlugins
472
607
  #
473
608
  # @return [<Symbol => String, Hash>]
474
609
  def read_shared_interface
475
- raise NotImplementedError
610
+ net_info = json do
611
+ execute_prlsrvctl('net', 'info', read_shared_network_id, '--json')
612
+ end
613
+
614
+ iface = {
615
+ nat: [],
616
+ status: 'Down'
617
+ }
618
+ adapter = net_info['Parallels adapter']
619
+
620
+ if adapter && net_info['Bound To']
621
+ # In PD >= 10.1.2 there are new field names for an IP/Subnet
622
+ iface[:ip] = adapter['IP address'] || adapter['IPv4 address']
623
+ iface[:netmask] = adapter['Subnet mask'] || adapter['IPv4 subnet mask']
624
+ iface[:bound_to] = net_info['Bound To']
625
+ iface[:status] = 'Up'
626
+ end
627
+
628
+ if net_info.key?('DHCPv4 server')
629
+ iface[:dhcp] = {
630
+ ip: net_info['DHCPv4 server']['Server address'],
631
+ lower: net_info['DHCPv4 server']['IP scope start address'],
632
+ upper: net_info['DHCPv4 server']['IP scope end address']
633
+ }
634
+ end
635
+
636
+ net_info['NAT server'].each do |group, rules|
637
+ rules.each do |name, params|
638
+ iface[:nat] << {
639
+ name: name,
640
+ protocol: group == 'TCP rules' ? 'tcp' : 'udp',
641
+ guest: params['destination IP/VM id'],
642
+ hostport: params['source port'],
643
+ guestport: params['destination port']
644
+ }
645
+ end
646
+ end
647
+
648
+ iface
476
649
  end
477
650
 
478
651
  # Returns a list of shared folders in format:
@@ -501,6 +674,8 @@ module VagrantPlugins
501
674
  #
502
675
  # @return [Array]
503
676
  def read_used_ports
677
+ # Ignore our own used ports
678
+ read_forwarded_ports(true).reject { |r| r[:guest].include?(@uuid) }
504
679
  end
505
680
 
506
681
  # Returns the configuration of all virtual networks in Parallels Desktop.
@@ -603,7 +778,8 @@ module VagrantPlugins
603
778
  # @param [Boolean] optimized Use "Longer Battery Life"
604
779
  # instead "Better Performance"
605
780
  def set_power_consumption_mode(optimized)
606
- raise NotImplementedError
781
+ state = optimized ? 'on' : 'off'
782
+ execute_prlctl('set', @uuid, '--longer-battery-life', state)
607
783
  end
608
784
 
609
785
  # Share a set of folders on this VM.
@@ -44,11 +44,10 @@ module VagrantPlugins
44
44
  major_ver = @@version.split('.').first.to_i
45
45
  driver_klass =
46
46
  case major_ver
47
- when 1..7 then raise Errors::ParallelsUnsupportedVersion
48
- when 8 then PD_8
49
- when 9 then PD_9
47
+ when 1..9 then raise Errors::ParallelsUnsupportedVersion
50
48
  when 10 then PD_10
51
- else PD_11
49
+ when 11 then PD_11
50
+ else PD_12
52
51
  end
53
52
 
54
53
  # Starting since PD 11 only Pro and Business editions have CLI
@@ -2,228 +2,18 @@ require 'log4r'
2
2
 
3
3
  require 'vagrant/util/platform'
4
4
 
5
- require_relative 'pd_9'
5
+ require_relative 'base'
6
6
 
7
7
  module VagrantPlugins
8
8
  module Parallels
9
9
  module Driver
10
10
  # Driver for Parallels Desktop 10.
11
- class PD_10 < PD_9
11
+ class PD_10 < Base
12
12
  def initialize(uuid)
13
13
  super(uuid)
14
14
 
15
15
  @logger = Log4r::Logger.new('vagrant_parallels::driver::pd_10')
16
16
  end
17
-
18
- def clear_forwarded_ports(ports)
19
- args = []
20
- ports.each do |r|
21
- args.concat(["--nat-#{r[:protocol]}-del", r[:name]])
22
- end
23
-
24
- if !args.empty?
25
- execute_prlsrvctl('net', 'set', read_shared_network_id, *args)
26
- end
27
- end
28
-
29
-
30
- def delete_unused_host_only_networks
31
- networks = read_virtual_networks
32
- # 'Shared'(vnic0) and 'Host-Only'(vnic1) are default in Parallels Desktop
33
- # They should not be deleted anyway.
34
- networks.keep_if do |net|
35
- net['Type'] == 'host-only' && net['Bound To'] &&
36
- net['Bound To'].match(/^(?>vnic|Parallels Host-Only #)(\d+)$/)[1].to_i >= 2
37
- end
38
-
39
- read_vms_info.each do |vm|
40
- used_nets = vm.fetch('Hardware', {}).select { |name, _| name.start_with? 'net' }
41
- used_nets.each_value do |net_params|
42
- networks.delete_if { |net| net['Network ID'] == net_params.fetch('iface', nil) }
43
- end
44
- end
45
-
46
- networks.each do |net|
47
- # Delete the actual host only network interface.
48
- execute_prlsrvctl('net', 'del', net['Network ID'])
49
- end
50
- end
51
-
52
- def disable_password_restrictions(acts)
53
- server_info = json { execute_prlsrvctl('info', '--json') }
54
- server_info.fetch('Require password to',[]).each do |act|
55
- execute_prlsrvctl('set', '--require-pwd', "#{act}:off") if acts.include? act
56
- end
57
- end
58
-
59
- def enable_adapters(adapters)
60
- # Get adapters which have already configured for this VM
61
- # Such adapters will be just overridden
62
- existing_adapters = read_settings.fetch('Hardware', {}).keys.select do |name|
63
- name.start_with? 'net'
64
- end
65
-
66
- # Disable all previously existing adapters (except shared 'vnet0')
67
- existing_adapters.each do |adapter|
68
- if adapter != 'vnet0'
69
- execute_prlctl('set', @uuid, '--device-set', adapter, '--disable')
70
- end
71
- end
72
-
73
- adapters.each do |adapter|
74
- args = []
75
- if existing_adapters.include? "net#{adapter[:adapter]}"
76
- args.concat(['--device-set',"net#{adapter[:adapter]}", '--enable'])
77
- else
78
- args.concat(['--device-add', 'net'])
79
- end
80
-
81
- if adapter[:type] == :hostonly
82
- args.concat(['--type', 'host', '--iface', adapter[:hostonly]])
83
- elsif adapter[:type] == :bridged
84
- args.concat(['--type', 'bridged', '--iface', adapter[:bridge]])
85
- elsif adapter[:type] == :shared
86
- args.concat(['--type', 'shared'])
87
- end
88
-
89
- if adapter[:mac_address]
90
- args.concat(['--mac', adapter[:mac_address]])
91
- end
92
-
93
- if adapter[:nic_type]
94
- args.concat(['--adapter-type', adapter[:nic_type].to_s])
95
- end
96
-
97
- execute_prlctl('set', @uuid, *args)
98
- end
99
- end
100
-
101
- def forward_ports(ports)
102
- args = []
103
- ports.each do |options|
104
- protocol = options[:protocol] || 'tcp'
105
- pf_builder = [
106
- options[:name],
107
- options[:hostport],
108
- @uuid,
109
- options[:guestport]
110
- ]
111
-
112
- args.concat(["--nat-#{protocol}-add", pf_builder.join(',')])
113
- end
114
-
115
- execute_prlsrvctl('net', 'set', read_shared_network_id, *args)
116
- end
117
-
118
- def read_forwarded_ports(global=false)
119
- all_rules = read_shared_interface[:nat]
120
-
121
- if global
122
- all_rules
123
- else
124
- all_rules.select { |r| r[:guest].include?(@uuid) }
125
- end
126
- end
127
-
128
- def read_host_only_interfaces
129
- net_list = read_virtual_networks
130
- net_list.keep_if { |net| net['Type'] == 'host-only' }
131
-
132
- hostonly_ifaces = []
133
- net_list.each do |iface|
134
- net_info = json do
135
- execute_prlsrvctl('net', 'info', iface['Network ID'], '--json')
136
- end
137
-
138
- iface = {
139
- name: net_info['Network ID'],
140
- status: 'Down'
141
- }
142
-
143
- adapter = net_info['Parallels adapter']
144
- if adapter && net_info['Bound To']
145
- # In PD >= 10.1.2 there are new field names for an IP/Subnet
146
- iface[:ip] = adapter['IP address'] || adapter['IPv4 address']
147
- iface[:netmask] = adapter['Subnet mask'] || adapter['IPv4 subnet mask']
148
- iface[:bound_to] = net_info['Bound To']
149
- iface[:status] = 'Up'
150
- end
151
-
152
- hostonly_ifaces << iface
153
- end
154
- hostonly_ifaces
155
- end
156
-
157
- def read_network_interfaces
158
- nics = {}
159
-
160
- # Get enabled VM's network interfaces
161
- ifaces = read_settings.fetch('Hardware', {}).keep_if do |dev, params|
162
- dev.start_with?('net') and params.fetch('enabled', true)
163
- end
164
- ifaces.each do |name, params|
165
- adapter = name.match(/^net(\d+)$/)[1].to_i
166
- nics[adapter] ||= {}
167
-
168
- if params['type'] == 'shared'
169
- nics[adapter][:type] = :shared
170
- elsif params['type'] == 'host'
171
- nics[adapter][:type] = :hostonly
172
- nics[adapter][:hostonly] = params.fetch('iface','')
173
- elsif params['type'] == 'bridged'
174
- nics[adapter][:type] = :bridged
175
- nics[adapter][:bridge] = params.fetch('iface','')
176
- end
177
- end
178
- nics
179
- end
180
-
181
- def read_shared_interface
182
- net_info = json do
183
- execute_prlsrvctl('net', 'info', read_shared_network_id, '--json')
184
- end
185
-
186
- iface = {
187
- nat: [],
188
- status: 'Down'
189
- }
190
- adapter = net_info['Parallels adapter']
191
-
192
- if adapter && net_info['Bound To']
193
- # In PD >= 10.1.2 there are new field names for an IP/Subnet
194
- iface[:ip] = adapter['IP address'] || adapter['IPv4 address']
195
- iface[:netmask] = adapter['Subnet mask'] || adapter['IPv4 subnet mask']
196
- iface[:bound_to] = net_info['Bound To']
197
- iface[:status] = 'Up'
198
- end
199
-
200
- if net_info.key?('DHCPv4 server')
201
- iface[:dhcp] = {
202
- ip: net_info['DHCPv4 server']['Server address'],
203
- lower: net_info['DHCPv4 server']['IP scope start address'],
204
- upper: net_info['DHCPv4 server']['IP scope end address']
205
- }
206
- end
207
-
208
- net_info['NAT server'].each do |group, rules|
209
- rules.each do |name, params|
210
- iface[:nat] << {
211
- name: name,
212
- protocol: group == 'TCP rules' ? 'tcp' : 'udp',
213
- guest: params['destination IP/VM id'],
214
- hostport: params['source port'],
215
- guestport: params['destination port']
216
- }
217
- end
218
- end
219
-
220
- iface
221
- end
222
-
223
- def read_used_ports
224
- # Ignore our own used ports
225
- read_forwarded_ports(true).reject { |r| r[:guest].include?(@uuid) }
226
- end
227
17
  end
228
18
  end
229
19
  end
@@ -0,0 +1,56 @@
1
+ require 'log4r'
2
+
3
+ require 'vagrant/util/platform'
4
+
5
+ require_relative 'pd_11'
6
+
7
+ module VagrantPlugins
8
+ module Parallels
9
+ module Driver
10
+ # Driver for Parallels Desktop 12.
11
+ class PD_12 < PD_11
12
+ def initialize(uuid)
13
+ super(uuid)
14
+
15
+ @logger = Log4r::Logger.new('vagrant_parallels::driver::pd_12')
16
+ end
17
+
18
+ def create_host_only_network(options)
19
+ # Create the interface
20
+ execute_prlsrvctl('net', 'add', options[:network_id], '--type', 'host-only')
21
+
22
+ # Get the IP so we can determine v4 vs v6
23
+ ip = IPAddr.new(options[:adapter_ip])
24
+ if ip.ipv4?
25
+ args = ['--ip', "#{options[:adapter_ip]}/#{options[:netmask]}"]
26
+ if options[:dhcp]
27
+ args.concat(['--dhcp-ip', options[:dhcp][:ip],
28
+ '--ip-scope-start', options[:dhcp][:lower],
29
+ '--ip-scope-end', options[:dhcp][:upper]])
30
+ end
31
+ elsif ip.ipv6?
32
+ # Convert prefix length to netmask ("32" -> "ffff:ffff::")
33
+ options[:netmask] = IPAddr.new(IPAddr::IN6MASK, Socket::AF_INET6)
34
+ .mask(options[:netmask]).to_s
35
+
36
+ args = ['--host-assign-ip6', 'on',
37
+ '--ip6', "#{options[:adapter_ip]}/#{options[:netmask]}"]
38
+ # DHCPv6 setting is not supported by Vagrant yet.
39
+ else
40
+ raise IPAddr::AddressFamilyError, 'BUG: unknown address family'
41
+ end
42
+
43
+ execute_prlsrvctl('net', 'set', options[:network_id], *args)
44
+
45
+ # Return the details
46
+ {
47
+ name: options[:network_id],
48
+ ip: options[:adapter_ip],
49
+ netmask: options[:netmask],
50
+ dhcp: options[:dhcp]
51
+ }
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -39,6 +39,10 @@ module VagrantPlugins
39
39
  error_key(:mac_os_x_required)
40
40
  end
41
41
 
42
+ class NetworkInvalidAddress < VagrantParallelsError
43
+ error_key(:network_invalid_address)
44
+ end
45
+
42
46
  class ExecutionError < VagrantParallelsError
43
47
  error_key(:execution_error)
44
48
  end
@@ -138,10 +138,9 @@ module VagrantPlugins
138
138
  # our drivers only when they are needed.
139
139
  module Driver
140
140
  autoload :Meta, File.expand_path('../driver/meta', __FILE__)
141
- autoload :PD_8, File.expand_path('../driver/pd_8', __FILE__)
142
- autoload :PD_9, File.expand_path('../driver/pd_9', __FILE__)
143
141
  autoload :PD_10, File.expand_path('../driver/pd_10', __FILE__)
144
142
  autoload :PD_11, File.expand_path('../driver/pd_11', __FILE__)
143
+ autoload :PD_12, File.expand_path('../driver/pd_12', __FILE__)
145
144
  end
146
145
 
147
146
  module Model
@@ -1,5 +1,5 @@
1
1
  module VagrantPlugins
2
2
  module Parallels
3
- VERSION = '1.6.3'
3
+ VERSION = '1.7.0'
4
4
  end
5
5
  end
data/locales/en.yml CHANGED
@@ -58,6 +58,11 @@ en:
58
58
  which are not supported by "prl_fs" file system.
59
59
 
60
60
  Invalid mount options: %{options}
61
+ network_invalid_address: |-
62
+ Network settings specified in your Vagrantfile are invalid:
63
+
64
+ Network settings: %{options}
65
+ Error: %{error}
61
66
  mac_os_x_required: |-
62
67
  Parallels provider works only on OS X (Mac OS X) systems.
63
68
  parallels_install_incomplete: |-
@@ -100,7 +105,7 @@ en:
100
105
  parallels_unsupported_version: |-
101
106
  Vagrant has detected that you have a version of Parallels Desktop for Mac
102
107
  installed that is not supported. Vagrant Parallels provider is compatible
103
- only with Parallels Desktop 8 or later.
108
+ only with Parallels Desktop 10 or later.
104
109
  Please upgrade your installation: http://parallels.com/desktop
105
110
 
106
111
  Note: Starting since Parallels Desktop 11 for Mac, Vagrant Parallels
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vagrant-parallels
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.3
4
+ version: 1.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mikhail Zholobov
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-07-11 00:00:00.000000000 Z
12
+ date: 2016-11-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -93,7 +93,6 @@ files:
93
93
  - lib/vagrant-parallels/action/export.rb
94
94
  - lib/vagrant-parallels/action/forced_halt.rb
95
95
  - lib/vagrant-parallels/action/forward_ports.rb
96
- - lib/vagrant-parallels/action/handle_forwarded_port_collisions.rb
97
96
  - lib/vagrant-parallels/action/handle_guest_tools.rb
98
97
  - lib/vagrant-parallels/action/import.rb
99
98
  - lib/vagrant-parallels/action/network.rb
@@ -117,8 +116,7 @@ files:
117
116
  - lib/vagrant-parallels/driver/meta.rb
118
117
  - lib/vagrant-parallels/driver/pd_10.rb
119
118
  - lib/vagrant-parallels/driver/pd_11.rb
120
- - lib/vagrant-parallels/driver/pd_8.rb
121
- - lib/vagrant-parallels/driver/pd_9.rb
119
+ - lib/vagrant-parallels/driver/pd_12.rb
122
120
  - lib/vagrant-parallels/errors.rb
123
121
  - lib/vagrant-parallels/guest_cap/darwin/install_parallels_tools.rb
124
122
  - lib/vagrant-parallels/guest_cap/darwin/mount_parallels_shared_folder.rb
@@ -1,30 +0,0 @@
1
- module VagrantPlugins
2
- module Parallels
3
- module Action
4
- class HandleForwardedPortCollisions < Vagrant::Action::Builtin::HandleForwardedPortCollisions
5
- def initialize(app, env)
6
- @app = app
7
- @logger = Log4r::Logger.new('vagrant_parallels::action::handle_port_collisions')
8
- end
9
-
10
- # This middleware just wraps the builtin action and allows to skip it if
11
- # port forwarding is not supported for current Parallels Desktop version.
12
- def call(env)
13
- if env[:machine].provider.pd_version_satisfies?('>= 10')
14
- super
15
- else
16
- # Just continue if port forwarding is not supported
17
- @app.call(env)
18
- end
19
- end
20
-
21
- def recover(env)
22
- if env[:machine].provider.pd_version_satisfies?('>= 10')
23
- super
24
- end
25
- # Do nothing if port forwarding is not supported
26
- end
27
- end
28
- end
29
- end
30
- end
@@ -1,183 +0,0 @@
1
- require 'log4r'
2
- require 'nokogiri'
3
- require 'securerandom'
4
-
5
- require 'vagrant/util/platform'
6
-
7
- require_relative 'base'
8
-
9
- module VagrantPlugins
10
- module Parallels
11
- module Driver
12
- # Driver for Parallels Desktop 8.
13
- class PD_8 < Base
14
- def initialize(uuid)
15
- super(uuid)
16
-
17
- @logger = Log4r::Logger.new('vagrant_parallels::driver::pd_8')
18
- end
19
-
20
- def delete_unused_host_only_networks
21
- networks = read_virtual_networks
22
-
23
- # 'Shared'(vnic0) and 'Host-Only'(vnic1) are default in Parallels Desktop
24
- # They should not be deleted anyway.
25
- networks.keep_if do |net|
26
- net['Type'] == 'host-only' &&
27
- net['Bound To'].match(/^(?>vnic|Parallels Host-Only #)(\d+)$/)[1].to_i >= 2
28
- end
29
-
30
- read_vms_info.each do |vm|
31
- used_nets = vm.fetch('Hardware', {}).select { |name, _| name.start_with? 'net' }
32
- used_nets.each_value do |net_params|
33
- networks.delete_if { |net| net['Bound To'] == net_params.fetch('iface', nil) }
34
- end
35
-
36
- end
37
-
38
- networks.each do |net|
39
- # Delete the actual host only network interface.
40
- execute_prlsrvctl('net', 'del', net['Network ID'])
41
- end
42
- end
43
-
44
- def enable_adapters(adapters)
45
- # Get adapters which have already configured for this VM
46
- # Such adapters will be just overridden
47
- existing_adapters = read_settings.fetch('Hardware', {}).keys.select do |name|
48
- name.start_with? 'net'
49
- end
50
-
51
- # Disable all previously existing adapters (except shared 'vnet0')
52
- existing_adapters.each do |adapter|
53
- if adapter != 'vnet0'
54
- execute_prlctl('set', @uuid, '--device-set', adapter, '--disable')
55
- end
56
- end
57
-
58
- adapters.each do |adapter|
59
- args = []
60
- if existing_adapters.include? "net#{adapter[:adapter]}"
61
- args.concat(['--device-set',"net#{adapter[:adapter]}", '--enable'])
62
- else
63
- args.concat(['--device-add', 'net'])
64
- end
65
-
66
- if adapter[:type] == :hostonly
67
- # Determine interface to which it has been bound
68
- net_info = json do
69
- execute_prlsrvctl('net', 'info', adapter[:hostonly], '--json')
70
- end
71
-
72
- # Oddly enough, but there is a 'bridge' type anyway.
73
- # The only difference is the destination interface:
74
- # - in host-only (private) network it will be bridged to the 'vnicX' device
75
- # - in real bridge (public) network it will be bridged to the assigned device
76
- args.concat(['--type', 'bridged', '--iface', net_info['Bound To']])
77
- elsif adapter[:type] == :bridged
78
- args.concat(['--type', 'bridged', '--iface', adapter[:bridge]])
79
- elsif adapter[:type] == :shared
80
- args.concat(['--type', 'shared'])
81
- end
82
-
83
- if adapter[:mac_address]
84
- args.concat(['--mac', adapter[:mac_address]])
85
- end
86
-
87
- if adapter[:nic_type]
88
- args.concat(['--adapter-type', adapter[:nic_type].to_s])
89
- end
90
-
91
- execute_prlctl('set', @uuid, *args)
92
- end
93
- end
94
-
95
- def read_host_only_interfaces
96
- net_list = read_virtual_networks
97
- net_list.keep_if { |net| net['Type'] == 'host-only' }
98
-
99
- hostonly_ifaces = []
100
- net_list.each do |iface|
101
- net_info = json do
102
- execute_prlsrvctl('net', 'info', iface['Network ID'], '--json')
103
- end
104
-
105
- iface = {
106
- name: net_info['Network ID'],
107
- status: 'Down'
108
- }
109
-
110
- adapter = net_info['Parallels adapter']
111
- if adapter && net_info['Bound To']
112
- iface[:ip] = adapter['IP address']
113
- iface[:netmask] = adapter['Subnet mask']
114
- iface[:bound_to] = net_info['Bound To']
115
- iface[:status] = 'Up'
116
- end
117
-
118
- hostonly_ifaces << iface
119
- end
120
- hostonly_ifaces
121
- end
122
-
123
- def read_network_interfaces
124
- nics = {}
125
-
126
- # Get enabled VM's network interfaces
127
- ifaces = read_settings.fetch('Hardware', {}).keep_if do |dev, params|
128
- dev.start_with?('net') and params.fetch('enabled', true)
129
- end
130
- ifaces.each do |name, params|
131
- adapter = name.match(/^net(\d+)$/)[1].to_i
132
- nics[adapter] ||= {}
133
-
134
- if params['type'] == 'shared'
135
- nics[adapter][:type] = :shared
136
- elsif params['type'] == 'host'
137
- # It is PD internal host-only network and it is bounded to 'vnic1'
138
- nics[adapter][:type] = :hostonly
139
- nics[adapter][:hostonly] = 'vnic1'
140
- elsif params['type'] == 'bridged' and params.fetch('iface','').start_with?('vnic')
141
- # Bridged to the 'vnicXX'? Then it is a host-only, actually.
142
- nics[adapter][:type] = :hostonly
143
- nics[adapter][:hostonly] = params.fetch('iface','')
144
- elsif params['type'] == 'bridged'
145
- nics[adapter][:type] = :bridged
146
- nics[adapter][:bridge] = params.fetch('iface','')
147
- end
148
- end
149
- nics
150
- end
151
-
152
- def read_shared_interface
153
- net_info = json do
154
- execute_prlsrvctl('net', 'info', read_shared_network_id, '--json')
155
- end
156
-
157
- iface = {
158
- nat: [],
159
- status: 'Down'
160
- }
161
-
162
- adapter = net_info['Parallels adapter']
163
- if adapter && net_info['Bound To']
164
- iface[:ip] = adapter['IP address']
165
- iface[:netmask] = adapter['Subnet mask']
166
- iface[:bound_to] = net_info['Bound To']
167
- iface[:status] = 'Up'
168
- end
169
-
170
- if net_info.key?('DHCPv4 server')
171
- iface[:dhcp] = {
172
- ip: net_info['DHCPv4 server']['Server address'],
173
- lower: net_info['DHCPv4 server']['IP scope start address'],
174
- upper: net_info['DHCPv4 server']['IP scope end address']
175
- }
176
- end
177
-
178
- iface
179
- end
180
- end
181
- end
182
- end
183
- end
@@ -1,25 +0,0 @@
1
- require 'log4r'
2
-
3
- require 'vagrant/util/platform'
4
-
5
- require_relative 'pd_8'
6
-
7
- module VagrantPlugins
8
- module Parallels
9
- module Driver
10
- # Driver for Parallels Desktop 9.
11
- class PD_9 < PD_8
12
- def initialize(uuid)
13
- super(uuid)
14
-
15
- @logger = Log4r::Logger.new('vagrant_parallels::driver::pd_9')
16
- end
17
-
18
- def set_power_consumption_mode(optimized)
19
- state = optimized ? 'on' : 'off'
20
- execute_prlctl('set', @uuid, '--longer-battery-life', state)
21
- end
22
- end
23
- end
24
- end
25
- end