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