class Omnibus::Compressor::DMG

Public Instance Methods

attach_dmg() click to toggle source

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
clean_disks() click to toggle source

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_dmg() click to toggle source

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() click to toggle source

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_writable_dmg() click to toggle source

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
package_name() click to toggle source

@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
pkg_position(val = NULL) click to toggle source

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
prettify_dmg() click to toggle source

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() click to toggle source

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
resources_dir() click to toggle source

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_dmg_icon() click to toggle source

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
set_volume_icon() click to toggle source

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_dmg() click to toggle source

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
volume_name() click to toggle source

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
window_bounds(val = NULL) click to toggle source

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
writable_dmg() click to toggle source

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