vagrant-parallels 2.1.0 → 2.2.3

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.
@@ -0,0 +1,50 @@
1
+ require_relative "../util/unix_mount_helpers"
2
+
3
+ module VagrantPlugins
4
+ module Parallels
5
+ module SyncedFolderCap
6
+ module MountOptions
7
+ extend VagrantPlugins::Parallels::Util::UnixMountHelpers
8
+
9
+ PRL_MOUNT_TYPE = "prl_fs".freeze
10
+
11
+ # Returns mount options for a parallels synced folder
12
+ #
13
+ # @param [Machine] machine
14
+ # @param [String] name of mount
15
+ # @param [String] path of mount on guest
16
+ # @param [Hash] hash of mount options
17
+ def self.mount_options(machine, name, guest_path, options)
18
+ mount_options = options.fetch(:mount_options, [])
19
+ detected_ids = detect_owner_group_ids(machine, guest_path, mount_options, options)
20
+ mount_uid = detected_ids[:uid]
21
+ mount_gid = detected_ids[:gid]
22
+
23
+ mount_options << "uid=#{mount_uid}"
24
+ mount_options << "gid=#{mount_gid}"
25
+ mount_options << "_netdev"
26
+ mount_options = mount_options.join(',')
27
+ return mount_options, mount_uid, mount_gid
28
+ end
29
+
30
+ def self.mount_type(machine)
31
+ return PRL_MOUNT_TYPE
32
+ end
33
+
34
+ ## We have to support 2 different expected interfaces of `mount_name` call:
35
+ ## Vagrant < 2.2.15: `def self.mount_name(machine, data)`
36
+ ## Vagrant >= 2.2.15: `def self.mount_name(machine, id, data)`
37
+ ## https://github.com/Parallels/vagrant-parallels/issues/384
38
+ def self.mount_name(*args)
39
+ if args.length >= 3
40
+ id = args[1]
41
+ else
42
+ id = args[-1][:guestpath]
43
+ end
44
+
45
+ id.gsub(/[*":<>?|\/\\]/,'_').sub(/^_/, '')
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -27,11 +27,11 @@ module VagrantPlugins
27
27
  # This flag is used to keep track of interrupted state (SIGINT)
28
28
  @interrupted = false
29
29
 
30
- @prlctl_path = util_path('prlctl')
30
+ @prlctl_path = util_path('prlctl')
31
31
  @prlsrvctl_path = util_path('prlsrvctl')
32
32
  @prldisktool_path = util_path('prl_disk_tool')
33
33
 
34
- if !@prlctl_path
34
+ unless @prlctl_path
35
35
  # This means that Parallels Desktop was not found, so we raise this
36
36
  # error here.
37
37
  raise VagrantPlugins::Parallels::Errors::ParallelsNotDetected
@@ -60,9 +60,7 @@ module VagrantPlugins
60
60
  args.concat(["--nat-#{r[:protocol]}-del", r[:name]])
61
61
  end
62
62
 
63
- if !args.empty?
64
- execute_prlsrvctl('net', 'set', read_shared_network_id, *args)
65
- end
63
+ execute_prlsrvctl('net', 'set', read_shared_network_id, *args) unless args.empty?
66
64
  end
67
65
 
68
66
  # Clears the shared folders that have been set on the virtual machine.
@@ -78,7 +76,7 @@ module VagrantPlugins
78
76
  # @param [String] src_name Name or UUID of the source VM or template.
79
77
  # @param [<String => String>] options Options to clone virtual machine.
80
78
  # @return [String] UUID of the new VM.
81
- def clone_vm(src_name, options={})
79
+ def clone_vm(src_name, options = {})
82
80
  dst_name = "vagrant_temp_#{(Time.now.to_f * 1000.0).to_i}_#{rand(100000)}"
83
81
 
84
82
  args = ['clone', src_name, '--name', dst_name]
@@ -146,10 +144,10 @@ module VagrantPlugins
146
144
 
147
145
  # Return the details
148
146
  {
149
- name: options[:network_id],
150
- ip: options[:adapter_ip],
147
+ name: options[:network_id],
148
+ ip: options[:adapter_ip],
151
149
  netmask: options[:netmask],
152
- dhcp: options[:dhcp]
150
+ dhcp: options[:dhcp]
153
151
  }
154
152
  end
155
153
 
@@ -160,9 +158,7 @@ module VagrantPlugins
160
158
  # @return [String] ID of the created snapshot.
161
159
  def create_snapshot(uuid, snapshot_name)
162
160
  stdout = execute_prlctl('snapshot', uuid, '--name', snapshot_name)
163
- if stdout =~ /\{([\w-]+)\}/
164
- return Regexp.last_match(1)
165
- end
161
+ return Regexp.last_match(1) if stdout =~ /{([\w-]+)}/
166
162
 
167
163
  raise Errors::SnapshotIdNotDetected, stdout: stdout
168
164
  end
@@ -222,7 +218,7 @@ module VagrantPlugins
222
218
  # ['create-vm', 'add-vm', 'remove-vm', 'clone-vm']
223
219
  def disable_password_restrictions(acts)
224
220
  server_info = json { execute_prlsrvctl('info', '--json') }
225
- server_info.fetch('Require password to',[]).each do |act|
221
+ server_info.fetch('Require password to', []).each do |act|
226
222
  execute_prlsrvctl('set', '--require-pwd', "#{act}:off") if acts.include? act
227
223
  end
228
224
  end
@@ -251,34 +247,29 @@ module VagrantPlugins
251
247
 
252
248
  # Disable all previously existing adapters (except shared 'vnet0')
253
249
  existing_adapters.each do |adapter|
254
- if adapter != 'vnet0'
255
- execute_prlctl('set', @uuid, '--device-set', adapter, '--disable')
256
- end
250
+ execute_prlctl('set', @uuid, '--device-set', adapter, '--disable') if adapter != 'vnet0'
257
251
  end
258
252
 
259
253
  adapters.each do |adapter|
260
254
  args = []
261
255
  if existing_adapters.include? "net#{adapter[:adapter]}"
262
- args.concat(['--device-set',"net#{adapter[:adapter]}", '--enable'])
256
+ args.concat(['--device-set', "net#{adapter[:adapter]}", '--enable'])
263
257
  else
264
- args.concat(['--device-add', 'net'])
258
+ args.concat(%w[--device-add net])
265
259
  end
266
260
 
267
- if adapter[:type] == :hostonly
261
+ case adapter[:type]
262
+ when :hostonly
268
263
  args.concat(['--type', 'host', '--iface', adapter[:hostonly]])
269
- elsif adapter[:type] == :bridged
264
+ when :bridged
270
265
  args.concat(['--type', 'bridged', '--iface', adapter[:bridge]])
271
- elsif adapter[:type] == :shared
272
- args.concat(['--type', 'shared'])
266
+ when :shared
267
+ args.concat(%w[--type shared])
273
268
  end
274
269
 
275
- if adapter[:mac_address]
276
- args.concat(['--mac', adapter[:mac_address]])
277
- end
270
+ args.concat(['--mac', adapter[:mac_address]]) if adapter[:mac_address]
278
271
 
279
- if adapter[:nic_type]
280
- args.concat(['--adapter-type', adapter[:nic_type].to_s])
281
- end
272
+ args.concat(['--adapter-type', adapter[:nic_type].to_s]) if adapter[:nic_type]
282
273
 
283
274
  execute_prlctl('set', @uuid, *args)
284
275
  end
@@ -308,9 +299,9 @@ module VagrantPlugins
308
299
  protocol = options[:protocol] || 'tcp'
309
300
  pf_builder = [
310
301
  options[:name],
311
- options[:hostport],
302
+ options[:host_port],
312
303
  @uuid,
313
- options[:guestport]
304
+ options[:guest_port]
314
305
  ]
315
306
 
316
307
  args.concat(["--nat-#{protocol}-add", pf_builder.join(',')])
@@ -329,7 +320,7 @@ module VagrantPlugins
329
320
  snap_config = File.join(settings.fetch('Home'), 'Snapshots.xml')
330
321
 
331
322
  # There are no snapshots, exit
332
- return {} if !File.exist?(snap_config)
323
+ return {} unless File.exist?(snap_config)
333
324
 
334
325
  xml = Nokogiri::XML(File.read(snap_config))
335
326
  snapshots = {}
@@ -349,7 +340,7 @@ module VagrantPlugins
349
340
  end
350
341
 
351
342
  # Halts the virtual machine (pulls the plug).
352
- def halt(force=false)
343
+ def halt(force = false)
353
344
  args = ['stop', @uuid]
354
345
  args << '--kill' if force
355
346
  execute_prlctl(*args)
@@ -370,22 +361,18 @@ module VagrantPlugins
370
361
  info = {}
371
362
  ifconfig = execute('ifconfig', iface)
372
363
  # Assign default values
373
- info[:name] = iface
374
- info[:ip] = '0.0.0.0'
364
+ info[:name] = iface
365
+ info[:ip] = '0.0.0.0'
375
366
  info[:netmask] = '0.0.0.0'
376
- info[:status] = 'Down'
367
+ info[:status] = 'Down'
377
368
 
378
- if ifconfig =~ /(?<=inet\s)(\S*)/
379
- info[:ip] = $1.to_s
380
- end
369
+ info[:ip] = $1.to_s if ifconfig =~ /(?<=inet\s)(\S*)/
381
370
  if ifconfig =~ /(?<=netmask\s)(\S*)/
382
371
  # Netmask will be converted from hex to dec:
383
372
  # '0xffffff00' -> '255.255.255.0'
384
- info[:netmask] = $1.hex.to_s(16).scan(/../).each.map{|octet| octet.hex}.join('.')
385
- end
386
- if ifconfig =~ /\W(UP)\W/ and ifconfig !~ /(?<=status:\s)inactive$/
387
- info[:status] = 'Up'
373
+ info[:netmask] = $1.hex.to_s(16).scan(/../).each.map { |octet| octet.hex }.join('.')
388
374
  end
375
+ info[:status] = 'Up' if ifconfig =~ /\W(UP)\W/ and ifconfig !~ /(?<=status:\s)inactive$/
389
376
 
390
377
  bridged_ifaces << info
391
378
  end
@@ -406,7 +393,7 @@ module VagrantPlugins
406
393
  # @param [Boolean] global If true, returns all the rules on the host.
407
394
  # Otherwise only rules related to the context VM will be returned.
408
395
  # @return [Array<Symbol => String>]
409
- def read_forwarded_ports(global=false)
396
+ def read_forwarded_ports(global = false)
410
397
  all_rules = read_shared_interface[:nat]
411
398
 
412
399
  if global
@@ -426,21 +413,21 @@ module VagrantPlugins
426
413
  leases = {}
427
414
  begin
428
415
  File.open(leases_file).grep(/#{mac_addr}/) do |line|
429
- _, ip, exp, dur, _, _ = line.split /([\d.]*)="(\d*),(\d*),(\w*),(\w*)".*/
416
+ _, ip, exp, dur, = line.split /([\d.]*)="(\d*),(\d*),(\w*),(\w*)".*/
430
417
  leases[ip] = exp.to_i - dur.to_i
431
418
  end
432
419
  rescue Errno::EACCES
433
- raise Errors::DhcpLeasesNotAccessible, :leases_file => leases_file.to_s
420
+ raise Errors::DhcpLeasesNotAccessible, leases_file: leases_file.to_s
434
421
  rescue Errno::ENOENT
435
422
  # File does not exist
436
423
  # Perhaps, it is the fist start of Parallels Desktop
437
- return nil
424
+ return ''
438
425
  end
439
426
 
440
- return nil if leases.empty?
427
+ return '' if leases.empty?
441
428
 
442
429
  # Get the most resent lease and return an associated IP
443
- leases.sort_by { |_ip, lease_time| lease_time }.last.first
430
+ leases.max_by { |_ip, lease_time| lease_time }.first
444
431
  end
445
432
 
446
433
  # Returns path to the Parallels Tools ISO file.
@@ -449,21 +436,19 @@ module VagrantPlugins
449
436
  # @return [String] Path to the ISO.
450
437
  def read_guest_tools_iso_path(guest_os)
451
438
  guest_os = guest_os.to_sym
452
- iso_name ={
439
+ iso_name = {
453
440
  linux: 'prl-tools-lin.iso',
454
441
  darwin: 'prl-tools-mac.iso',
455
442
  windows: 'PTIAgent.exe'
456
443
  }
457
- return nil if !iso_name[guest_os]
444
+ return nil unless iso_name[guest_os]
458
445
 
459
- bundle_id = 'com.parallels.desktop.console'
446
+ bundle_id = 'com.parallels.desktop.console'
460
447
  bundle_path = execute('mdfind', "kMDItemCFBundleIdentifier == #{bundle_id}")
461
448
  iso_path = File.expand_path("./Contents/Resources/Tools/#{iso_name[guest_os]}",
462
449
  bundle_path.split("\n")[0])
463
450
 
464
- if !File.exist?(iso_path)
465
- raise Errors::ParallelsToolsIsoNotFound, :iso_path => iso_path
466
- end
451
+ raise Errors::ParallelsToolsIsoNotFound, iso_path: iso_path unless File.exist?(iso_path)
467
452
 
468
453
  iso_path
469
454
  end
@@ -478,7 +463,7 @@ module VagrantPlugins
478
463
  # @return [Symbol]
479
464
  def read_guest_tools_state
480
465
  state = read_settings.fetch('GuestTools', {}).fetch('state', nil)
481
- state = 'not_installed' if !state
466
+ state ||= 'not_installed'
482
467
  state.to_sym
483
468
  end
484
469
 
@@ -512,18 +497,18 @@ module VagrantPlugins
512
497
  end
513
498
 
514
499
  iface = {
515
- name: net_info['Network ID'],
500
+ name: net_info['Network ID'],
516
501
  status: 'Down'
517
502
  }
518
503
 
519
504
  adapter = net_info['Parallels adapter']
520
505
  if adapter
521
- iface[:ip] = adapter['IPv4 address']
522
- iface[:netmask] = adapter['IPv4 subnet mask']
523
- iface[:status] = 'Up'
506
+ iface[:ip] = adapter['IPv4 address']
507
+ iface[:netmask] = adapter['IPv4 subnet mask']
508
+ iface[:status] = 'Up'
524
509
 
525
510
  if adapter['IPv6 address'] && adapter['IPv6 subnet mask']
526
- iface[:ipv6] = adapter['IPv6 address']
511
+ iface[:ipv6] = adapter['IPv6 address']
527
512
  iface[:ipv6_prefix] = adapter['IPv6 subnet mask']
528
513
  end
529
514
  end
@@ -542,9 +527,7 @@ module VagrantPlugins
542
527
  name.start_with?('net') && params['type'] == 'shared'
543
528
  end
544
529
 
545
- if shared_ifaces.empty?
546
- raise Errors::SharedInterfaceNotFound
547
- end
530
+ raise Errors::SharedInterfaceNotFound if shared_ifaces.empty?
548
531
 
549
532
  shared_ifaces.values.first.fetch('mac', nil)
550
533
  end
@@ -570,14 +553,15 @@ module VagrantPlugins
570
553
  adapter = name.match(/^net(\d+)$/)[1].to_i
571
554
  nics[adapter] ||= {}
572
555
 
573
- if params['type'] == 'shared'
556
+ case params['type']
557
+ when 'shared'
574
558
  nics[adapter][:type] = :shared
575
- elsif params['type'] == 'host'
559
+ when 'host'
576
560
  nics[adapter][:type] = :hostonly
577
- nics[adapter][:hostonly] = params.fetch('iface','')
578
- elsif params['type'] == 'bridged'
561
+ nics[adapter][:hostonly] = params.fetch('iface', '')
562
+ when 'bridged'
579
563
  nics[adapter][:type] = :bridged
580
- nics[adapter][:bridge] = params.fetch('iface','')
564
+ nics[adapter][:bridge] = params.fetch('iface', '')
581
565
  end
582
566
  end
583
567
  nics
@@ -586,8 +570,8 @@ module VagrantPlugins
586
570
  # Returns virtual machine settings
587
571
  #
588
572
  # @return [<String => String, Hash>]
589
- def read_settings(uuid=@uuid)
590
- vm = json { execute_prlctl('list', uuid, '--info', '--no-header', '--json') }
573
+ def read_settings(uuid = @uuid)
574
+ vm = json { execute_prlctl('list', uuid, '--info', '--no-header', '--json') }
591
575
  vm.last
592
576
  end
593
577
 
@@ -609,20 +593,20 @@ module VagrantPlugins
609
593
  end
610
594
 
611
595
  iface = {
612
- nat: [],
596
+ nat: [],
613
597
  status: 'Down'
614
598
  }
615
599
  adapter = net_info['Parallels adapter']
616
600
 
617
601
  if adapter
618
- iface[:ip] = adapter['IPv4 address']
619
- iface[:netmask] = adapter['IPv4 subnet mask']
620
- iface[:status] = 'Up'
602
+ iface[:ip] = adapter['IPv4 address']
603
+ iface[:netmask] = adapter['IPv4 subnet mask']
604
+ iface[:status] = 'Up'
621
605
  end
622
606
 
623
607
  if net_info.key?('DHCPv4 server')
624
608
  iface[:dhcp] = {
625
- ip: net_info['DHCPv4 server']['Server address'],
609
+ ip: net_info['DHCPv4 server']['Server address'],
626
610
  lower: net_info['DHCPv4 server']['IP scope start address'],
627
611
  upper: net_info['DHCPv4 server']['IP scope end address']
628
612
  }
@@ -631,10 +615,10 @@ module VagrantPlugins
631
615
  net_info['NAT server'].each do |group, rules|
632
616
  rules.each do |name, params|
633
617
  iface[:nat] << {
634
- name: name,
635
- protocol: group == 'TCP rules' ? 'tcp' : 'udp',
636
- guest: params['destination IP/VM id'],
637
- hostport: params['source port'],
618
+ name: name,
619
+ protocol: group == 'TCP rules' ? 'tcp' : 'udp',
620
+ guest: params['destination IP/VM id'],
621
+ hostport: params['source port'],
638
622
  guestport: params['destination port']
639
623
  }
640
624
  end
@@ -650,7 +634,7 @@ module VagrantPlugins
650
634
  def read_shared_folders
651
635
  shf_info = read_settings.fetch('Host Shared Folders', {})
652
636
  list = {}
653
- shf_info.delete_if { |k,v| k == 'enabled' }.each do |id, data|
637
+ shf_info.delete_if { |k, _v| k == 'enabled' }.each do |id, data|
654
638
  list[id] = data.fetch('path')
655
639
  end
656
640
 
@@ -686,11 +670,9 @@ module VagrantPlugins
686
670
  # @param [String] option Name of option (See all: `prlctl list -L`)
687
671
  # @param [String] uuid Virtual machine UUID
688
672
  # @return [String]
689
- def read_vm_option(option, uuid=@uuid)
690
- out = execute_prlctl('list', uuid,'--no-header', '-o', option).strip
691
- if out.empty?
692
- raise Errors::ParallelsVMOptionNotFound, vm_option: option
693
- end
673
+ def read_vm_option(option, uuid = @uuid)
674
+ out = execute_prlctl('list', uuid, '--no-header', '-o', option).strip
675
+ raise Errors::ParallelsVMOptionNotFound, vm_option: option if out.empty?
694
676
 
695
677
  out
696
678
  end
@@ -699,7 +681,7 @@ module VagrantPlugins
699
681
  #
700
682
  # @return [<String => String>]
701
683
  def read_vms
702
- args = %w(list --all --no-header --json -o name,uuid)
684
+ args = %w[list --all --no-header --json -o name,uuid]
703
685
  vms_arr = json { execute_prlctl(*args) }
704
686
  templates_arr = json { execute_prlctl(*args, '--template') }
705
687
 
@@ -711,7 +693,7 @@ module VagrantPlugins
711
693
  #
712
694
  # @return [Array <String => String>]
713
695
  def read_vms_info
714
- args = %w(list --all --info --no-header --json)
696
+ args = %w[list --all --info --no-header --json]
715
697
  vms_arr = json { execute_prlctl(*args) }
716
698
  templates_arr = json { execute_prlctl(*args, '--template') }
717
699
 
@@ -722,7 +704,7 @@ module VagrantPlugins
722
704
  #
723
705
  # @param [String] pvm_file Path to the machine image (*.pvm)
724
706
  # @param [Array<String>] opts List of options for "prlctl register"
725
- def register(pvm_file, opts=[])
707
+ def register(pvm_file, opts = [])
726
708
  execute_prlctl('register', pvm_file, *opts)
727
709
  end
728
710
 
@@ -823,7 +805,7 @@ module VagrantPlugins
823
805
 
824
806
  # Sometimes this happens. In this case, retry.
825
807
  # If we don't see this text, the VM really doesn't exist.
826
- return false if !result.stderr.include?('Login failed:')
808
+ return false unless result.stderr.include?('Login failed:')
827
809
 
828
810
  # Sleep a bit though to give Parallels Desktop time to fix itself
829
811
  sleep 2
@@ -861,8 +843,8 @@ module VagrantPlugins
861
843
  # If there was an error running command, show the error and the
862
844
  # output.
863
845
  raise VagrantPlugins::Parallels::Errors::ExecutionError,
864
- :command => command.inspect,
865
- :stderr => r.stderr
846
+ command: command.inspect,
847
+ stderr: r.stderr
866
848
  end
867
849
  end
868
850
  r.stdout
@@ -877,12 +859,10 @@ module VagrantPlugins
877
859
  JSON.parse(data)
878
860
  rescue JSON::JSONError
879
861
  # We retried already, raise the issue and be done
880
- if raise_error
881
- raise VagrantPlugins::Parallels::Errors::JSONParseError, data: data
882
- end
862
+ raise VagrantPlugins::Parallels::Errors::JSONParseError, data: data if raise_error
883
863
 
884
864
  # Remove garbage before/after json string[GH-204]
885
- data = data[/(\{.*\}|\[.*\])/m]
865
+ data = data[/({.*}|\[.*\])/m]
886
866
 
887
867
  # Remove all control characters unsupported by JSON [GH-219]
888
868
  data.tr!("\u0000-\u001f", '')
@@ -903,7 +883,7 @@ module VagrantPlugins
903
883
  end
904
884
 
905
885
  # Append in the options for subprocess
906
- command << {notify: [:stdout, :stderr]}
886
+ command << { notify: [:stdout, :stderr] }
907
887
 
908
888
  Vagrant::Util::Busy.busy(int_callback) do
909
889
  Vagrant::Util::Subprocess.execute(*command, &block)