vagrant-parallels 0.0.9 → 0.1.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.
data/README.md CHANGED
@@ -12,18 +12,23 @@ Almost all features are available except for exporting/packaging VM's. This wil
12
12
 
13
13
  We look forward to hearing from you with any issues or features. Thank you!
14
14
 
15
+ ## Installation
16
+ The latest version of this provider is supporting **only Vagrant 1.4 or higher**.
17
+ If you are still using Vagrant 1.3.*, please, specify the plugin version '0.0.9':
18
+
19
+ - For Vagrant 1.4 or higher execute `vagrant plugin install vagrant-parallels`.
20
+ - For Vagrant 1.3.x execute `vagrant plugin install vagrant-parallels --plugin-version 0.0.9`.
21
+
15
22
  ## Usage
16
- Install using standard Vagrant 1.1+ plugin installation methods. After installing, then do a `vagrant up` and specify the `parallels` provider. An example is shown below.
23
+ After installing, then do a `vagrant up` and specify the `parallels` provider. An example is shown below.
17
24
 
18
25
  ```
19
- $ vagrant plugin install vagrant-parallels
20
- ...
21
26
  $ vagrant init
22
27
  $ vagrant up --provider=parallels
23
28
  ...
24
29
  ```
25
30
 
26
- You need to have a parallels compatible box file installed before doing a `vagrant up`, please refer to the coming section for instructions.
31
+ You need to have a parallels compatible box specified in your `Vagrantfile` before doing a `vagrant up`, please refer to the coming section for instructions.
27
32
 
28
33
  ### Default Provider
29
34
 
@@ -12,17 +12,14 @@ module VagrantPlugins
12
12
  def self.action_boot
13
13
  Vagrant::Action::Builder.new.tap do |b|
14
14
  b.use CheckAccessible
15
- # b.use CleanMachineFolder
16
15
  # b.use ClearForwardedPorts
17
16
  b.use Provision
18
17
  b.use EnvSet, :port_collision_repair => true
19
18
  # b.use PrepareForwardedPortCollisionParams
20
19
  # b.use HandleForwardedPortCollisions
21
- b.use PruneNFSExports
22
- b.use NFS
20
+ b.use SyncedFolderCleanup
21
+ b.use SyncedFolders
23
22
  b.use PrepareNFSSettings
24
- b.use ClearSharedFolders
25
- b.use ShareFolders
26
23
  b.use Network
27
24
  b.use ClearNetworkInterfaces
28
25
  # b.use ForwardPorts
@@ -295,11 +292,9 @@ module VagrantPlugins
295
292
  autoload :Package, File.expand_path("../action/package", __FILE__)
296
293
  autoload :PackageConfigFiles, File.expand_path("../action/package_config_files", __FILE__)
297
294
  autoload :PrepareNFSSettings, File.expand_path("../action/prepare_nfs_settings", __FILE__)
298
- autoload :PruneNFSExports, File.expand_path("../action/prune_nfs_exports", __FILE__)
299
295
  autoload :RegisterTemplate, File.expand_path("../action/register_template", __FILE__)
300
296
  autoload :Resume, File.expand_path("../action/resume", __FILE__)
301
297
  autoload :SetupPackageFiles, File.expand_path("../action/setup_package_files", __FILE__)
302
- autoload :ShareFolders, File.expand_path("../action/share_folders", __FILE__)
303
298
  autoload :Suspend, File.expand_path("../action/suspend", __FILE__)
304
299
  autoload :UnregisterTemplate, File.expand_path("../action/unregister_template", __FILE__)
305
300
 
@@ -11,12 +11,11 @@ module VagrantPlugins
11
11
  if !tools_version
12
12
  env[:ui].warn I18n.t("vagrant.actions.vm.check_guest_tools.not_detected")
13
13
  else
14
- env[:machine].provider.driver.verify! =~ /^[\w\s]+ ([\d.]+)$/
15
- os_version = $1
16
- unless os_version.start_with? tools_version
14
+ pd_version = env[:machine].provider.driver.version
15
+ unless pd_version.start_with? tools_version
17
16
  env[:ui].warn(I18n.t("vagrant_parallels.actions.vm.check_guest_tools.version_mismatch",
18
17
  tools_version: tools_version,
19
- parallels_version: os_version))
18
+ parallels_version: pd_version))
20
19
  end
21
20
  end
22
21
 
@@ -8,35 +8,48 @@ module VagrantPlugins
8
8
  end
9
9
 
10
10
  def call(env)
11
+ @machine = env[:machine]
11
12
  @app.call(env)
12
13
 
13
- using_nfs = false
14
- env[:machine].config.vm.synced_folders.each do |id, opts|
15
- if opts[:nfs]
16
- using_nfs = true
17
- break
18
- end
14
+ if using_nfs?
15
+ @logger.info("Using NFS, preparing NFS settings by reading host IP and machine IP")
16
+ add_nfs_settings_to_env!(env)
19
17
  end
18
+ end
20
19
 
21
- if using_nfs
22
- @logger.info("Using NFS, preparing NFS settings by reading host IP and machine IP")
23
- env[:nfs_host_ip] = read_host_ip(env[:machine])
24
- env[:nfs_machine_ip] = read_machine_ip(env[:machine])
20
+ # We're using NFS if we have any synced folder with NFS configured. If
21
+ # we are not using NFS we don't need to do the extra work to
22
+ # populate these fields in the environment.
23
+ def using_nfs?
24
+ @machine.config.vm.synced_folders.any? { |_, opts| opts[:type] == :nfs }
25
+ end
25
26
 
26
- raise Vagrant::Errors::NFSNoHostonlyNetwork if !env[:nfs_machine_ip]
27
- end
27
+ # Extracts the proper host and guest IPs for NFS mounts and stores them
28
+ # in the environment for the SyncedFolder action to use them in
29
+ # mounting.
30
+ #
31
+ # The ! indicates that this method modifies its argument.
32
+ def add_nfs_settings_to_env!(env)
33
+ adapter, host_ip = find_host_only_adapter
34
+ machine_ip = nil
35
+ machine_ip = read_machine_ip if adapter
36
+
37
+ raise Vagrant::Errors::NFSNoHostonlyNetwork if !host_ip || !machine_ip
38
+
39
+ env[:nfs_host_ip] = host_ip
40
+ env[:nfs_machine_ip] = machine_ip
28
41
  end
29
42
 
30
- # Returns the IP address of the first host only network adapter
43
+ # Finds first host only network adapter and returns its adapter number
44
+ # and IP address
31
45
  #
32
- # @param [Machine] machine
33
- # @return [String]
34
- def read_host_ip(machine)
35
- machine.provider.driver.read_network_interfaces.each do |adapter, opts|
46
+ # @return [Integer, String] adapter number, ip address of found host-only adapter
47
+ def find_host_only_adapter
48
+ @machine.provider.driver.read_network_interfaces.each do |adapter, opts|
36
49
  if opts[:type] == :hostonly
37
- machine.provider.driver.read_host_only_interfaces.each do |interface|
50
+ @machine.provider.driver.read_host_only_interfaces.each do |interface|
38
51
  if interface[:bound_to] == opts[:hostonly]
39
- return interface[:ip]
52
+ return adapter, interface[:ip]
40
53
  end
41
54
  end
42
55
  end
@@ -48,17 +61,17 @@ module VagrantPlugins
48
61
  # Returns the IP address of the guest by looking at the first
49
62
  # enabled host only network.
50
63
  #
51
- # @return [String]
52
- def read_machine_ip(machine)
64
+ # @return [String] ip address of adapter in guest
65
+ def read_machine_ip
53
66
  ips = []
54
- machine.config.vm.networks.each do |type, options|
67
+ @machine.config.vm.networks.each do |type, options|
55
68
  if type == :private_network && options[:ip].is_a?(String)
56
69
  ips << options[:ip]
57
70
  end
58
71
  end
59
72
 
60
73
  if ips.empty?
61
- return nil
74
+ raise Vagrant::Errors::NFSNoGuestIP
62
75
  end
63
76
 
64
77
  ips
@@ -411,13 +411,15 @@ module VagrantPlugins
411
411
  #
412
412
  # This should raise a VagrantError if things are not ready.
413
413
  def verify!
414
- # TODO: Use version method?
415
- execute('--version')
414
+ version
416
415
  end
417
416
 
418
417
  def version
419
- raw_version = execute('--version', retryable: true)
420
- raw_version.gsub('/prlctl version /', '')
418
+ if execute('--version', retryable: true) =~ /prlctl version ([\d\.]+)/
419
+ $1.downcase
420
+ else
421
+ raise VagrantPlugins::Parallels::Errors::ParallelsInstallIncomplete
422
+ end
421
423
  end
422
424
 
423
425
  private
@@ -19,6 +19,10 @@ module VagrantPlugins
19
19
  error_key(:parallels_kernel_module_not_loaded)
20
20
  end
21
21
 
22
+ class ParallelsInstallIncomplete < VagrantParallelsError
23
+ error_key(:parallels_install_incomplete)
24
+ end
25
+
22
26
  class ParallelsNoRoomForHighLevelNetwork < VagrantParallelsError
23
27
  error_key(:parallels_no_room_for_high_level_network)
24
28
  end
@@ -6,8 +6,8 @@ end
6
6
 
7
7
  # This is a sanity check to make sure no one is attempting to install
8
8
  # this into an early Vagrant version.
9
- if Vagrant::VERSION < "1.2.0"
10
- raise "The Vagrant Parallels plugin is only compatible with Vagrant 1.2+"
9
+ if Vagrant::VERSION < "1.4.0"
10
+ raise "The Vagrant Parallels plugin is only compatible with Vagrant 1.4+"
11
11
  end
12
12
 
13
13
  module VagrantPlugins
@@ -40,6 +40,11 @@ module VagrantPlugins
40
40
  GuestLinuxCap::MountParallelsSharedFolder
41
41
  end
42
42
 
43
+ synced_folder(:parallels) do
44
+ require File.expand_path("../synced_folder", __FILE__)
45
+ SyncedFolder
46
+ end
47
+
43
48
  end
44
49
 
45
50
  module Driver
@@ -0,0 +1,79 @@
1
+ require "vagrant/util/platform"
2
+
3
+ module VagrantPlugins
4
+ module Parallels
5
+ class SyncedFolder < Vagrant.plugin("2", :synced_folder)
6
+ def usable?(machine)
7
+ # These synced folders only work if the provider if VirtualBox
8
+ machine.provider_name == :parallels
9
+ end
10
+
11
+ def prepare(machine, folders, _opts)
12
+ defs = []
13
+ folders.each do |id, data|
14
+ hostpath = Vagrant::Util::Platform.cygwin_windows_path(data[:hostpath])
15
+
16
+ defs << {
17
+ # Escape special symbols (Parallels Shared Folders specific)
18
+ name: id.split('/').delete_if{|i| i.empty?}.join('_'),
19
+ hostpath: hostpath.to_s,
20
+ transient: data[:transient],
21
+ }
22
+ end
23
+
24
+ driver(machine).share_folders(defs)
25
+ end
26
+
27
+ def enable(machine, folders, _opts)
28
+ # short guestpaths first, so we don't step on ourselves
29
+ folders = folders.sort_by do |id, data|
30
+ if data[:guestpath]
31
+ data[:guestpath].length
32
+ else
33
+ # A long enough path to just do this at the end.
34
+ 10000
35
+ end
36
+ end
37
+
38
+ # Go through each folder and mount
39
+ machine.ui.info(I18n.t("vagrant.actions.vm.share_folders.mounting"))
40
+ folders.each do |id, data|
41
+ if data[:guestpath]
42
+ data[:guestpath] = data[:guestpath]
43
+
44
+ # Guest path specified, so mount the folder to specified point
45
+ machine.ui.info(I18n.t("vagrant.actions.vm.share_folders.mounting_entry",
46
+ :guest_path => data[:guestpath]))
47
+
48
+ # Dup the data so we can pass it to the guest API
49
+ data = data.dup
50
+
51
+ # Calculate the owner and group
52
+ ssh_info = machine.ssh_info
53
+ data[:owner] ||= ssh_info[:username]
54
+ data[:group] ||= ssh_info[:username]
55
+
56
+ # Mount the actual folder
57
+ machine.guest.capability(
58
+ :mount_parallels_shared_folder, id, data[:guestpath], data)
59
+ else
60
+ # If no guest path is specified, then automounting is disabled
61
+ machine.ui.info(I18n.t("vagrant.actions.vm.share_folders.nomount_entry",
62
+ :host_path => data[:hostpath]))
63
+ end
64
+ end
65
+ end
66
+
67
+ def cleanup(machine, opts)
68
+ driver(machine).clear_shared_folders if machine.id && machine.id != ""
69
+ end
70
+
71
+ protected
72
+
73
+ # This is here so that we can stub it for tests
74
+ def driver(machine)
75
+ machine.provider.driver
76
+ end
77
+ end
78
+ end
79
+ end
@@ -1,5 +1,5 @@
1
1
  module VagrantPlugins
2
2
  module Parallels
3
- VERSION = "0.0.9"
3
+ VERSION = "0.1.0"
4
4
  end
5
5
  end
data/locales/en.yml CHANGED
@@ -538,10 +538,9 @@ en:
538
538
  Parallels Desktop is complaining that the kernel module is not loaded. Please
539
539
  run `prlctl --version` or open the Parallels Desktop GUI to see the error
540
540
  message which should contain instructions on how to fix this error.
541
- virtualbox_install_incomplete: |-
542
- Parallels Desktop is complaining that the installation is incomplete. Please
543
- run `prlctl --version` to see the error message which should contain
544
- instructions on how to fix this error.
541
+ parallels_install_incomplete: |-
542
+ Parallels Desktop is complaining that the installation is incomplete. Try to reinstall Parallels
543
+ Desktop or contact Parallels support.
545
544
  parallels_no_room_for_high_level_network: |-
546
545
  There is no available slots on the Parallels Desktop VM for the configured
547
546
  high-level network interfaces. "private_network" and "public_network"
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: 0.0.9
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -127,11 +127,9 @@ files:
127
127
  - lib/vagrant-parallels/action/package.rb
128
128
  - lib/vagrant-parallels/action/package_config_files.rb
129
129
  - lib/vagrant-parallels/action/prepare_nfs_settings.rb
130
- - lib/vagrant-parallels/action/prune_nfs_exports.rb
131
130
  - lib/vagrant-parallels/action/register_template.rb
132
131
  - lib/vagrant-parallels/action/resume.rb
133
132
  - lib/vagrant-parallels/action/setup_package_files.rb
134
- - lib/vagrant-parallels/action/share_folders.rb
135
133
  - lib/vagrant-parallels/action/suspend.rb
136
134
  - lib/vagrant-parallels/action/unregister_template.rb
137
135
  - lib/vagrant-parallels/action.rb
@@ -142,6 +140,7 @@ files:
142
140
  - lib/vagrant-parallels/guest_cap/linux/mount_parallels_shared_folder.rb
143
141
  - lib/vagrant-parallels/plugin.rb
144
142
  - lib/vagrant-parallels/provider.rb
143
+ - lib/vagrant-parallels/synced_folder.rb
145
144
  - lib/vagrant-parallels/version.rb
146
145
  - lib/vagrant-parallels.rb
147
146
  - LICENSE.txt
@@ -168,7 +167,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
168
167
  version: '0'
169
168
  segments:
170
169
  - 0
171
- hash: -608531981673184362
170
+ hash: 646482643972557885
172
171
  required_rubygems_version: !ruby/object:Gem::Requirement
173
172
  none: false
174
173
  requirements:
@@ -1,20 +0,0 @@
1
- module VagrantPlugins
2
- module Parallels
3
- module Action
4
- class PruneNFSExports
5
- def initialize(app, env)
6
- @app = app
7
- end
8
-
9
- def call(env)
10
- if env[:host]
11
- vms = env[:machine].provider.driver.read_all_names
12
- env[:host].nfs_prune(vms.values)
13
- end
14
-
15
- @app.call(env)
16
- end
17
- end
18
- end
19
- end
20
- end
@@ -1,130 +0,0 @@
1
- require "pathname"
2
-
3
- require "log4r"
4
-
5
- require "vagrant/util/platform"
6
- require "vagrant/util/scoped_hash_override"
7
-
8
- module VagrantPlugins
9
- module Parallels
10
- module Action
11
- class ShareFolders
12
- include Vagrant::Util::ScopedHashOverride
13
-
14
- def initialize(app, env)
15
- @logger = Log4r::Logger.new("vagrant::action::vm::share_folders")
16
- @app = app
17
- end
18
-
19
- def call(env)
20
- @env = env
21
-
22
- prepare_folders
23
- create_metadata
24
-
25
- @app.call(env)
26
-
27
- mount_shared_folders
28
- end
29
-
30
- # This method returns an actual list of Parallels Desktop
31
- # shared folders to create and their proper path.
32
- def shared_folders
33
- {}.tap do |result|
34
- @env[:machine].config.vm.synced_folders.each do |id, data|
35
- data = scoped_hash_override(data, :parallels)
36
-
37
- # Ignore NFS shared folders
38
- next if data[:nfs]
39
-
40
- # Ignore disabled shared folders
41
- next if data[:disabled]
42
-
43
- # This to prevent overwriting the actual shared folders data
44
- id = Pathname.new(id).to_s.split('/').drop_while{|i| i.empty?}.join('_')
45
- result[id] = data.dup
46
- end
47
- end
48
- end
49
-
50
- # Prepares the shared folders by verifying they exist and creating them
51
- # if they don't.
52
- def prepare_folders
53
- shared_folders.each do |id, options|
54
- hostpath = Pathname.new(options[:hostpath]).expand_path(@env[:root_path])
55
-
56
- if !hostpath.directory? && options[:create]
57
- # Host path doesn't exist, so let's create it.
58
- @logger.debug("Host path doesn't exist, creating: #{hostpath}")
59
-
60
- begin
61
- hostpath.mkpath
62
- rescue Errno::EACCES
63
- raise Vagrant::Errors::SharedFolderCreateFailed,
64
- :path => hostpath.to_s
65
- end
66
- end
67
- end
68
- end
69
-
70
- def create_metadata
71
- @env[:ui].info I18n.t("vagrant.actions.vm.share_folders.creating")
72
-
73
- folders = []
74
- shared_folders.each do |id, data|
75
- hostpath = File.expand_path(data[:hostpath], @env[:root_path])
76
- hostpath = Vagrant::Util::Platform.cygwin_windows_path(hostpath)
77
-
78
- folders << {
79
- :name => id,
80
- :hostpath => hostpath,
81
- :transient => data[:transient]
82
- }
83
- end
84
-
85
- @env[:machine].provider.driver.share_folders(folders)
86
- end
87
-
88
- # TODO: Fix this, doesn't execute at the correct time
89
- def mount_shared_folders
90
- @env[:ui].info I18n.t("vagrant.actions.vm.share_folders.mounting")
91
-
92
- # short guestpaths first, so we don't step on ourselves
93
- folders = shared_folders.sort_by do |id, data|
94
- if data[:guestpath]
95
- data[:guestpath].length
96
- else
97
- # A long enough path to just do this at the end.
98
- 10000
99
- end
100
- end
101
-
102
- # Go through each folder and mount
103
- folders.each do |id, data|
104
- if data[:guestpath]
105
- # Guest path specified, so mount the folder to specified point
106
- @env[:ui].info(I18n.t("vagrant.actions.vm.share_folders.mounting_entry",
107
- :guest_path => data[:guestpath]))
108
-
109
- # Dup the data so we can pass it to the guest API
110
- data = data.dup
111
-
112
- # Calculate the owner and group
113
- ssh_info = @env[:machine].ssh_info
114
- data[:owner] ||= ssh_info[:username]
115
- data[:group] ||= ssh_info[:username]
116
-
117
- # Mount the actual folder
118
- @env[:machine].guest.capability(
119
- :mount_parallels_shared_folder, id, data[:guestpath], data)
120
- else
121
- # If no guest path is specified, then automounting is disabled
122
- @env[:ui].info(I18n.t("vagrant.actions.vm.share_folders.nomount_entry",
123
- :host_path => data[:hostpath]))
124
- end
125
- end
126
- end
127
- end
128
- end
129
- end
130
- end