vagrant-parallels 0.0.4.dev → 0.0.4
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 +8 -8
- data/README.md +18 -7
- data/lib/vagrant-parallels/action.rb +32 -13
- data/lib/vagrant-parallels/action/export.rb +72 -0
- data/lib/vagrant-parallels/action/import.rb +10 -9
- data/lib/vagrant-parallels/action/package.rb +20 -0
- data/lib/vagrant-parallels/action/package_config_files.rb +45 -0
- data/lib/vagrant-parallels/action/prune_nfs_exports.rb +1 -1
- data/lib/vagrant-parallels/action/register_template.rb +4 -2
- data/lib/vagrant-parallels/action/setup_package_files.rb +51 -0
- data/lib/vagrant-parallels/action/share_folders.rb +11 -2
- data/lib/vagrant-parallels/action/unregister_template.rb +6 -4
- data/lib/vagrant-parallels/driver/prl_ctl.rb +71 -22
- data/lib/vagrant-parallels/guest_cap/darwin/mount_parallels_shared_folder.rb +31 -0
- data/lib/vagrant-parallels/guest_cap/linux/mount_parallels_shared_folder.rb +31 -0
- data/lib/vagrant-parallels/plugin.rb +17 -2
- data/lib/vagrant-parallels/version.rb +1 -1
- data/locales/en.yml +1 -0
- data/vagrant-parallels.gemspec +1 -1
- metadata +9 -3
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
OTE5YTIzYmUyZWQwZWNmYzE4OTM2MjY3ZWJiZjllNmYyNTNiMWExYg==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
YWNhZjVlMDk2MTk1MjYxMmFmODAxNDU0NTRjYTUyNWNjMDIzZDhiNQ==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
MTA1MDQ2ZTRjYWUwYmQ5MmQ4MmRmM2YzZGZmNjllNjkxMmZmNzg1MzY3NTM1
|
10
|
+
NGZmMmE3MmRjNzE4MDI1NzA2ZmVmN2ZjNTJkOGZlODBjZGY4Y2UyMGIwZTQ1
|
11
|
+
MDFiYTc3MmIyNDkzMWNmNmE3YTNiY2VhN2U3NDMzODlkZWFkOWY=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
YjdjMzU2NzMxZmYxODBhMjNjZTEzYTAzNWY4ZTZhNDJkNDVmZDlkNTEyNGQ1
|
14
|
+
M2NmZWIyYTBiYzZiZmFjNTIxN2IxNWM3NDg4ZjE1MTJlYjJjMmM1NTZjMWYw
|
15
|
+
YzM3NDFkYWNlZGI3MTEzZjhmZTU0ZjEzNjIyNjRjMWY5ZTMwYTk=
|
data/README.md
CHANGED
@@ -1,22 +1,20 @@
|
|
1
1
|
# Vagrant Parallels Provider
|
2
2
|
|
3
|
-
This is a [Vagrant](http://www.vagrantup.com) 1.
|
4
|
-
provider to Vagrant, allowing Vagrant to control and provision machines using Parallels insead of the default Virtualbox.
|
3
|
+
This is a [Vagrant](http://www.vagrantup.com) 1.3+ plugin that adds an [Parallels Desktop](http://www.parallels.com/products/desktop/)
|
4
|
+
provider to Vagrant, allowing Vagrant to control and provision machines using Parallels Desktop insead of the default Virtualbox.
|
5
5
|
|
6
6
|
## Note
|
7
7
|
|
8
8
|
This project is still in active development and not all vagrant features have been developed, please report any issues you might find.
|
9
|
-
Almost all features are available except for exporting/packaging VM's this will be available soon
|
9
|
+
Almost all features are available except for exporting/packaging VM's this will be available soon.
|
10
10
|
|
11
11
|
We look forward to hearing from you with any issues or features, Thank you
|
12
12
|
|
13
13
|
## Usage
|
14
|
-
|
15
|
-
Install using standard Vagrant 1.1+ plugin installation methods. After
|
16
|
-
installing, then do a `vagrant up` and specify the `parallels` provider. An example is shown below.
|
14
|
+
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.
|
17
15
|
|
18
16
|
```
|
19
|
-
$ vagrant plugin install vagrant-parallels
|
17
|
+
$ vagrant plugin install vagrant-parallels
|
20
18
|
...
|
21
19
|
$ vagrant init
|
22
20
|
$ vagrant up --provider=parallels
|
@@ -79,3 +77,16 @@ Use bundler to execute Vagrant:
|
|
79
77
|
```
|
80
78
|
$ bundle exec vagrant up --provider=parallels
|
81
79
|
```
|
80
|
+
|
81
|
+
After testing you can also build a gem-package by yourself and then install it as a plugin:
|
82
|
+
(if you have 'vagrant-parallels' plugin already installed, delete it first)
|
83
|
+
|
84
|
+
```
|
85
|
+
$ git clone https://github.com/yshahin/vagrant-parallels
|
86
|
+
$ cd vagrant-parallels
|
87
|
+
$ rake build
|
88
|
+
...
|
89
|
+
$ vagrant plugin install ./pkg/vagrant-parallels-<version>.gem
|
90
|
+
...
|
91
|
+
```
|
92
|
+
So, now you have your own plugin installed, check it by command `vagrant plugin list`
|
@@ -76,8 +76,9 @@ module VagrantPlugins
|
|
76
76
|
end
|
77
77
|
|
78
78
|
b2.use Call, GracefulHalt, :stopped, :running do |env2, b3|
|
79
|
-
|
80
|
-
|
79
|
+
if !env2[:result]
|
80
|
+
b3.use ForcedHalt
|
81
|
+
end
|
81
82
|
end
|
82
83
|
else
|
83
84
|
b2.use MessageNotCreated
|
@@ -89,6 +90,22 @@ module VagrantPlugins
|
|
89
90
|
# This action packages the virtual machine into a single box file.
|
90
91
|
def self.action_package
|
91
92
|
Vagrant::Action::Builder.new.tap do |b|
|
93
|
+
b.use CheckParallels
|
94
|
+
b.use Call, Created do |env1, b2|
|
95
|
+
if !env1[:result]
|
96
|
+
b2.use MessageNotCreated
|
97
|
+
next
|
98
|
+
end
|
99
|
+
|
100
|
+
b2.use SetupPackageFiles
|
101
|
+
b2.use CheckAccessible
|
102
|
+
b2.use action_halt
|
103
|
+
#b2.use ClearForwardedPorts
|
104
|
+
b2.use ClearSharedFolders
|
105
|
+
b2.use Export
|
106
|
+
b2.use PackageConfigFiles
|
107
|
+
b2.use Package
|
108
|
+
end
|
92
109
|
end
|
93
110
|
end
|
94
111
|
|
@@ -139,16 +156,14 @@ module VagrantPlugins
|
|
139
156
|
# suspended machines.
|
140
157
|
def self.action_resume
|
141
158
|
Vagrant::Action::Builder.new.tap do |b|
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
b2.use MessageNotCreated
|
151
|
-
end
|
159
|
+
b.use CheckParallels
|
160
|
+
b.use Call, Created do |env, b2|
|
161
|
+
if env[:result]
|
162
|
+
b2.use CheckAccessible
|
163
|
+
b2.use EnvSet, :port_collision_repair => false
|
164
|
+
b2.use Resume
|
165
|
+
else
|
166
|
+
b2.use MessageNotCreated
|
152
167
|
end
|
153
168
|
end
|
154
169
|
end
|
@@ -249,6 +264,7 @@ module VagrantPlugins
|
|
249
264
|
end
|
250
265
|
end
|
251
266
|
|
267
|
+
#autoload :PrepareNFSSettings, File.expand_path("../action/prepare_nfs_settings", __FILE__)
|
252
268
|
autoload :Boot, File.expand_path("../action/boot", __FILE__)
|
253
269
|
autoload :CheckAccessible, File.expand_path("../action/check_accessible", __FILE__)
|
254
270
|
autoload :CheckCreated, File.expand_path("../action/check_created", __FILE__)
|
@@ -259,6 +275,7 @@ module VagrantPlugins
|
|
259
275
|
autoload :ClearSharedFolders, File.expand_path("../action/clear_shared_folders", __FILE__)
|
260
276
|
autoload :Created, File.expand_path("../action/created", __FILE__)
|
261
277
|
autoload :Destroy, File.expand_path("../action/destroy", __FILE__)
|
278
|
+
autoload :Export, File.expand_path("../action/export", __FILE__)
|
262
279
|
autoload :ForcedHalt, File.expand_path("../action/forced_halt", __FILE__)
|
263
280
|
autoload :Import, File.expand_path("../action/import", __FILE__)
|
264
281
|
autoload :IsPaused, File.expand_path("../action/is_paused", __FILE__)
|
@@ -269,10 +286,12 @@ module VagrantPlugins
|
|
269
286
|
autoload :MessageNotCreated, File.expand_path("../action/message_not_created", __FILE__)
|
270
287
|
autoload :MessageNotRunning, File.expand_path("../action/message_not_running", __FILE__)
|
271
288
|
autoload :MessageWillNotDestroy, File.expand_path("../action/message_will_not_destroy", __FILE__)
|
272
|
-
|
289
|
+
autoload :Package, File.expand_path("../action/package", __FILE__)
|
290
|
+
autoload :PackageConfigFiles, File.expand_path("../action/package_config_files", __FILE__)
|
273
291
|
autoload :PruneNFSExports, File.expand_path("../action/prune_nfs_exports", __FILE__)
|
274
292
|
autoload :RegisterTemplate, File.expand_path("../action/register_template", __FILE__)
|
275
293
|
autoload :Resume, File.expand_path("../action/resume", __FILE__)
|
294
|
+
autoload :SetupPackageFiles, File.expand_path("../action/setup_package_files", __FILE__)
|
276
295
|
autoload :ShareFolders, File.expand_path("../action/share_folders", __FILE__)
|
277
296
|
autoload :Suspend, File.expand_path("../action/suspend", __FILE__)
|
278
297
|
autoload :UnregisterTemplate, File.expand_path("../action/unregister_template", __FILE__)
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require "fileutils"
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module Parallels
|
5
|
+
module Action
|
6
|
+
class Export
|
7
|
+
attr_reader :temp_dir
|
8
|
+
|
9
|
+
include Util
|
10
|
+
|
11
|
+
def initialize(app, env)
|
12
|
+
@app = app
|
13
|
+
end
|
14
|
+
|
15
|
+
def call(env)
|
16
|
+
@env = env
|
17
|
+
|
18
|
+
raise Vagrant::Errors::VMPowerOffToPackage if \
|
19
|
+
@env[:machine].provider.state.id != :stopped
|
20
|
+
|
21
|
+
setup_temp_dir
|
22
|
+
export
|
23
|
+
compact
|
24
|
+
|
25
|
+
@app.call(env)
|
26
|
+
|
27
|
+
recover(env) # called to cleanup temp directory
|
28
|
+
end
|
29
|
+
|
30
|
+
def recover(env)
|
31
|
+
if temp_dir && File.exist?(temp_dir)
|
32
|
+
FileUtils.rm_rf(temp_dir)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def setup_temp_dir
|
37
|
+
@env[:ui].info I18n.t("vagrant.actions.vm.export.create_dir")
|
38
|
+
@temp_dir = @env["export.temp_dir"] = @env[:tmp_path].join(Time.now.to_i.to_s)
|
39
|
+
FileUtils.mkpath(@env["export.temp_dir"])
|
40
|
+
end
|
41
|
+
|
42
|
+
#TODO: cleanup registered VM on interupt
|
43
|
+
def export
|
44
|
+
vm_name = generate_name(@env[:root_path], '_export')
|
45
|
+
|
46
|
+
@env[:ui].info I18n.t("vagrant.actions.vm.export.exporting")
|
47
|
+
@uuid = @env[:machine].provider.driver.export(@env["export.temp_dir"], vm_name) do |progress|
|
48
|
+
@env[:ui].clear_line
|
49
|
+
@env[:ui].report_progress(progress, 100, false)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Clear the line a final time so the next data can appear
|
53
|
+
# alone on the line.
|
54
|
+
@env[:ui].clear_line
|
55
|
+
end
|
56
|
+
|
57
|
+
def compact
|
58
|
+
@env[:ui].info I18n.t("vagrant_parallels.actions.vm.export.compacting")
|
59
|
+
@env[:machine].provider.driver.compact(@uuid) do |progress|
|
60
|
+
@env[:ui].clear_line
|
61
|
+
@env[:ui].report_progress(progress, 100, false)
|
62
|
+
end
|
63
|
+
@env[:machine].provider.driver.unregister(@uuid)
|
64
|
+
|
65
|
+
# Clear the line a final time so the next data can appear
|
66
|
+
# alone on the line.
|
67
|
+
@env[:ui].clear_line
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -2,29 +2,30 @@ module VagrantPlugins
|
|
2
2
|
module Parallels
|
3
3
|
module Action
|
4
4
|
class Import
|
5
|
+
|
6
|
+
include Util
|
7
|
+
|
5
8
|
def initialize(app, env)
|
6
9
|
@app = app
|
7
10
|
end
|
8
11
|
|
12
|
+
#TODO: Clean up registered VM on interupt
|
9
13
|
def call(env)
|
10
|
-
env[:ui].info I18n.t("
|
14
|
+
env[:ui].info I18n.t("vagrant_parallels.actions.vm.import.importing",
|
11
15
|
:name => env[:machine].box.name)
|
12
16
|
|
13
|
-
|
14
|
-
prefix.gsub!(/[^-a-z0-9_]/i, "")
|
15
|
-
vm_name = prefix + "_#{Time.now.to_i}"
|
17
|
+
vm_name = generate_name(env[:root_path])
|
16
18
|
|
17
19
|
# Verify the name is not taken
|
18
|
-
if env[:machine].provider.driver.
|
20
|
+
if env[:machine].provider.driver.read_all_names.has_key?(vm_name)
|
19
21
|
raise Vagrant::Errors::VMNameExists, :name => vm_name
|
20
22
|
end
|
21
23
|
|
22
24
|
# Import the virtual machine
|
23
|
-
|
24
|
-
|
25
|
-
).first.basename.to_s[0...-4]
|
25
|
+
template_path = File.realpath(Pathname.glob(env[:machine].box.directory.join('*.pvm')).first)
|
26
|
+
template_uuid = env[:machine].provider.driver.read_all_paths[template_path]
|
26
27
|
|
27
|
-
env[:machine].id = env[:machine].provider.driver.import(
|
28
|
+
env[:machine].id = env[:machine].provider.driver.import(template_uuid, vm_name) do |progress|
|
28
29
|
env[:ui].clear_line
|
29
30
|
env[:ui].report_progress(progress, 100, false)
|
30
31
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'vagrant/action/general/package'
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module Parallels
|
5
|
+
module Action
|
6
|
+
class Package < Vagrant::Action::General::Package
|
7
|
+
# Doing this so that we can test that the parent is properly
|
8
|
+
# called in the unit tests.
|
9
|
+
alias_method :general_call, :call
|
10
|
+
def call(env)
|
11
|
+
# Just match up a couple environmental variables so that
|
12
|
+
# the superclass will do the right thing. Then, call the
|
13
|
+
# superclass
|
14
|
+
env["package.directory"] = env["export.temp_dir"]
|
15
|
+
general_call(env)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'vagrant/util/template_renderer'
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module Parallels
|
5
|
+
module Action
|
6
|
+
class PackageConfigFiles
|
7
|
+
# For TemplateRenderer
|
8
|
+
include Vagrant::Util
|
9
|
+
|
10
|
+
def initialize(app, env)
|
11
|
+
@app = app
|
12
|
+
end
|
13
|
+
|
14
|
+
def call(env)
|
15
|
+
@env = env
|
16
|
+
create_metadata
|
17
|
+
create_vagrantfile
|
18
|
+
@app.call(env)
|
19
|
+
end
|
20
|
+
|
21
|
+
# This method creates the auto-generated Vagrantfile at the root of the
|
22
|
+
# box. This Vagrantfile contains the MAC address so that the user doesn't
|
23
|
+
# have to worry about it.
|
24
|
+
def create_vagrantfile
|
25
|
+
File.open(File.join(@env["export.temp_dir"], "Vagrantfile"), "w") do |f|
|
26
|
+
f.write(TemplateRenderer.render("package_Vagrantfile", {
|
27
|
+
:base_mac => @env[:machine].provider.driver.read_mac_address
|
28
|
+
}))
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def create_metadata
|
33
|
+
File.open(File.join(@env["export.temp_dir"], "metadata.json"), "w") do |f|
|
34
|
+
f.write(template_metadatafile)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
def template_metadatafile
|
40
|
+
%Q({"provider": "parallels"}\n)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -7,9 +7,11 @@ module VagrantPlugins
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def call(env)
|
10
|
-
|
10
|
+
pvm_glob = Pathname.glob(env[:machine].box.directory.join('*.pvm')).first
|
11
|
+
# TODO: Handle error cases better, throw a Vagrant error and not a stack trace etc.
|
12
|
+
pvm_file = File.realpath pvm_glob.to_s
|
11
13
|
|
12
|
-
unless env[:machine].provider.driver.registered?(pvm_file
|
14
|
+
unless env[:machine].provider.driver.registered?(pvm_file)
|
13
15
|
env[:machine].provider.driver.register(pvm_file.to_s)
|
14
16
|
end
|
15
17
|
# Call the next if we have one (but we shouldn't, since this
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module Parallels
|
3
|
+
module Action
|
4
|
+
class SetupPackageFiles
|
5
|
+
def initialize(app, env)
|
6
|
+
@app = app
|
7
|
+
|
8
|
+
env["package.include"] ||= []
|
9
|
+
env["package.vagrantfile"] ||= nil
|
10
|
+
end
|
11
|
+
|
12
|
+
def call(env)
|
13
|
+
files = {}
|
14
|
+
env["package.include"].each do |file|
|
15
|
+
source = Pathname.new(file)
|
16
|
+
dest = nil
|
17
|
+
|
18
|
+
# If the source is relative then we add the file as-is to the include
|
19
|
+
# directory. Otherwise, we copy only the file into the root of the
|
20
|
+
# include directory. Kind of strange, but seems to match what people
|
21
|
+
# expect based on history.
|
22
|
+
if source.relative?
|
23
|
+
dest = source
|
24
|
+
else
|
25
|
+
dest = source.basename
|
26
|
+
end
|
27
|
+
|
28
|
+
# Assign the mapping
|
29
|
+
files[file] = dest
|
30
|
+
end
|
31
|
+
|
32
|
+
if env["package.vagrantfile"]
|
33
|
+
# Vagrantfiles are treated special and mapped to a specific file
|
34
|
+
files[env["package.vagrantfile"]] = "_Vagrantfile"
|
35
|
+
end
|
36
|
+
|
37
|
+
# Verify the mapping
|
38
|
+
files.each do |from, _|
|
39
|
+
raise Vagrant::Errors::PackageIncludeMissing,
|
40
|
+
:file => from if !File.exist?(from)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Save the mapping
|
44
|
+
env["package.files"] = files
|
45
|
+
|
46
|
+
@app.call(env)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -106,8 +106,17 @@ module VagrantPlugins
|
|
106
106
|
@env[:ui].info(I18n.t("vagrant.actions.vm.share_folders.mounting_entry",
|
107
107
|
:guest_path => data[:guestpath]))
|
108
108
|
|
109
|
-
#
|
110
|
-
|
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)
|
111
120
|
else
|
112
121
|
# If no guest path is specified, then automounting is disabled
|
113
122
|
@env[:ui].info(I18n.t("vagrant.actions.vm.share_folders.nomount_entry",
|
@@ -7,12 +7,14 @@ module VagrantPlugins
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def call(env)
|
10
|
-
|
10
|
+
template_path = File.realpath(Pathname.glob(
|
11
11
|
env[:machine].box.directory.join('*.pvm')
|
12
|
-
).first
|
12
|
+
).first)
|
13
13
|
|
14
|
-
|
15
|
-
|
14
|
+
template_uuid = env[:machine].provider.driver.read_all_paths[template_path]
|
15
|
+
|
16
|
+
if env[:machine].provider.driver.registered?(template_path)
|
17
|
+
env[:machine].provider.driver.unregister(template_uuid)
|
16
18
|
end
|
17
19
|
# Call the next if we have one (but we shouldn't, since this
|
18
20
|
# middleware is built to run with the Call-type middlewares)
|
@@ -41,27 +41,29 @@ module VagrantPlugins
|
|
41
41
|
read_settings(@uuid).fetch('State', 'inaccessible').to_sym
|
42
42
|
end
|
43
43
|
|
44
|
-
# Returns a hash of all UUIDs
|
45
|
-
# known by Parallels.
|
44
|
+
# Returns a hash of all UUIDs assigned to VMs and templates currently
|
45
|
+
# known by Parallels. Keys are 'name' values
|
46
46
|
#
|
47
47
|
# @return [Hash]
|
48
|
-
def
|
48
|
+
def read_all_names
|
49
49
|
list = {}
|
50
|
-
|
51
|
-
list[item.fetch('
|
50
|
+
read_all_info.each do |item|
|
51
|
+
list[item.fetch('Name')] = item.fetch('ID')
|
52
52
|
end
|
53
53
|
|
54
54
|
list
|
55
55
|
end
|
56
56
|
|
57
|
-
# Returns a hash of all UUIDs
|
58
|
-
# known by Parallels.
|
57
|
+
# Returns a hash of all UUIDs assigned to VMs and templates currently
|
58
|
+
# known by Parallels. Keys are 'Home' directories
|
59
59
|
#
|
60
60
|
# @return [Hash]
|
61
|
-
def
|
61
|
+
def read_all_paths
|
62
62
|
list = {}
|
63
|
-
|
64
|
-
|
63
|
+
read_all_info.each do |item|
|
64
|
+
if Dir.exists? item.fetch('Home')
|
65
|
+
list[File.realpath item.fetch('Home')] = item.fetch('ID')
|
66
|
+
end
|
65
67
|
end
|
66
68
|
|
67
69
|
list
|
@@ -75,18 +77,24 @@ module VagrantPlugins
|
|
75
77
|
#
|
76
78
|
# This should raise a VagrantError if things are not ready.
|
77
79
|
def verify!
|
80
|
+
# TODO: Use version method?
|
78
81
|
execute('--version')
|
79
82
|
end
|
80
83
|
|
84
|
+
def version
|
85
|
+
raw_version = execute('--version', retryable: true)
|
86
|
+
raw_version.gsub('/prlctl version /', '')
|
87
|
+
end
|
88
|
+
|
81
89
|
def clear_shared_folders
|
82
90
|
read_settings.fetch("Host Shared Folders", {}).keys.drop(1).each do |folder|
|
83
91
|
execute("set", @uuid, "--shf-host-del", folder)
|
84
92
|
end
|
85
93
|
end
|
86
94
|
|
87
|
-
def import(
|
95
|
+
def import(template_uuid, vm_name)
|
88
96
|
last = 0
|
89
|
-
execute("clone",
|
97
|
+
execute("clone", template_uuid, '--name', vm_name) do |type, data|
|
90
98
|
lines = data.split("\r")
|
91
99
|
# The progress of the import will be in the last line. Do a greedy
|
92
100
|
# regular expression to find what we're looking for.
|
@@ -131,6 +139,42 @@ module VagrantPlugins
|
|
131
139
|
execute('delete', @uuid)
|
132
140
|
end
|
133
141
|
|
142
|
+
def export(path, vm_name)
|
143
|
+
last = 0
|
144
|
+
execute("clone", @uuid, "--name", vm_name, "--template", "--dst", path.to_s) do |type, data|
|
145
|
+
lines = data.split("\r")
|
146
|
+
# The progress of the import will be in the last line. Do a greedy
|
147
|
+
# regular expression to find what we're looking for.
|
148
|
+
if lines.last =~ /.+?(\d{,3})%/
|
149
|
+
current = $1.to_i
|
150
|
+
if current > last
|
151
|
+
last = current
|
152
|
+
yield current if block_given?
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
read_settings(vm_name).fetch('ID', vm_name)
|
158
|
+
end
|
159
|
+
|
160
|
+
def compact(uuid=nil)
|
161
|
+
uuid ||= @uuid
|
162
|
+
path_to_hdd = read_settings(uuid).fetch("Hardware", {}).fetch("hdd0", {}).fetch("image", nil)
|
163
|
+
last = 0
|
164
|
+
raw('prl_disk_tool', 'compact', '--hdd', path_to_hdd) do |type, data|
|
165
|
+
lines = data.split("\r")
|
166
|
+
# The progress of the import will be in the last line. Do a greedy
|
167
|
+
# regular expression to find what we're looking for.
|
168
|
+
if lines.last =~ /.+?(\d{,3}) ?%/
|
169
|
+
current = $1.to_i
|
170
|
+
if current > last
|
171
|
+
last = current
|
172
|
+
yield current if block_given?
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
134
178
|
def register(pvm_file)
|
135
179
|
execute("register", pvm_file)
|
136
180
|
end
|
@@ -139,8 +183,10 @@ module VagrantPlugins
|
|
139
183
|
execute("unregister", uuid)
|
140
184
|
end
|
141
185
|
|
142
|
-
def registered?(
|
143
|
-
|
186
|
+
def registered?(path)
|
187
|
+
# TODO: Make this take UUID and have callers pass that instead
|
188
|
+
# Need a way to get the UUID from unregistered templates though (config.pvs XML parsing/regex?)
|
189
|
+
read_all_paths.has_key?(path)
|
144
190
|
end
|
145
191
|
|
146
192
|
def set_mac_address(mac)
|
@@ -162,14 +208,6 @@ module VagrantPlugins
|
|
162
208
|
end
|
163
209
|
end
|
164
210
|
|
165
|
-
def symlink(id, path)
|
166
|
-
guest_execute('ln', '-sf', "/media/psf/#{id}", path)
|
167
|
-
end
|
168
|
-
|
169
|
-
def execute_command(command)
|
170
|
-
raw(*command)
|
171
|
-
end
|
172
|
-
|
173
211
|
def ready?
|
174
212
|
!!guest_execute('uname') rescue false
|
175
213
|
end
|
@@ -186,6 +224,17 @@ module VagrantPlugins
|
|
186
224
|
|
187
225
|
private
|
188
226
|
|
227
|
+
# Parse the JSON from *all* VMs and templates. Then return an array of objects (without duplicates)
|
228
|
+
def read_all_info
|
229
|
+
vms_arr = json({}) do
|
230
|
+
execute('list', '--info', '--json', retryable: true).gsub(/^(INFO)?/, '')
|
231
|
+
end
|
232
|
+
templates_arr = json({}) do
|
233
|
+
execute('list', '--info', '--json', '--template', retryable: true).gsub(/^(INFO)?/, '')
|
234
|
+
end
|
235
|
+
vms_arr | templates_arr
|
236
|
+
end
|
237
|
+
|
189
238
|
def read_settings(uuid=nil)
|
190
239
|
uuid ||= @uuid
|
191
240
|
json({}) { execute('list', uuid, '--info', '--json', retryable: true).gsub(/^(INFO)?\[/, '').gsub(/\]$/, '') }
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module Parallels
|
3
|
+
module GuestDarwinCap
|
4
|
+
class MountParallelsSharedFolder
|
5
|
+
|
6
|
+
def self.mount_parallels_shared_folder(machine, name, guestpath, options)
|
7
|
+
machine.communicate.tap do |comm|
|
8
|
+
# clear prior symlink
|
9
|
+
if comm.test("test -L \"#{guestpath}\"", :sudo => true)
|
10
|
+
comm.sudo("rm \"#{guestpath}\"")
|
11
|
+
end
|
12
|
+
|
13
|
+
# clear prior directory if exists
|
14
|
+
if comm.test("test -d \"#{guestpath}\"", :sudo => true)
|
15
|
+
comm.sudo("rm -Rf \"#{guestpath}\"")
|
16
|
+
end
|
17
|
+
|
18
|
+
# create intermediate directories if needed
|
19
|
+
intermediate_dir = File.dirname(guestpath)
|
20
|
+
if !comm.test("test -d \"#{intermediate_dir}\"", :sudo => true)
|
21
|
+
comm.sudo("mkdir -p \"#{intermediate_dir}\"")
|
22
|
+
end
|
23
|
+
|
24
|
+
# finally make the symlink
|
25
|
+
comm.sudo("ln -s \"/Volumes/SharedFolders/#{name}\" \"#{guestpath}\"")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module Parallels
|
3
|
+
module GuestLinuxCap
|
4
|
+
class MountParallelsSharedFolder
|
5
|
+
|
6
|
+
def self.mount_parallels_shared_folder(machine, name, guestpath, options)
|
7
|
+
machine.communicate.tap do |comm|
|
8
|
+
# clear prior symlink
|
9
|
+
if comm.test("test -L \"#{guestpath}\"", :sudo => true)
|
10
|
+
comm.sudo("rm \"#{guestpath}\"")
|
11
|
+
end
|
12
|
+
|
13
|
+
# clear prior directory if exists
|
14
|
+
if comm.test("test -d \"#{guestpath}\"", :sudo => true)
|
15
|
+
comm.sudo("rm -Rf \"#{guestpath}\"")
|
16
|
+
end
|
17
|
+
|
18
|
+
# create intermediate directories if needed
|
19
|
+
intermediate_dir = File.dirname(guestpath)
|
20
|
+
if !comm.test("test -d \"#{intermediate_dir}\"", :sudo => true)
|
21
|
+
comm.sudo("mkdir -p \"#{intermediate_dir}\"")
|
22
|
+
end
|
23
|
+
|
24
|
+
# finally make the symlink
|
25
|
+
comm.sudo("ln -s \"/media/psf/#{name}\" \"#{guestpath}\"")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require "vagrant"
|
2
|
-
|
3
1
|
begin
|
4
2
|
require "vagrant"
|
5
3
|
rescue LoadError
|
@@ -70,10 +68,27 @@ module VagrantPlugins
|
|
70
68
|
# require File.expand_path("../config", __FILE__)
|
71
69
|
# Config
|
72
70
|
# end
|
71
|
+
|
72
|
+
guest_capability(:darwin, :mount_parallels_shared_folder) do
|
73
|
+
require_relative "guest_cap/darwin/mount_parallels_shared_folder"
|
74
|
+
GuestDarwinCap::MountParallelsSharedFolder
|
75
|
+
end
|
76
|
+
|
77
|
+
guest_capability(:linux, :mount_parallels_shared_folder) do
|
78
|
+
require_relative "guest_cap/linux/mount_parallels_shared_folder"
|
79
|
+
GuestLinuxCap::MountParallelsSharedFolder
|
80
|
+
end
|
81
|
+
|
73
82
|
end
|
74
83
|
|
75
84
|
module Driver
|
76
85
|
autoload :PrlCtl, File.expand_path("../driver/prl_ctl", __FILE__)
|
77
86
|
end
|
87
|
+
|
88
|
+
module Util
|
89
|
+
def generate_name(path, suffix='')
|
90
|
+
"#{path.basename.to_s.gsub(/[^-a-z0-9_]/i, '')}#{suffix}_#{Time.now.to_i}"
|
91
|
+
end
|
92
|
+
end
|
78
93
|
end
|
79
94
|
end
|
data/locales/en.yml
CHANGED
@@ -835,6 +835,7 @@ en:
|
|
835
835
|
export:
|
836
836
|
create_dir: Creating temporary directory for export...
|
837
837
|
exporting: Exporting VM...
|
838
|
+
compacting: Compacting exported HDD...
|
838
839
|
power_off: "The Vagrant virtual environment you are trying to package must be powered off."
|
839
840
|
forward_ports:
|
840
841
|
auto_empty: |-
|
data/vagrant-parallels.gemspec
CHANGED
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.4
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Youssef Shahin
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-10-06 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -100,6 +100,7 @@ files:
|
|
100
100
|
- lib/vagrant-parallels/action/clear_shared_folders.rb
|
101
101
|
- lib/vagrant-parallels/action/created.rb
|
102
102
|
- lib/vagrant-parallels/action/destroy.rb
|
103
|
+
- lib/vagrant-parallels/action/export.rb
|
103
104
|
- lib/vagrant-parallels/action/forced_halt.rb
|
104
105
|
- lib/vagrant-parallels/action/import.rb
|
105
106
|
- lib/vagrant-parallels/action/is_paused.rb
|
@@ -110,16 +111,21 @@ files:
|
|
110
111
|
- lib/vagrant-parallels/action/message_not_created.rb
|
111
112
|
- lib/vagrant-parallels/action/message_not_running.rb
|
112
113
|
- lib/vagrant-parallels/action/message_will_not_destroy.rb
|
114
|
+
- lib/vagrant-parallels/action/package.rb
|
115
|
+
- lib/vagrant-parallels/action/package_config_files.rb
|
113
116
|
- lib/vagrant-parallels/action/prepare_nfs_settings.rb
|
114
117
|
- lib/vagrant-parallels/action/prune_nfs_exports.rb
|
115
118
|
- lib/vagrant-parallels/action/register_template.rb
|
116
119
|
- lib/vagrant-parallels/action/resume.rb
|
120
|
+
- lib/vagrant-parallels/action/setup_package_files.rb
|
117
121
|
- lib/vagrant-parallels/action/share_folders.rb
|
118
122
|
- lib/vagrant-parallels/action/suspend.rb
|
119
123
|
- lib/vagrant-parallels/action/unregister_template.rb
|
120
124
|
- lib/vagrant-parallels/action.rb
|
121
125
|
- lib/vagrant-parallels/driver/prl_ctl.rb
|
122
126
|
- lib/vagrant-parallels/errors.rb
|
127
|
+
- lib/vagrant-parallels/guest_cap/darwin/mount_parallels_shared_folder.rb
|
128
|
+
- lib/vagrant-parallels/guest_cap/linux/mount_parallels_shared_folder.rb
|
123
129
|
- lib/vagrant-parallels/plugin.rb
|
124
130
|
- lib/vagrant-parallels/provider.rb
|
125
131
|
- lib/vagrant-parallels/version.rb
|
@@ -139,7 +145,7 @@ metadata: {}
|
|
139
145
|
post_install_message:
|
140
146
|
rdoc_options: []
|
141
147
|
require_paths:
|
142
|
-
-
|
148
|
+
- lib
|
143
149
|
required_ruby_version: !ruby/object:Gem::Requirement
|
144
150
|
requirements:
|
145
151
|
- - ! '>='
|