vagrant-parallels 0.0.4.dev → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
- - ! '>='
|