vagrant-parallels 1.5.1 → 1.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +7 -4
- data/CHANGELOG.md +33 -0
- data/Gemfile +2 -2
- data/README.md +1 -1
- data/debug.log +1237 -1
- data/lib/vagrant-parallels/action.rb +8 -0
- data/lib/vagrant-parallels/action/box_register.rb +113 -0
- data/lib/vagrant-parallels/action/box_unregister.rb +43 -0
- data/lib/vagrant-parallels/action/export.rb +36 -35
- data/lib/vagrant-parallels/action/forward_ports.rb +32 -18
- data/lib/vagrant-parallels/action/import.rb +59 -106
- data/lib/vagrant-parallels/action/network.rb +17 -13
- data/lib/vagrant-parallels/action/prepare_clone_snapshot.rb +67 -0
- data/lib/vagrant-parallels/action/set_name.rb +1 -1
- data/lib/vagrant-parallels/action/snapshot_delete.rb +25 -0
- data/lib/vagrant-parallels/action/snapshot_restore.rb +23 -0
- data/lib/vagrant-parallels/action/snapshot_save.rb +23 -0
- data/lib/vagrant-parallels/cap.rb +63 -0
- data/lib/vagrant-parallels/config.rb +7 -3
- data/lib/vagrant-parallels/driver/base.rb +61 -28
- data/lib/vagrant-parallels/driver/meta.rb +20 -10
- data/lib/vagrant-parallels/driver/pd_11.rb +0 -21
- data/lib/vagrant-parallels/errors.rb +14 -6
- data/lib/vagrant-parallels/guest_cap/darwin/install_parallels_tools.rb +34 -0
- data/lib/vagrant-parallels/plugin.rb +23 -8
- data/lib/vagrant-parallels/version.rb +1 -1
- data/locales/en.yml +31 -17
- data/test/acceptance/provider/linked_clone_spec.rb +6 -2
- data/test/acceptance/skeletons/linked_clone/Vagrantfile +1 -1
- data/test/unit/base.rb +1 -0
- data/test/unit/cap_test.rb +96 -0
- data/test/unit/support/shared/pd_driver_examples.rb +7 -10
- metadata +12 -6
- data/lib/vagrant-parallels/cap/forwarded_ports.rb +0 -22
- data/lib/vagrant-parallels/cap/host_address.rb +0 -15
- data/lib/vagrant-parallels/cap/nic_mac_addresses.rb +0 -17
- data/lib/vagrant-parallels/cap/public_address.rb +0 -15
@@ -14,6 +14,11 @@ module VagrantPlugins
|
|
14
14
|
# We use forwardable to do all our driver forwarding
|
15
15
|
extend Forwardable
|
16
16
|
|
17
|
+
# We cache the Parallels Desktop version here once we have one,
|
18
|
+
# since during the execution of Vagrant, it likely doesn't change.
|
19
|
+
@@version = nil
|
20
|
+
@@version_lock = Mutex.new
|
21
|
+
|
17
22
|
# The UUID of the virtual machine we represent
|
18
23
|
attr_reader :uuid
|
19
24
|
|
@@ -29,23 +34,26 @@ module VagrantPlugins
|
|
29
34
|
|
30
35
|
# Read and assign the version of Parallels Desktop we know which
|
31
36
|
# specific driver to instantiate.
|
32
|
-
|
33
|
-
|
37
|
+
@@version_lock.synchronize do
|
38
|
+
@@version = read_version
|
39
|
+
end
|
40
|
+
|
34
41
|
# Instantiate the proper version driver for Parallels Desktop
|
35
|
-
@logger.debug("Finding driver for Parallels Desktop version: #{
|
42
|
+
@logger.debug("Finding driver for Parallels Desktop version: #{@@version}")
|
36
43
|
|
44
|
+
major_ver = @@version.split('.').first.to_i
|
37
45
|
driver_klass =
|
38
|
-
case
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
46
|
+
case major_ver
|
47
|
+
when 1..7 then raise Errors::ParallelsUnsupportedVersion
|
48
|
+
when 8 then PD_8
|
49
|
+
when 9 then PD_9
|
50
|
+
when 10 then PD_10
|
51
|
+
else PD_11
|
44
52
|
end
|
45
53
|
|
46
54
|
# Starting since PD 11 only Pro and Business editions have CLI
|
47
55
|
# functionality and can be used with Vagrant.
|
48
|
-
if
|
56
|
+
if major_ver >= 11
|
49
57
|
edition = read_edition
|
50
58
|
if !edition || !%w(any pro business).include?(edition)
|
51
59
|
raise Errors::ParallelsUnsupportedEdition
|
@@ -54,6 +62,7 @@ module VagrantPlugins
|
|
54
62
|
|
55
63
|
@logger.info("Using Parallels driver: #{driver_klass}")
|
56
64
|
@driver = driver_klass.new(@uuid)
|
65
|
+
@version = @@version
|
57
66
|
|
58
67
|
if @uuid
|
59
68
|
# Verify the VM exists, and if it doesn't, then don't worry
|
@@ -77,6 +86,7 @@ module VagrantPlugins
|
|
77
86
|
:forward_ports,
|
78
87
|
:halt,
|
79
88
|
:clone_vm,
|
89
|
+
:list_snapshots,
|
80
90
|
:read_bridged_interfaces,
|
81
91
|
:read_current_snapshot,
|
82
92
|
:read_forwarded_ports,
|
@@ -14,27 +14,6 @@ module VagrantPlugins
|
|
14
14
|
|
15
15
|
@logger = Log4r::Logger.new('vagrant_parallels::driver::pd_11')
|
16
16
|
end
|
17
|
-
|
18
|
-
def create_snapshot(uuid, options)
|
19
|
-
args = ['snapshot', uuid]
|
20
|
-
args.concat(['--name', options[:name]]) if options[:name]
|
21
|
-
args.concat(['--description', options[:desc]]) if options[:desc]
|
22
|
-
|
23
|
-
stdout = execute_prlctl(*args)
|
24
|
-
if stdout =~ /\{([\w-]+)\}/
|
25
|
-
return $1
|
26
|
-
end
|
27
|
-
|
28
|
-
raise Errors::SnapshotIdNotDetected, stdout: stdout
|
29
|
-
end
|
30
|
-
|
31
|
-
def read_current_snapshot(uuid)
|
32
|
-
if execute_prlctl('snapshot-list', uuid) =~ /\*\{([\w-]+)\}/
|
33
|
-
return $1
|
34
|
-
end
|
35
|
-
|
36
|
-
nil
|
37
|
-
end
|
38
17
|
end
|
39
18
|
end
|
40
19
|
end
|
@@ -7,6 +7,14 @@ module VagrantPlugins
|
|
7
7
|
error_namespace('vagrant_parallels.errors')
|
8
8
|
end
|
9
9
|
|
10
|
+
class BoxImageNotFound < VagrantParallelsError
|
11
|
+
error_key(:box_image_not_found)
|
12
|
+
end
|
13
|
+
|
14
|
+
class BoxIDNotFound < VagrantParallelsError
|
15
|
+
error_key(:box_id_not_found)
|
16
|
+
end
|
17
|
+
|
10
18
|
class DhcpLeasesNotAccessible < VagrantParallelsError
|
11
19
|
error_key(:dhcp_leases_file_not_accessible)
|
12
20
|
end
|
@@ -51,10 +59,6 @@ module VagrantPlugins
|
|
51
59
|
error_key(:parallels_tools_iso_not_found)
|
52
60
|
end
|
53
61
|
|
54
|
-
class ParallelsTplNameNotFound < VagrantParallelsError
|
55
|
-
error_key(:parallels_tpl_name_not_found)
|
56
|
-
end
|
57
|
-
|
58
62
|
class ParallelsVMOptionNotFound < VagrantParallelsError
|
59
63
|
error_key(:parallels_vm_option_not_found)
|
60
64
|
end
|
@@ -75,8 +79,12 @@ module VagrantPlugins
|
|
75
79
|
error_key(:snapshot_id_not_detected)
|
76
80
|
end
|
77
81
|
|
78
|
-
class
|
79
|
-
error_key(:
|
82
|
+
class SnapshotNotFound < VagrantParallelsError
|
83
|
+
error_key(:snapshot_not_found)
|
84
|
+
end
|
85
|
+
|
86
|
+
class VMCloneFailure < VagrantParallelsError
|
87
|
+
error_key(:vm_clone_failure)
|
80
88
|
end
|
81
89
|
|
82
90
|
class VMNameExists < VagrantParallelsError
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module Parallels
|
3
|
+
module GuestDarwinCap
|
4
|
+
class InstallParallelsTools
|
5
|
+
|
6
|
+
def self.install_parallels_tools(machine)
|
7
|
+
machine.communicate.tap do |comm|
|
8
|
+
tools_iso_path = File.expand_path(
|
9
|
+
machine.provider.driver.read_guest_tools_iso_path('darwin'),
|
10
|
+
machine.env.root_path
|
11
|
+
)
|
12
|
+
remote_file = '/tmp/prl-tools-mac.iso'
|
13
|
+
mount_point = "/media/prl-tools-lin_#{rand(100000)}/"
|
14
|
+
|
15
|
+
comm.upload(tools_iso_path, remote_file)
|
16
|
+
|
17
|
+
# Create mount point directory if needed
|
18
|
+
if !comm.test("test -d \"#{mount_point}\"", :sudo => true)
|
19
|
+
comm.sudo("mkdir -p \"#{mount_point}\"")
|
20
|
+
end
|
21
|
+
|
22
|
+
# Mount ISO and install Parallels Tools
|
23
|
+
comm.sudo("hdiutil attach #{remote_file} -mountpoint #{mount_point}")
|
24
|
+
comm.sudo("installer -pkg '#{mount_point}/Install.app/Contents/Resources/Install.mpkg' -target /")
|
25
|
+
comm.sudo("hdiutil detach '#{mount_point}'")
|
26
|
+
|
27
|
+
comm.sudo("rm -Rf \"#{mount_point}\"")
|
28
|
+
comm.sudo("rm -f \"#{remote_file}\"")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
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.
|
10
|
-
raise 'The Vagrant Parallels plugin is only compatible with Vagrant 1.
|
9
|
+
if Gem::Version.new(Vagrant::VERSION).release < Gem::Version.new('1.8.0')
|
10
|
+
raise 'The installed version of Vagrant Parallels plugin is only compatible with Vagrant 1.8+'
|
11
11
|
end
|
12
12
|
|
13
13
|
module VagrantPlugins
|
@@ -33,6 +33,11 @@ module VagrantPlugins
|
|
33
33
|
Config
|
34
34
|
end
|
35
35
|
|
36
|
+
guest_capability(:darwin, :install_parallels_tools) do
|
37
|
+
require_relative 'guest_cap/darwin/install_parallels_tools'
|
38
|
+
GuestDarwinCap::InstallParallelsTools
|
39
|
+
end
|
40
|
+
|
36
41
|
guest_capability(:darwin, :mount_parallels_shared_folder) do
|
37
42
|
require_relative 'guest_cap/darwin/mount_parallels_shared_folder'
|
38
43
|
GuestDarwinCap::MountParallelsSharedFolder
|
@@ -64,18 +69,28 @@ module VagrantPlugins
|
|
64
69
|
end
|
65
70
|
|
66
71
|
provider_capability(:parallels, :public_address) do
|
67
|
-
require_relative 'cap
|
68
|
-
Cap
|
72
|
+
require_relative 'cap'
|
73
|
+
Cap
|
74
|
+
end
|
75
|
+
|
76
|
+
provider_capability(:parallels, :forwarded_ports) do
|
77
|
+
require_relative 'cap'
|
78
|
+
Cap
|
69
79
|
end
|
70
80
|
|
71
81
|
provider_capability(:parallels, :host_address) do
|
72
|
-
require_relative 'cap
|
73
|
-
Cap
|
82
|
+
require_relative 'cap'
|
83
|
+
Cap
|
74
84
|
end
|
75
85
|
|
76
86
|
provider_capability(:parallels, :nic_mac_addresses) do
|
77
|
-
require_relative 'cap
|
78
|
-
Cap
|
87
|
+
require_relative 'cap'
|
88
|
+
Cap
|
89
|
+
end
|
90
|
+
|
91
|
+
provider_capability(:parallels, :snapshot_list) do
|
92
|
+
require_relative 'cap'
|
93
|
+
Cap
|
79
94
|
end
|
80
95
|
|
81
96
|
synced_folder(:parallels) do
|
data/locales/en.yml
CHANGED
@@ -7,6 +7,18 @@ en:
|
|
7
7
|
# Translations for exception classes
|
8
8
|
#-------------------------------------------------------------------------------
|
9
9
|
errors:
|
10
|
+
box_id_not_found: |-
|
11
|
+
Parallels provider couldn't fetch the box image ID. This is usually because
|
12
|
+
the "config.pvs" file is corrupted or doesn't exist. Please remove the box,
|
13
|
+
re-add it, and try again.
|
14
|
+
|
15
|
+
Box: "%{name}"
|
16
|
+
Box VM config: "%{config}"
|
17
|
+
|
18
|
+
box_image_not_found: |-
|
19
|
+
Parallels VM image (*.pvm) could not be found in the directory of
|
20
|
+
'%{name}' box. This is usually because the image has been removed manually.
|
21
|
+
Please remove the box, re-add it, and try again.
|
10
22
|
dhcp_leases_file_not_accessible: |-
|
11
23
|
Parallels DHCP leases file is not accessible. The Parallels provider
|
12
24
|
uses it to detect an IP address of virtual machine. This file must be
|
@@ -67,12 +79,6 @@ en:
|
|
67
79
|
reinstall Parallels Desktop.
|
68
80
|
|
69
81
|
Expected ISO path: "%{iso_path}"
|
70
|
-
parallels_tpl_name_not_found: |-
|
71
|
-
The VM import failed! Template name not found. Please verify that
|
72
|
-
the box you're using is not corrupted and try again.
|
73
|
-
|
74
|
-
Template config path: "%{config_path}"
|
75
|
-
|
76
82
|
parallels_vm_option_not_found: |-
|
77
83
|
Could not find a required option of Parallels Desktop virtual machine:
|
78
84
|
%{vm_option}
|
@@ -95,17 +101,22 @@ en:
|
|
95
101
|
Desktop for Mac. Please, be aware while choosing the edition to upgrade to.
|
96
102
|
snapshot_id_not_detected: |-
|
97
103
|
ID of the newly created shapshod could not be detected. This is an
|
98
|
-
internal error that users should never see. Please report a bug
|
104
|
+
internal error that users should never see. Please report a bug to
|
105
|
+
Parallels provider.
|
99
106
|
|
100
107
|
stdout: %{stdout}
|
108
|
+
snapshot_not_found: |-
|
109
|
+
The 'linked_clone_snapshot' specified could not be found. Please double
|
110
|
+
check and try again.
|
111
|
+
|
112
|
+
Snapshot ID: %{snapshot}
|
101
113
|
shared_adapter_not_found: |-
|
102
114
|
Shared network adapter was not found in your virtual machine configuration.
|
103
115
|
It is required to communicate with VM and forward ports. Please check
|
104
116
|
network configuration in your Vagrantfile.
|
105
|
-
|
106
|
-
The VM
|
117
|
+
vm_clone_failure: |-
|
118
|
+
The VM cloning failed! Please ensure that the box you're using is not
|
107
119
|
corrupted and try again.
|
108
|
-
|
109
120
|
vm_name_exists: |-
|
110
121
|
Parallels Desktop virtual machine with the name '%{name}' already exists.
|
111
122
|
Please use another name or delete the machine with the existing
|
@@ -170,6 +181,12 @@ en:
|
|
170
181
|
#-------------------------------------------------------------------------------
|
171
182
|
actions:
|
172
183
|
vm:
|
184
|
+
box:
|
185
|
+
register: Registering VM image from the base box '%{name}'...
|
186
|
+
unregister: Unregistering the box VM image...
|
187
|
+
clone:
|
188
|
+
full: Cloning new virtual machine...
|
189
|
+
linked: Creating new virtual machine as a linked clone...
|
173
190
|
handle_guest_tools:
|
174
191
|
cant_install: |-
|
175
192
|
Vagrant doesn't support installing Parallels Tools for the guest OS
|
@@ -181,24 +198,21 @@ en:
|
|
181
198
|
Installing the proper version of Parallels Tools. This may take a few minutes...
|
182
199
|
not_detected: |-
|
183
200
|
Parallels Tools were not detected on this VM! They are required
|
184
|
-
for
|
185
|
-
|
186
|
-
|
187
|
-
reload your VM.
|
201
|
+
for shared folders, time sync and more. If shared folders are not
|
202
|
+
working on this machine, please install Parallels Tools within the
|
203
|
+
virtual machine and reload your VM.
|
188
204
|
rebooting: |-
|
189
205
|
Parallels Tools have been installed. Rebooting the VM...
|
190
206
|
outdated: |-
|
191
207
|
Parallels Tools installed on this VM are outdated! In most cases
|
192
208
|
this is fine but in rare cases it can cause things such as shared
|
193
209
|
folders to not work properly. If you see shared folder errors,
|
194
|
-
please update Parallels Tools within the virtual machine and
|
210
|
+
please update Parallels Tools within the virtual machine and
|
195
211
|
reload your VM.
|
196
212
|
export:
|
197
213
|
compacting: Compacting exported HDDs...
|
198
214
|
forward_ports:
|
199
215
|
forwarding_entry: |-
|
200
216
|
%{guest_port} => %{host_port}
|
201
|
-
import:
|
202
|
-
importing_linked: Importing base box '%{name}' as a linked clone...
|
203
217
|
sane_defaults:
|
204
218
|
setting: Setting the default configuration for VM...
|
@@ -10,7 +10,6 @@ shared_examples 'provider/linked_clone' do |provider, options|
|
|
10
10
|
before do
|
11
11
|
environment.skeleton('linked_clone')
|
12
12
|
assert_execute('vagrant', 'box', 'add', 'basic', options[:box])
|
13
|
-
assert_execute('vagrant', 'up', "--provider=#{provider}")
|
14
13
|
end
|
15
14
|
|
16
15
|
after do
|
@@ -18,7 +17,12 @@ shared_examples 'provider/linked_clone' do |provider, options|
|
|
18
17
|
end
|
19
18
|
|
20
19
|
it 'creates machine as linked clone' do
|
21
|
-
status('Test: machine is
|
20
|
+
status('Test: machine is created as a linked clone')
|
21
|
+
result = execute('vagrant', 'up', "--provider=#{provider}")
|
22
|
+
expect(result).to exit_with(0)
|
23
|
+
expect(result.stdout).to match(/linked clone/)
|
24
|
+
|
25
|
+
status('Test: machine is available by ssh')
|
22
26
|
result = execute('vagrant', 'ssh', '-c', 'echo foo')
|
23
27
|
expect(result).to exit_with(0)
|
24
28
|
expect(result.stdout).to match(/foo\n$/)
|
data/test/unit/base.rb
CHANGED
@@ -0,0 +1,96 @@
|
|
1
|
+
require_relative 'base'
|
2
|
+
|
3
|
+
require 'vagrant-parallels/cap'
|
4
|
+
|
5
|
+
describe VagrantPlugins::Parallels::Cap do
|
6
|
+
include_context 'vagrant-unit'
|
7
|
+
|
8
|
+
let(:iso_env) do
|
9
|
+
# We have to create a Vagrantfile so there is a root path
|
10
|
+
env = isolated_environment
|
11
|
+
env.vagrantfile('')
|
12
|
+
env.create_vagrant_env
|
13
|
+
end
|
14
|
+
|
15
|
+
let(:machine) do
|
16
|
+
iso_env.machine(iso_env.machine_names[0], :dummy).tap do |m|
|
17
|
+
m.provider.stub(driver: driver)
|
18
|
+
m.stub(state: state)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
let(:driver) { double('driver') }
|
23
|
+
let(:state) { double('state', id: :running) }
|
24
|
+
|
25
|
+
describe '#forwarded_ports' do
|
26
|
+
it 'returns all the forwarded ports' do
|
27
|
+
allow(driver).to receive(:read_forwarded_ports).and_return([
|
28
|
+
{ hostport: 123, guestport: 456 },
|
29
|
+
{ hostport: 245, guestport: 245 }
|
30
|
+
])
|
31
|
+
|
32
|
+
expect(described_class.forwarded_ports(machine)).to eq({
|
33
|
+
123 => 456,
|
34
|
+
245 => 245,
|
35
|
+
})
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'returns nil when the machine is not running' do
|
39
|
+
allow(state).to receive(:id).and_return(:stopped)
|
40
|
+
expect(described_class.forwarded_ports(machine)).to be(nil)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe '#host_address' do
|
45
|
+
it "returns host's IP of Shared interface" do
|
46
|
+
allow(driver).to receive(:read_shared_interface).and_return(ip: '1.2.3.4')
|
47
|
+
expect(described_class.host_address(machine)).to eq('1.2.3.4')
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe '#nic_mac_addresses' do
|
52
|
+
it 'returns a hash with MAC addresses' do
|
53
|
+
allow(driver).to receive(:read_mac_addresses).and_return(
|
54
|
+
['001A2B3C4D5E', '005E4D3C2B1A'])
|
55
|
+
expect(described_class.nic_mac_addresses(machine)).to eq({
|
56
|
+
1 => '001A2B3C4D5E',
|
57
|
+
2 => '005E4D3C2B1A'
|
58
|
+
})
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'returns an empty hash when there are no NICs' do
|
62
|
+
allow(driver).to receive(:read_mac_addresses).and_return([])
|
63
|
+
expect(described_class.nic_mac_addresses(machine)).to eq({})
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe '#public_address' do
|
68
|
+
it "returns VM's IP" do
|
69
|
+
allow(machine).to receive(:ssh_info).and_return(host: '1.2.3.4')
|
70
|
+
expect(described_class.public_address(machine)).to eq('1.2.3.4')
|
71
|
+
end
|
72
|
+
|
73
|
+
it "returns nil when the machine is not running" do
|
74
|
+
allow(state).to receive(:id).and_return(:stopped)
|
75
|
+
expect(described_class.public_address(machine)).to be(nil)
|
76
|
+
end
|
77
|
+
|
78
|
+
it "returns nil when there is no ssh info" do
|
79
|
+
allow(machine).to receive(:ssh_info).and_return(nil)
|
80
|
+
expect(described_class.public_address(machine)).to be(nil)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe '#snapshot_list' do
|
85
|
+
it 'returns a list of snapshots' do
|
86
|
+
allow(machine).to receive(:id).and_return('foo')
|
87
|
+
allow(driver).to receive(:list_snapshots).with('foo').and_return({
|
88
|
+
'snap_name_1' => 'snap_uuid_1',
|
89
|
+
'snap_name_2' => 'snap_uuid_2'
|
90
|
+
})
|
91
|
+
|
92
|
+
expect(described_class.snapshot_list(machine)).to eq(
|
93
|
+
['snap_name_1', 'snap_name_2'])
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|