class Omnibus::Compressor::DMG
Public Instance Methods
Attach the dmg, storing a reference to the device for later use.
@return [String]
the name of the attached device
# File lib/omnibus/compressors/dmg.rb, line 159 def attach_dmg @device ||= Dir.chdir(staging_dir) do log.info(log_key) { "Attaching dmg as disk" } cmd = shellout! <<-EOH.gsub(/^ {10}/, "") hdiutil attach \\ -puppetstrings \\ -readwrite \\ -noverify \\ -noautoopen \\ "#{writable_dmg}" | egrep '^/dev/' | sed 1q | awk '{print $1}' EOH cmd.stdout.strip end end
Cleans any previously left over mounted disks.
We are trying to detach disks that look like:
/dev/disk1s1 on /Volumes/chef (hfs, local, nodev, nosuid, read-only, noowners, quarantine, mounted by serdar) /dev/disk2s1 on /Volumes/chef 1 (hfs, local, nodev, nosuid, read-only, noowners, quarantine, mounted by serdar)
@return [void]
# File lib/omnibus/compressors/dmg.rb, line 121 def clean_disks log.info(log_key) { "Cleaning previously mounted disks" } existing_disks = shellout!("mount | grep \"/Volumes/#{volume_name}\" | awk '{print $1}'") existing_disks.stdout.lines.each do |existing_disk| existing_disk.chomp! Omnibus.logger.debug(log_key) do "Detaching disk `#{existing_disk}' before starting dmg packaging." end shellout!("hdiutil detach '#{existing_disk}'") end end
Compress the dmg using hdiutil and zlib. zlib offers better compression levels than bzip2 (10.4+) or LZFSE (10.11+), but takes longer to compress. We’re willing to trade slightly longer build times for smaller package sizes.
@return [void]
# File lib/omnibus/compressors/dmg.rb, line 253 def compress_dmg log.info(log_key) { "Compressing dmg" } Dir.chdir(staging_dir) do shellout! <<-EOH.gsub(/^ {10}/, "") chmod -Rf go-w "/Volumes/#{volume_name}" sync hdiutil unmount "#{@device}" # Give some time to the system so unmount dmg ATTEMPTS=1 until [ $ATTEMPTS -eq 6 ] || hdiutil detach "#{@device}"; do sleep 10 echo Attempt number $(( ATTEMPTS++ )) done hdiutil convert \\ "#{writable_dmg}" \\ -format UDZO \\ -imagekey \\ zlib-level=9 \\ -o "#{package_path}" \\ -puppetstrings EOH end end
Copy assets to dmg
# File lib/omnibus/compressors/dmg.rb, line 179 def copy_assets_to_dmg log.info(log_key) { "Copying assets into dmg" } FileSyncer.glob("#{resources_dir}/*").each do |file| FileUtils.cp_r(file, "/Volumes/#{volume_name}") end end
Create a writable dmg we can put assets on.
# File lib/omnibus/compressors/dmg.rb, line 139 def create_writable_dmg log.info(log_key) { "Creating writable dmg" } shellout! <<-EOH.gsub(/^ {8}/, "") hdiutil create \\ -volname "#{volume_name}" \\ -fs HFS+ \\ -fsargs "-c c=64,a=16,e=16" \\ -size 512000k \\ "#{writable_dmg}" \\ -puppetstrings EOH end
@see Base#package_name
# File lib/omnibus/compressors/dmg.rb, line 336 def package_name extname = File.extname(packager.package_name) packager.package_name.sub(extname, ".dmg") end
Set or return the starting x,y position where the .pkg file should live in the DMG
window.
@example
pkg_position "535, 50"
@param [String] val
the PKG position inside the DMG
@return [String]
the PKG position inside the DMG
# File lib/omnibus/compressors/dmg.rb, line 89 def pkg_position(val = NULL) if null?(val) @pkg_position || "535, 50" else @pkg_position = val end end
Use Applescript to setup the DMG
with pretty logos and colors.
@return [void]
# File lib/omnibus/compressors/dmg.rb, line 227 def prettify_dmg log.info(log_key) { "Making the dmg all pretty and stuff" } render_template(resource_path("create_dmg.osascript.erb"), destination: "#{staging_dir}/create_dmg.osascript", variables: { volume_name: volume_name, pkg_name: packager.package_name, window_bounds: window_bounds, pkg_position: pkg_position, }) Dir.chdir(staging_dir) do shellout! <<-EOH.gsub(/^ {10}/, "") osascript "#{staging_dir}/create_dmg.osascript" EOH end end
Remove writable dmg.
@return [void]
# File lib/omnibus/compressors/dmg.rb, line 300 def remove_writable_dmg log.info(log_key) { "Removing writable dmg" } Dir.chdir(staging_dir) do shellout! <<-EOH.gsub(/^ {10}/, "") rm -rf "#{writable_dmg}" EOH end end
The path where the MSI resources will live.
@return [String]
# File lib/omnibus/compressors/dmg.rb, line 107 def resources_dir File.expand_path("#{staging_dir}/Resources") end
Set the dmg icon to our custom icon.
@return [void]
# File lib/omnibus/compressors/dmg.rb, line 315 def set_dmg_icon log.info(log_key) { "Setting dmg icon" } Dir.chdir(staging_dir) do shellout! <<-EOH.gsub(/^ {10}/, "") # Convert the png to an icon sips -i "#{resource_path("icon.png")}" # Extract the icon into its own resource DeRez -only icns "#{resource_path("icon.png")}" > tmp.rsrc # Append the icon reosurce to the DMG Rez -append tmp.rsrc -o "#{package_path}" # Source the icon SetFile -a C "#{package_path}" EOH end end
Create the icon for the volume using sips.
@return [void]
# File lib/omnibus/compressors/dmg.rb, line 192 def set_volume_icon log.info(log_key) { "Setting volume icon" } icon = resource_path("icon.png") Dir.chdir(staging_dir) do shellout! <<-EOH.gsub(/^ {10}/, "") # Generate the icns mkdir tmp.iconset sips -z 16 16 #{icon} --out tmp.iconset/icon_16x16.png sips -z 32 32 #{icon} --out tmp.iconset/icon_16x16@2x.png sips -z 32 32 #{icon} --out tmp.iconset/icon_32x32.png sips -z 64 64 #{icon} --out tmp.iconset/icon_32x32@2x.png sips -z 128 128 #{icon} --out tmp.iconset/icon_128x128.png sips -z 256 256 #{icon} --out tmp.iconset/icon_128x128@2x.png sips -z 256 256 #{icon} --out tmp.iconset/icon_256x256.png sips -z 512 512 #{icon} --out tmp.iconset/icon_256x256@2x.png sips -z 512 512 #{icon} --out tmp.iconset/icon_512x512.png sips -z 1024 1024 #{icon} --out tmp.iconset/icon_512x512@2x.png iconutil -c icns tmp.iconset # Copy it over cp tmp.icns "/Volumes/#{volume_name}/.VolumeIcon.icns" # Source the icon SetFile -a C "/Volumes/#{volume_name}" EOH end end
Verify checksum on created dmg.
@return [void]
# File lib/omnibus/compressors/dmg.rb, line 283 def verify_dmg log.info(log_key) { "Verifying dmg" } Dir.chdir(staging_dir) do shellout! <<-EOH.gsub(/^ {10}/, "") hdiutil verify \\ "#{package_path}" \\ -puppetstrings EOH end end
The name of the volume to create. By defauly, this is the project’s friendly name.
@return [String]
# File lib/omnibus/compressors/dmg.rb, line 354 def volume_name project.friendly_name end
Set or return the starting x,y and ending x,y positions for the created DMG
window.
@example
window_bounds "100, 100, 750, 600"
@param [String] val
the DMG window bounds
@return [String]
the DMG window bounds
# File lib/omnibus/compressors/dmg.rb, line 67 def window_bounds(val = NULL) if null?(val) @window_bounds || "100, 100, 750, 600" else @window_bounds = val end end
The path to the writable dmg on disk.
@return [String]
# File lib/omnibus/compressors/dmg.rb, line 344 def writable_dmg File.expand_path("#{staging_dir}/#{project.name}-writable.dmg") end