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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 56a162b7814012ac1d148abdbec556b1ad44c947
4
- data.tar.gz: 0f6bb9b0154454670a525045fc40627462d84e21
3
+ metadata.gz: e03354e3ebf3d421641208fbd59e61b96a3bfd3b
4
+ data.tar.gz: 3f90e09c1a0bb98d6acb2512dd2644446e635a17
5
5
  SHA512:
6
- metadata.gz: aa4a303bfdf7567dad85868082c79ed8e3305f6a72245f043995c0d4d2ae08fd1c07a95f197dcae949b1801e202a84e47fbe9e7aa7b40d6fe4c0478fa9ffb1ba
7
- data.tar.gz: 3a3f827be1a640ec9394344bc0a5e5695a9f6304587203d9ddeb1ebbc5c050db8ffe43f15ac73e35952da1c86316ecf528c663037d46548f587653b06f3df2c9
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
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- macinbox (3.1.0)
4
+ macinbox (3.2.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
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
- To create and boot a box in the 'vmware_fusion' or 'vmware_desktop' formats you must also have:
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
- To create and boot a box in the 'parallels' format you must also have:
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
- To create and boot a box in the 'virtualbox' format you must also have:
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. You can disable this behavior using the `--no-hidpi` option.
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[:box_format] = "virtualbox"
194
- opts[:image_path] = "macinbox.dmg"
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"
@@ -1,3 +1,4 @@
1
+ require "macinbox/actions/check_macos_versions"
1
2
  require "macinbox/actions/create_box_from_hdd"
2
3
  require "macinbox/actions/create_box_from_vdi"
3
4
  require "macinbox/actions/create_box_from_vmdk"
@@ -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
- Task.run %W[ /bin/cp -r #{@input_hdd} #{@box_dir}/macinbox.pvm/macinbox.hdd ] + [task_opts]
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
- FileUtils.cp @input_vmdk, "#{@box_dir}/macinbox.vmdk"
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
- @collector.on_cleanup do
33
- %x( diskutil eject #{@device.shellescape} > /dev/null 2>&1 ) if @device
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
- @device = %x(
37
- /usr/bin/hdiutil attach #{@input_image.shellescape} -nomount |
38
- /usr/bin/grep _partition_scheme |
39
- /usr/bin/cut -f1 |
40
- /usr/bin/tr -d [:space:]
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
- raise Macinbox::Error.new("failed to attach the image") unless File.exist? @device
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
- Logger.info "Converting the image to HDD format..." do
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
- disk_info = Task.backtick %W[ /usr/sbin/fdisk #{@device} ]
124
+ def convert_image
125
+ Logger.info "Converting the image to HDD format..." do
49
126
 
50
- geometry_re = /geometry: (\d+)\/(\d+)\/(\d+) \[(\d+) sectors\]/
127
+ disk_info = Task.backtick %W[ /usr/sbin/fdisk #{@disk.device} ]
51
128
 
52
- match = geometry_re.match(disk_info)
129
+ geometry_re = /geometry: (\d+)\/(\d+)\/(\d+) \[(\d+) sectors\]/
53
130
 
54
- raise Macinbox::Error.new("failed to determine disk geometry") if match.nil? || match.captures.length != 4
131
+ match = geometry_re.match(disk_info)
55
132
 
56
- device_sectors = match.captures[3]
133
+ raise Macinbox::Error.new("failed to determine disk geometry") if match.nil? || match.captures.length != 4
57
134
 
58
- device_cylinders = match.captures[0]
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
- bios_cylinders = 1024
63
- bios_heads_per_track = device_heads_per_track
64
- bios_sectors_per_track = device_sectors_per_track
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
- File.write "#{@temp_dir}/macinbox.vmdk", <<~EOF
67
- # Disk DescriptorFile
68
- version=1
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
- # Extent description
76
- RW #{device_sectors} FLAT "#{@device}" 0
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
- # The Disk Data Base
79
- #DDB
154
+ # Extent description
155
+ RW #{device_sectors} FLAT "#{@disk.device}" 0
80
156
 
81
- ddb.adapterType = "lsilogic"
82
- ddb.deletable = "true"
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
- prl_convert = "#{@parallels_app}/Contents/MacOS/prl_convert"
95
- task_opts = @debug ? {} : { :out => File::NULL }
96
- Task.run %W[ #{prl_convert} #{@temp_dir}/macinbox.vmdk --allow-no-os --dst=#{@temp_dir} ] + [task_opts]
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
- Logger.info "Moving the HDD to the destination..." do
101
- FileUtils.chown_R ENV["SUDO_USER"], nil, "#{@temp_dir}/macinbox.hdd"
102
- FileUtils.mv "#{@temp_dir}/macinbox.hdd", @output_path
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