macinbox 3.1.0 → 3.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -0
- data/Gemfile.lock +1 -1
- data/README.md +68 -13
- data/lib/macinbox.rb +2 -0
- data/lib/macinbox/actions.rb +1 -0
- data/lib/macinbox/actions/check_macos_versions.rb +44 -0
- data/lib/macinbox/actions/create_box_from_hdd.rb +3 -1
- data/lib/macinbox/actions/create_box_from_vmdk.rb +3 -2
- data/lib/macinbox/actions/create_hdd_from_image.rb +133 -55
- data/lib/macinbox/actions/create_image_from_installer.rb +25 -216
- data/lib/macinbox/actions/create_vdi_from_image.rb +54 -16
- data/lib/macinbox/actions/create_vmdk_from_image.rb +106 -19
- data/lib/macinbox/actions/install_box.rb +21 -13
- data/lib/macinbox/cli.rb +30 -16
- data/lib/macinbox/cli/options.rb +4 -0
- data/lib/macinbox/collector.rb +12 -6
- data/lib/macinbox/copyfiles.rb +16 -0
- data/lib/macinbox/version.rb +1 -1
- data/lib/macinbox/virtual_disk.rb +97 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e03354e3ebf3d421641208fbd59e61b96a3bfd3b
|
4
|
+
data.tar.gz: 3f90e09c1a0bb98d6acb2512dd2644446e635a17
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d8e7d1fd2a1b05a6bd89c778ef095ff70f268934281cc263f32375d5119dc25ac9ed3f3315e6e1316d7c1d93f4b23bf5314c32c557d2945a5c58b62e78902a55
|
7
|
+
data.tar.gz: 0d64344b66fb076a07e879a93a66c38d51d67adcd84c48679b83ac579494329e6f31d1e1201e240fb9abd68f36023121a8e15a8871e0b1a8d56db3fc7bc15171
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
## 3.2.0 (February 2, 2019)
|
2
|
+
|
3
|
+
FEATURES:
|
4
|
+
|
5
|
+
- Add --use-qemu option to support building vmware_desktop boxes with qemu-img. [GH-12]
|
6
|
+
- Add --installer-dmg option to support using installers wrapped in disk images. [GH-21]
|
7
|
+
|
8
|
+
IMPROVEMENTS:
|
9
|
+
|
10
|
+
- Use clonefile (`cp -c`) to copy files faster.
|
11
|
+
- Use the detected OS version as the box version.
|
12
|
+
- Skip creation of the wrapper image when it isn't necessary. [GH-21]
|
13
|
+
|
1
14
|
## 3.1.0 (January 21, 2019)
|
2
15
|
|
3
16
|
FEATURES:
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -16,26 +16,49 @@ Supports creating boxes in either the 'vmware_fusion', 'vmware_desktop', 'parall
|
|
16
16
|
* At least 2 cores (4 recommended)
|
17
17
|
* At least 100 GB of available disk space
|
18
18
|
|
19
|
-
## Dependencies
|
19
|
+
## Additional Dependencies
|
20
20
|
|
21
|
-
The following software is required. Versions other than those mentioned may work, but these are the latest versions tested
|
21
|
+
The following software is required. Versions other than those mentioned may work, but these are the latest versions tested.
|
22
|
+
|
23
|
+
### Vagrant
|
24
|
+
|
25
|
+
To boot a box created by `macinbox` you will need Vagrant:
|
22
26
|
|
23
|
-
* [macOS 10.14.2 Mojave installer application](http://appstore.com/mac/macosmojave)
|
24
27
|
* [Vagrant 2.2.3](https://www.vagrantup.com/)
|
25
28
|
|
26
|
-
|
29
|
+
### macOS Installer
|
30
|
+
|
31
|
+
To create a box you will need a macOS installer application:
|
32
|
+
|
33
|
+
* [macOS 10.14.3 Mojave installer application](http://appstore.com/mac/macosmojave)
|
34
|
+
|
35
|
+
Previous versions of the macOS installer (e.g. High Sierra) may also work.
|
36
|
+
|
37
|
+
**NOTE:** If you have questions about the permissibility of virtualizing macOS you may want to review the documentation for the virtualization software you are using and the [software license agreement](https://www.apple.com/legal/sla/) for macOS.
|
38
|
+
|
39
|
+
### Virtualization Software
|
40
|
+
|
41
|
+
One of the following virtualization applications is required:
|
42
|
+
|
43
|
+
#### VMware Fusion
|
44
|
+
|
45
|
+
To create and boot a box in the 'vmware_fusion' or 'vmware_desktop' formats you will need:
|
27
46
|
|
28
47
|
* [VMware Fusion Pro 10.1.5](http://www.vmware.com/products/fusion.html)
|
29
48
|
* [Vagrant VMware Desktop Provider 2.0.1](https://www.vagrantup.com/vmware/)
|
30
49
|
|
31
|
-
**NOTE:** VMware Fusion Pro 11 is not yet supported; see [issue #12](https://github.com/bacongravy/macinbox/issues/12) for more information.
|
50
|
+
**NOTE:** VMware Fusion Pro 11 is not yet supported for box creation; see [issue #12](https://github.com/bacongravy/macinbox/issues/12) for more information. As a workaround you can install `qemu-img` and pass the `--use-qemu` option.
|
32
51
|
|
33
|
-
|
52
|
+
#### Parallels Desktop
|
53
|
+
|
54
|
+
To create and boot a box in the 'parallels' format you will need:
|
34
55
|
|
35
56
|
* [Parallels Desktop 14 for Mac Pro Edition 14.1.0](https://www.parallels.com/products/desktop/)
|
36
57
|
* [Vagrant Parallels Provider 1.7.8](https://parallels.github.io/vagrant-parallels/)
|
37
58
|
|
38
|
-
|
59
|
+
#### VirtualBox
|
60
|
+
|
61
|
+
To create and boot a box in the 'virtualbox' format you will need:
|
39
62
|
|
40
63
|
* [VirtualBox 6.0.2 with the extension pack](https://www.virtualbox.org)
|
41
64
|
|
@@ -80,6 +103,7 @@ Usage: macinbox [options]
|
|
80
103
|
-p, --password PASSWORD Password of the user (default: vagrant)
|
81
104
|
|
82
105
|
--installer PATH Path to the macOS installer app
|
106
|
+
--installer-dmg PATH Path to a macOS installer app disk image
|
83
107
|
--vmware PATH Path to the VMware Fusion app
|
84
108
|
--parallels PATH Path to the Parallels Desktop app
|
85
109
|
|
@@ -89,6 +113,8 @@ Usage: macinbox [options]
|
|
89
113
|
--no-fullscreen Display the virtual machine GUI in a window
|
90
114
|
--no-gui Disable the GUI
|
91
115
|
|
116
|
+
--use-qemu Use qemu-img (vmware_desktop only)
|
117
|
+
|
92
118
|
--debug Enable debug mode
|
93
119
|
|
94
120
|
-v, --version
|
@@ -107,7 +133,7 @@ If you have the VAGRANT_HOME environment variable set and want the created box t
|
|
107
133
|
|
108
134
|
## Retina Display and HiDPI Support
|
109
135
|
|
110
|
-
By default `macinbox` will configure the guest OS to have HiDPI resolutions enabled, and configure the virtual machine to use the native display resolution.
|
136
|
+
By default `macinbox` will configure the guest OS to have HiDPI resolutions enabled, and configure the virtual machine to use the native display resolution. You can disable this behavior using the `--no-hidpi` option.
|
111
137
|
|
112
138
|
## Box Format Support
|
113
139
|
|
@@ -117,6 +143,10 @@ When the box format is set to 'parallels' using the `--box-format` option then t
|
|
117
143
|
|
118
144
|
When the box format is set to 'virtualbox' no guest extensions are installed. Note that some features behave differently with VirtualBox. The screen resolution is set to 1280x800 and HiDPI resolutions are not supported. The GUI scale factor is set to 2.0 (so that the VM displays properly on a host with a retina display) unless the `--no-hidpi` option is used. Lastly, ssh port-forwarding is enabled by default so that the host can connect to the guest.
|
119
145
|
|
146
|
+
## Installer Disk Image Support
|
147
|
+
|
148
|
+
The `--installer-dmg` option allows you to indicate the path to a disk image containing a macOS installer, and overrides the `--installer` option. The specified disk image should not already be mounted; `macinbox` will mount and unmount it as needed. This feature allows you to use the installer disk images created by [installinstallmacos.py](https://github.com/munki/macadmin-scripts/blob/master/installinstallmacos.py) as part of the `macinbox` workflow.
|
149
|
+
|
120
150
|
## Implementation Details
|
121
151
|
|
122
152
|
This tool performs the following actions:
|
@@ -190,16 +220,41 @@ opts = Macinbox::CLI::DEFAULT_OPTION_VALUES
|
|
190
220
|
opts[:collector] = Macinbox::Collector.new
|
191
221
|
opts[:full_name] = "Vagrant"
|
192
222
|
opts[:password] = "vagrant"
|
193
|
-
opts[:
|
194
|
-
opts[:
|
195
|
-
opts[:vdi_path] = "macinbox.vdi"
|
196
|
-
opts[:box_path] = "macinbox.box"
|
197
|
-
opts[:boxes_dir] = File.expand_path "~/.vagrant.d"
|
223
|
+
opts[:image_path] = "macinbox.sparseimage"
|
224
|
+
opts[:boxes_dir] = File.expand_path "~/.vagrant.d/boxes"
|
198
225
|
opts[:debug] = true
|
226
|
+
|
199
227
|
include Macinbox::Actions
|
228
|
+
|
229
|
+
opts[:macos_version] = CheckMacosVersions.new(opts).run
|
230
|
+
|
200
231
|
CreateImageFromInstaller.new(opts).run
|
232
|
+
|
233
|
+
opts[:vmdk_path] = "macinbox.vmdk"
|
234
|
+
CreateVMDKFromImage.new(opts).run
|
235
|
+
|
236
|
+
opts[:box_format] = "vmware_desktop"
|
237
|
+
opts[:box_path] = "vmware_desktop.box"
|
238
|
+
CreateBoxFromVMDK.new(opts).run
|
239
|
+
InstallBox.new(opts).run
|
240
|
+
|
241
|
+
opts[:hdd_path] = "macinbox.hdd"
|
242
|
+
CreateHDDFromImage.new(opts).run
|
243
|
+
|
244
|
+
opts[:box_format] = "parallels"
|
245
|
+
opts[:box_path] = "parallels.box"
|
246
|
+
CreateBoxFromHDD.new(opts).run
|
247
|
+
InstallBox.new(opts).run
|
248
|
+
|
249
|
+
opts[:vdi_path] = "macinbox.vdi"
|
201
250
|
CreateVDIFromImage.new(opts).run
|
251
|
+
|
252
|
+
opts[:box_format] = "virtualbox"
|
253
|
+
opts[:box_path] = "virtualbox.box"
|
202
254
|
CreateBoxFromVDI.new(opts).run
|
255
|
+
InstallBox.new(opts).run
|
256
|
+
|
257
|
+
opts[:collector].cleanup!
|
203
258
|
```
|
204
259
|
|
205
260
|
To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
data/lib/macinbox.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
require "macinbox/actions"
|
2
2
|
require "macinbox/cli"
|
3
3
|
require "macinbox/collector"
|
4
|
+
require "macinbox/copyfiles"
|
4
5
|
require "macinbox/error"
|
5
6
|
require "macinbox/logger"
|
6
7
|
require "macinbox/task"
|
7
8
|
require "macinbox/tty"
|
8
9
|
require "macinbox/version"
|
10
|
+
require "macinbox/virtual_disk"
|
data/lib/macinbox/actions.rb
CHANGED
@@ -0,0 +1,44 @@
|
|
1
|
+
module Macinbox
|
2
|
+
|
3
|
+
module Actions
|
4
|
+
|
5
|
+
class CheckMacosVersions
|
6
|
+
|
7
|
+
def initialize(opts)
|
8
|
+
@installer_app = opts[:installer_path] or raise ArgumentError.new(":installer_path not specified")
|
9
|
+
|
10
|
+
@collector = opts[:collector] or raise ArgumentError.new(":collector not specified")
|
11
|
+
@debug = opts[:debug]
|
12
|
+
|
13
|
+
raise Macinbox::Error.new("Installer app not found") unless File.exist? @installer_app
|
14
|
+
end
|
15
|
+
|
16
|
+
def run
|
17
|
+
install_info_plist = "#{@installer_app}/Contents/SharedSupport/InstallInfo.plist"
|
18
|
+
raise Macinbox::Error.new("InstallInfo.plist not found in installer app bundle") unless File.exist? install_info_plist
|
19
|
+
|
20
|
+
installer_os_version = Task.backtick %W[ /usr/libexec/PlistBuddy -c #{'Print :System\ Image\ Info:version'} #{install_info_plist} ]
|
21
|
+
installer_os_version_components = installer_os_version.split(".") rescue [0, 0, 0]
|
22
|
+
installer_os_version_major = installer_os_version_components[0]
|
23
|
+
installer_os_version_minor = installer_os_version_components[1]
|
24
|
+
Logger.info "Installer macOS version detected: #{installer_os_version}" if @debug
|
25
|
+
|
26
|
+
host_os_version = Task.backtick %W[ /usr/bin/sw_vers -productVersion ]
|
27
|
+
host_os_version_components = host_os_version.split(".") rescue [0, 0, 0]
|
28
|
+
host_os_version_major = host_os_version_components[0]
|
29
|
+
host_os_version_minor = host_os_version_components[1]
|
30
|
+
Logger.info "Host macOS version detected: #{host_os_version}" if @debug
|
31
|
+
|
32
|
+
if installer_os_version_major != host_os_version_major || installer_os_version_minor != host_os_version_minor
|
33
|
+
Logger.error "Warning: host OS version (#{host_os_version}) and installer OS version (#{installer_os_version}) do not match"
|
34
|
+
# raise Macinbox::Error.new("host OS version (#{host_os_version}) and installer OS version (#{installer_os_version}) do not match")
|
35
|
+
end
|
36
|
+
|
37
|
+
installer_os_version
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'fileutils'
|
2
2
|
require 'rubygems/package'
|
3
3
|
|
4
|
+
require 'macinbox/copyfiles'
|
4
5
|
require 'macinbox/error'
|
5
6
|
require 'macinbox/logger'
|
6
7
|
require 'macinbox/task'
|
@@ -62,7 +63,8 @@ module Macinbox
|
|
62
63
|
Task.run %W[ prlctl unregister macinbox ] + [task_opts]
|
63
64
|
end
|
64
65
|
|
65
|
-
|
66
|
+
Macinbox::copyfiles(from: @input_hdd, to: "#{@box_dir}/macinbox.pvm/macinbox.hdd", recursive: true)
|
67
|
+
|
66
68
|
Task.run %W[ prl_disk_tool convert --merge --hdd #{@box_dir}/macinbox.pvm/macinbox.hdd ] + [task_opts]
|
67
69
|
Task.run %W[ prlctl set macinbox --device-add hdd --image #{@box_dir}/macinbox.pvm/macinbox.hdd ] + [task_opts]
|
68
70
|
Task.run %W[ prlctl set macinbox --high-resolution #{@hidpi ? "on" : "off"} ] + [task_opts]
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'fileutils'
|
2
2
|
require 'rubygems/package'
|
3
3
|
|
4
|
+
require 'macinbox/copyfiles'
|
4
5
|
require 'macinbox/error'
|
5
6
|
require 'macinbox/logger'
|
6
7
|
require 'macinbox/task'
|
@@ -28,7 +29,7 @@ module Macinbox
|
|
28
29
|
@debug = opts[:debug]
|
29
30
|
|
30
31
|
raise Macinbox::Error.new("VMDK not found") unless File.exist? @input_vmdk
|
31
|
-
raise Macinbox::Error.new("Box format not supported: #{@box_format}") unless ["vmware_fusion", "vmware_desktop"].include? @box_format
|
32
|
+
raise Macinbox::Error.new("Box format not supported: #{@box_format}") unless ["vmware_fusion", "vmware_desktop"].include? @box_format
|
32
33
|
end
|
33
34
|
|
34
35
|
def run
|
@@ -128,7 +129,7 @@ module Macinbox
|
|
128
129
|
end
|
129
130
|
EOF
|
130
131
|
|
131
|
-
|
132
|
+
Macinbox::copyfiles(from: @input_vmdk, to: "#{@box_dir}/macinbox.vmdk")
|
132
133
|
|
133
134
|
end
|
134
135
|
|
@@ -1,9 +1,11 @@
|
|
1
1
|
require 'fileutils'
|
2
2
|
require 'shellwords'
|
3
3
|
|
4
|
+
require 'macinbox/copyfiles'
|
4
5
|
require 'macinbox/error'
|
5
6
|
require 'macinbox/logger'
|
6
7
|
require 'macinbox/task'
|
8
|
+
require 'macinbox/virtual_disk'
|
7
9
|
|
8
10
|
module Macinbox
|
9
11
|
|
@@ -24,88 +26,164 @@ module Macinbox
|
|
24
26
|
end
|
25
27
|
|
26
28
|
def run
|
29
|
+
create_temp_dir
|
30
|
+
copy_input_image
|
31
|
+
attach_image
|
32
|
+
install_parallels_tools
|
33
|
+
eject_and_reattach_image
|
34
|
+
convert_image
|
35
|
+
save_image
|
36
|
+
end
|
37
|
+
|
38
|
+
def create_temp_dir
|
27
39
|
@temp_dir = Task.backtick %W[ /usr/bin/mktemp -d -t create_hdd_from_image ]
|
28
40
|
@collector.add_temp_dir @temp_dir
|
41
|
+
end
|
29
42
|
|
43
|
+
def copy_input_image
|
44
|
+
Logger.info "Copying the image..." do
|
45
|
+
@image = "#{@temp_dir}/macinbox.sparseimage"
|
46
|
+
Macinbox::copyfiles(from: @input_image, to: @image)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def attach_image
|
30
51
|
Logger.info "Attaching the image..." do
|
52
|
+
@disk = VirtualDisk.new(@image, @debug)
|
53
|
+
@collector.on_cleanup { @disk.detach! }
|
54
|
+
@image_mountpoint = "#{@temp_dir}/image_mountpoint"
|
55
|
+
FileUtils.mkdir @image_mountpoint
|
56
|
+
@disk.attach
|
57
|
+
@disk.mount(at: @image_mountpoint, owners: true)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def install_parallels_tools
|
62
|
+
|
63
|
+
Logger.info "Installing the Parallels Tools..." do
|
64
|
+
|
65
|
+
tools_image = "#{@parallels_app}/Contents/Resources/Tools/prl-tools-mac.iso"
|
66
|
+
|
67
|
+
tools_disk = VirtualDisk.new(tools_image, @debug)
|
68
|
+
|
69
|
+
@collector.on_cleanup { tools_disk.detach! }
|
31
70
|
|
32
|
-
@
|
33
|
-
|
71
|
+
tools_mountpoint = "#{@temp_dir}/tools_mountpoint"
|
72
|
+
FileUtils.mkdir tools_mountpoint
|
73
|
+
|
74
|
+
tools_disk.attach
|
75
|
+
tools_disk.mount(at: tools_mountpoint)
|
76
|
+
|
77
|
+
tools_packages_dir = "#{tools_mountpoint}/Install.app/Contents/Resources/Install.mpkg/Contents/Packages"
|
78
|
+
|
79
|
+
tools_packages = [
|
80
|
+
"Parallels Tools Audio 10.9.pkg",
|
81
|
+
"Parallels Tools Coherence.pkg",
|
82
|
+
"Parallels Tools CopyPaste.pkg",
|
83
|
+
"Parallels Tools DragDrop.pkg",
|
84
|
+
"Parallels Tools HostTime.pkg",
|
85
|
+
"Parallels Tools InstallationAgent.pkg",
|
86
|
+
"Parallels Tools Network 10.9.pkg",
|
87
|
+
"Parallels Tools SharedFolders.pkg",
|
88
|
+
"Parallels Tools TimeSync.pkg",
|
89
|
+
"Parallels Tools ToolGate 10.9.pkg",
|
90
|
+
"Parallels Tools Utilities.pkg",
|
91
|
+
"Parallels Tools Video 10.9.pkg"
|
92
|
+
]
|
93
|
+
|
94
|
+
tools_expanded_packages_dir = "#{@temp_dir}/tools_packages"
|
95
|
+
FileUtils.mkdir tools_expanded_packages_dir
|
96
|
+
|
97
|
+
tools_packages.each do |package|
|
98
|
+
Task.run %W[ /usr/sbin/pkgutil --expand #{tools_packages_dir}/#{package} #{tools_expanded_packages_dir}/#{package} ]
|
99
|
+
Task.run %W[ /usr/bin/ditto -x -z #{tools_expanded_packages_dir}/#{package}/Payload #{@image_mountpoint} ]
|
34
100
|
end
|
35
101
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
102
|
+
prl_nettool_source = "/Library/Parallels Guest Tools/prl_nettool"
|
103
|
+
prl_nettool_target = "#{@image_mountpoint}/usr/local/bin/prl_nettool"
|
104
|
+
|
105
|
+
FileUtils.mkdir_p File.dirname(prl_nettool_target)
|
106
|
+
FileUtils.ln_s prl_nettool_source, prl_nettool_target
|
107
|
+
|
108
|
+
prl_fsd_plist = "#{@image_mountpoint}/Library/LaunchDaemons/com.parallels.vm.prl_fsd.plist"
|
109
|
+
Task.run %W[ /usr/bin/sed -i #{''} s/PARALLELS_ADDITIONAL_ARGS/--share/ #{prl_fsd_plist} ]
|
42
110
|
|
43
|
-
|
111
|
+
contents = "/Library/Parallels\ Guest\ Tools/dynres --enable-retina\n"
|
112
|
+
File.write "#{@image_mountpoint}/private/etc/rc.vagrant", contents, mode: 'a'
|
113
|
+
|
114
|
+
tools_disk.eject
|
44
115
|
end
|
45
116
|
|
46
|
-
|
117
|
+
def eject_and_reattach_image
|
118
|
+
Logger.info "Reattaching the image..." do
|
119
|
+
@disk.eject
|
120
|
+
@disk.attach
|
121
|
+
end
|
122
|
+
end
|
47
123
|
|
48
|
-
|
124
|
+
def convert_image
|
125
|
+
Logger.info "Converting the image to HDD format..." do
|
49
126
|
|
50
|
-
|
127
|
+
disk_info = Task.backtick %W[ /usr/sbin/fdisk #{@disk.device} ]
|
51
128
|
|
52
|
-
|
129
|
+
geometry_re = /geometry: (\d+)\/(\d+)\/(\d+) \[(\d+) sectors\]/
|
53
130
|
|
54
|
-
|
131
|
+
match = geometry_re.match(disk_info)
|
55
132
|
|
56
|
-
|
133
|
+
raise Macinbox::Error.new("failed to determine disk geometry") if match.nil? || match.captures.length != 4
|
57
134
|
|
58
|
-
|
59
|
-
device_heads_per_track = match.captures[1]
|
60
|
-
device_sectors_per_track = match.captures[2]
|
135
|
+
device_sectors = match.captures[3]
|
61
136
|
|
62
|
-
|
63
|
-
|
64
|
-
|
137
|
+
device_cylinders = match.captures[0]
|
138
|
+
device_heads_per_track = match.captures[1]
|
139
|
+
device_sectors_per_track = match.captures[2]
|
65
140
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
encoding="UTF-8"
|
70
|
-
CID=fffffffe
|
71
|
-
parentCID=ffffffff
|
72
|
-
isNativeSnapshot="no"
|
73
|
-
createType="monolithicFlat"
|
141
|
+
bios_cylinders = 1024
|
142
|
+
bios_heads_per_track = device_heads_per_track
|
143
|
+
bios_sectors_per_track = device_sectors_per_track
|
74
144
|
|
75
|
-
#
|
76
|
-
|
145
|
+
File.write "#{@temp_dir}/macinbox.vmdk", <<~EOF
|
146
|
+
# Disk DescriptorFile
|
147
|
+
version=1
|
148
|
+
encoding="UTF-8"
|
149
|
+
CID=fffffffe
|
150
|
+
parentCID=ffffffff
|
151
|
+
isNativeSnapshot="no"
|
152
|
+
createType="monolithicFlat"
|
77
153
|
|
78
|
-
|
79
|
-
|
154
|
+
# Extent description
|
155
|
+
RW #{device_sectors} FLAT "#{@disk.device}" 0
|
80
156
|
|
81
|
-
|
82
|
-
|
83
|
-
ddb.geometry.biosCylinders = "#{bios_cylinders}"
|
84
|
-
ddb.geometry.biosHeads = "#{bios_heads_per_track}"
|
85
|
-
ddb.geometry.biosSectors = "#{bios_sectors_per_track}"
|
86
|
-
ddb.geometry.cylinders = "#{device_cylinders}"
|
87
|
-
ddb.geometry.heads = "#{device_heads_per_track}"
|
88
|
-
ddb.geometry.sectors = "#{device_sectors_per_track}"
|
89
|
-
ddb.longContentID = "9fa218b506cfe68615c39994fffffffe"
|
90
|
-
ddb.uuid = "60 00 C2 99 91 76 dd 77-6e 0d 84 8b b0 24 6e 00"
|
91
|
-
ddb.virtualHWVersion = "14"
|
92
|
-
EOF
|
157
|
+
# The Disk Data Base
|
158
|
+
#DDB
|
93
159
|
|
94
|
-
|
95
|
-
|
96
|
-
|
160
|
+
ddb.adapterType = "lsilogic"
|
161
|
+
ddb.deletable = "true"
|
162
|
+
ddb.geometry.biosCylinders = "#{bios_cylinders}"
|
163
|
+
ddb.geometry.biosHeads = "#{bios_heads_per_track}"
|
164
|
+
ddb.geometry.biosSectors = "#{bios_sectors_per_track}"
|
165
|
+
ddb.geometry.cylinders = "#{device_cylinders}"
|
166
|
+
ddb.geometry.heads = "#{device_heads_per_track}"
|
167
|
+
ddb.geometry.sectors = "#{device_sectors_per_track}"
|
168
|
+
ddb.longContentID = "9fa218b506cfe68615c39994fffffffe"
|
169
|
+
ddb.uuid = "60 00 C2 99 91 76 dd 77-6e 0d 84 8b b0 24 6e 00"
|
170
|
+
ddb.virtualHWVersion = "14"
|
171
|
+
EOF
|
97
172
|
|
173
|
+
prl_convert = "#{@parallels_app}/Contents/MacOS/prl_convert"
|
174
|
+
task_opts = @debug ? {} : { :out => File::NULL }
|
175
|
+
Task.run %W[ #{prl_convert} #{@temp_dir}/macinbox.vmdk --allow-no-os --dst=#{@temp_dir} ] + [task_opts]
|
176
|
+
@disk.eject
|
177
|
+
end
|
98
178
|
end
|
99
179
|
|
100
|
-
|
101
|
-
|
102
|
-
|
180
|
+
def save_image
|
181
|
+
Logger.info "Moving the HDD to the destination..." do
|
182
|
+
FileUtils.chown_R ENV["SUDO_USER"], nil, "#{@temp_dir}/macinbox.hdd"
|
183
|
+
FileUtils.mv "#{@temp_dir}/macinbox.hdd", @output_path
|
184
|
+
end
|
103
185
|
end
|
104
186
|
|
105
|
-
task_opts = @debug ? {} : { :out => File::NULL }
|
106
|
-
Task.run %W[ /usr/sbin/diskutil eject #{@device.shellescape} ] + [task_opts]
|
107
|
-
@device = nil
|
108
|
-
|
109
187
|
end
|
110
188
|
|
111
189
|
end
|