Merge pull request #2772 from reitermarkus/dmg-eula

Fix DMG mounting.
This commit is contained in:
Markus Reiter 2017-07-02 02:04:07 +02:00 committed by GitHub
commit eb110e94f0
5 changed files with 76 additions and 59 deletions

View File

@ -16,7 +16,7 @@ module Hbc
end end
ohai "Extracting nested container #{source.basename}" ohai "Extracting nested container #{source.basename}"
container.new(@cask, source, @command).extract container.new(@cask, source, @command, verbose: verbose?).extract
FileUtils.remove_entry_secure(source) FileUtils.remove_entry_secure(source)
end end
end end

View File

@ -1,11 +1,16 @@
module Hbc module Hbc
class Container class Container
class Base class Base
def initialize(cask, path, command, nested: false) def initialize(cask, path, command, nested: false, verbose: false)
@cask = cask @cask = cask
@path = path @path = path
@command = command @command = command
@nested = nested @nested = nested
@verbose = verbose
end
def verbose?
@verbose
end end
def extract_nested_inside(dir) def extract_nested_inside(dir)
@ -32,7 +37,7 @@ module Hbc
return false unless container return false unless container
ohai "Extracting nested container #{source.basename}" ohai "Extracting nested container #{source.basename}"
container.new(@cask, source, @command, nested: true).extract container.new(@cask, source, @command, nested: true, verbose: verbose?).extract
true true
end end

View File

@ -13,34 +13,54 @@ module Hbc
print_stderr: false).stdout.empty? print_stderr: false).stdout.empty?
end end
attr_reader :mounts
def initialize(*args)
super(*args)
@mounts = []
end
def extract def extract
mount! mount do |mounts|
assert_mounts_found begin
extract_mounts raise CaskError, "No mounts found in '#{@path}'; perhaps it is a bad DMG?" if mounts.empty?
mounts.each(&method(:extract_mount))
ensure ensure
eject! mounts.each(&method(:eject))
end
end
end end
def mount! def mount
plist = @command.run!("/usr/bin/hdiutil",
# realpath is a failsafe against unusual filenames # realpath is a failsafe against unusual filenames
args: %w[mount -plist -nobrowse -readonly -noidme -mountrandom /tmp] + [Pathname.new(@path).realpath], path = Pathname.new(@path).realpath
input: "y\n")
.plist Dir.mktmpdir do |unpack_dir|
@mounts = mounts_from_plist(plist) cdr_path = Pathname.new(unpack_dir).join("#{path.basename(".dmg")}.cdr")
without_eula = @command.run("/usr/bin/hdiutil",
args: ["attach", "-plist", "-nobrowse", "-readonly", "-noidme", "-mountrandom", unpack_dir, path],
input: "qn\n",
print_stderr: false)
# If mounting without agreeing to EULA succeeded, there is none.
plist = if without_eula.success?
without_eula.plist
else
@command.run!("/usr/bin/hdiutil", args: ["convert", "-quiet", "-format", "UDTO", "-o", cdr_path, path])
with_eula = @command.run!("/usr/bin/hdiutil",
args: ["attach", "-plist", "-nobrowse", "-readonly", "-noidme", "-mountrandom", unpack_dir, cdr_path])
if verbose? && !(eula_text = without_eula.stdout).empty?
ohai "Software License Agreement for '#{path}':"
puts eula_text
end end
def eject! with_eula.plist
@mounts.each do |mount| end
yield mounts_from_plist(plist)
end
end
def eject(mount)
# realpath is a failsafe against unusual filenames # realpath is a failsafe against unusual filenames
mountpath = Pathname.new(mount).realpath mountpath = Pathname.new(mount).realpath
next unless mountpath.exist? return unless mountpath.exist?
begin begin
tries ||= 3 tries ||= 3
@ -60,14 +80,9 @@ module Hbc
retry retry
end end
end end
end
private private
def extract_mounts
@mounts.each(&method(:extract_mount))
end
def extract_mount(mount) def extract_mount(mount)
Tempfile.open(["", ".bom"]) do |bomfile| Tempfile.open(["", ".bom"]) do |bomfile|
bomfile.close bomfile.close
@ -124,10 +139,6 @@ module Hbc
return [] unless plist.respond_to?(:fetch) return [] unless plist.respond_to?(:fetch)
plist.fetch("system-entities", []).map { |e| e["mount-point"] }.compact plist.fetch("system-entities", []).map { |e| e["mount-point"] }.compact
end end
def assert_mounts_found
raise CaskError, "No mounts found in '#{@path}'; perhaps it is a bad DMG?" if @mounts.empty?
end
end end
end end
end end

View File

@ -153,7 +153,7 @@ module Hbc
end end
odebug "Using container class #{container} for #{@downloaded_path}" odebug "Using container class #{container} for #{@downloaded_path}"
container.new(@cask, @downloaded_path, @command).extract container.new(@cask, @downloaded_path, @command, verbose: verbose?).extract
end end
def install_artifacts def install_artifacts

View File

@ -9,11 +9,12 @@ describe Hbc::Container::Dmg, :cask do
Hbc::SystemCommand, Hbc::SystemCommand,
) )
dmg.mount do |mounts|
begin begin
dmg.mount! expect(mounts).not_to include nil
expect(dmg.mounts).not_to include nil
ensure ensure
dmg.eject! mounts.each(&dmg.public_method(:eject))
end
end end
end end
end end