bug 498500 - Mac DMG unpackaging is unreliable, r=ted
authorRobert Kaiser <kairo@kairo.at>
Mon, 06 Jul 2009 18:13:57 +0200
changeset 30010 33475a1b57461caa594985eca52d59868abad515
parent 30009 e83a66661e8c87b6be68b81843e64d11d05d84c9
child 30011 0471fa063e439ae93a490d4cbfcc823d64a76ec8
child 30041 a5dfd04812d820e905a1847dc7a4283cb3562c28
push idunknown
push userunknown
push dateunknown
reviewersted
bugs498500
milestone1.9.2a1pre
bug 498500 - Mac DMG unpackaging is unreliable, r=ted
build/package/mac_osx/installdmg.ex
build/package/mac_osx/unpack-diskimage
toolkit/mozapps/installer/packager.mk
deleted file mode 100644
--- a/build/package/mac_osx/installdmg.ex
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/usr/bin/expect
-# ***** BEGIN LICENSE BLOCK *****
-# Version: MPL 1.1/GPL 2.0/LGPL 2.1
-#
-# The contents of this file are subject to the Mozilla Public License Version
-# 1.1 (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-# http://www.mozilla.org/MPL/
-#
-# Software distributed under the License is distributed on an "AS IS" basis,
-# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-# for the specific language governing rights and limitations under the
-# License.
-#
-# The Original Code is Mozilla Corporation Code.
-#
-# The Initial Developer of the Original Code is
-# Clint Talbert.
-# Portions created by the Initial Developer are Copyright (C) 2007
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-#  Armen Zambrano Gasparnian <armenzg@mozilla.com>
-#  Axel Hecht <l10n@mozilla.com>
-#
-# Alternatively, the contents of this file may be used under the terms of
-# either the GNU General Public License Version 2 or later (the "GPL"), or
-# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-# in which case the provisions of the GPL or the LGPL are applicable instead
-# of those above. If you wish to allow use of your version of this file only
-# under the terms of either the GPL or the LGPL, and not to allow others to
-# use your version of this file under the terms of the MPL, indicate your
-# decision by deleting the provisions above and replace them with the notice
-# and other provisions required by the GPL or the LGPL. If you do not delete
-# the provisions above, a recipient may use your version of this file under
-# the terms of any one of the MPL, the GPL or the LGPL.
-#
-# ***** END LICENSE BLOCK *****
-spawn hdiutil attach -readonly -mountroot /tmp -private -noautoopen $argv
-expect {
-"byte" {send "G"; exp_continue}
-"END" {send "\r"; exp_continue}
-"Y/N?" {send "Y\r"; exp_continue}
-}
new file mode 100755
--- /dev/null
+++ b/build/package/mac_osx/unpack-diskimage
@@ -0,0 +1,88 @@
+#!/bin/bash
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the installdmg.sh script from taols utilities
+#
+# The Initial Developer of the Original Code is
+# Mozilla Corporation.
+# Portions created by the Initial Developer are Copyright (C) 2009
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#  Chris AtLee <catlee@mozilla.com>
+#  Robert Kaiser <kairo@kairo.at>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+# Unpack a disk image to a specified target folder
+#
+# Usage: unpack-diskimage <image_file>
+#                         <mountpoint>
+#                         <target_path>
+
+DMG_PATH=$1
+MOUNTPOINT=$2
+TARGETPATH=$3
+
+# How long to wait before giving up waiting for the mount to finish (seconds)
+TIMEOUT=90
+
+# If mnt already exists, then the previous run may not have cleaned up
+# properly.  We should try to umount and remove the mnt directory.
+if [ -d $MOUNTPOINT ]; then
+    echo "mnt already exists, trying to clean up"
+    hdiutil detach $MOUNTPOINT -force
+    rm -rdfv $MOUNTPOINT
+fi
+
+# Install an on-exit handler that will unmount and remove the '$MOUNTPOINT' directory
+trap "{ if [ -d $MOUNTPOINT ]; then hdiutil detach $MOUNTPOINT -force; rm -rdfv $MOUNTPOINT; fi; }" EXIT
+
+mkdir -p $MOUNTPOINT
+
+hdiutil attach -verbose -noautoopen -mountpoint $MOUNTPOINT "$DMG_PATH"
+# Wait for files to show up
+# hdiutil uses a helper process, diskimages-helper, which isn't always done its
+# work by the time hdiutil exits. So we wait until something shows up in the
+# mnt directory. Due to the async nature of diskimages-helper, the best thing
+# we can do is to make sure the glob() rsync is making can find files.
+i=0
+while [ "$(echo $MOUNTPOINT/*)" == "$MOUNTPOINT/*" ]; do
+    if [ $i -gt $TIMEOUT ]; then
+        echo "No files found, exiting"
+        exit 1
+    fi
+    sleep 1
+    i=$(expr $i + 1)
+done
+# Now we can copy everything out of the $MOUNTPOINT directory into the target directory
+rsync -av $MOUNTPOINT/* $MOUNTPOINT/.DS_Store $MOUNTPOINT/.background $MOUNTPOINT/.VolumeIcon.icns $TARGETPATH/.
+hdiutil detach $MOUNTPOINT
+rm -rdf $MOUNTPOINT
+# diskimage-helper prints messages to stdout asynchronously as well, sleep
+# for a bit to ensure they don't disturb following commands in a script that
+# might parse stdout messages
+sleep 5
--- a/toolkit/mozapps/installer/packager.mk
+++ b/toolkit/mozapps/installer/packager.mk
@@ -146,36 +146,30 @@ ifdef UNIVERSAL_BINARY
 STAGEPATH = universal/
 endif
 ifndef PKG_DMG_SOURCE
 PKG_DMG_SOURCE = $(STAGEPATH)$(MOZ_PKG_DIR)
 endif
 MAKE_PACKAGE	= $(_ABS_MOZSRCDIR)/build/package/mac_osx/pkg-dmg \
   --source "$(PKG_DMG_SOURCE)" --target "$(PACKAGE)" \
   --volname "$(MOZ_APP_DISPLAYNAME)" $(PKG_DMG_FLAGS)
+_ABS_DIST = $(call core_abspath,$(DIST))
 UNMAKE_PACKAGE	= \
   set -ex; \
-  function cleanup() { \
-    hdiutil detach $${DEV_NAME} || \
-     { sleep 5 && hdiutil detach $${DEV_NAME} -force; }; \
-    return $$1 && $$?; \
-  }; \
-  unset NEXT_ROOT; \
-  export PAGER=true; \
-  expect $(_ABS_MOZSRCDIR)/build/package/mac_osx/installdmg.ex $(UNPACKAGE) | tee hdi.output; \
-  DEV_NAME=`perl -n -e 'if($$_=~/(\/dev\/disk[^ ]*)/) {print $$1."\n";exit;}'< hdi.output`; \
-  MOUNTPOINT=`perl -n -e 'split(/\/dev\/disk[^ ]*/,$$_,2);if($$_[1]=~/(\/.[^\r]*)/) {print $$1;exit;}'< hdi.output` || cleanup 1; \
-  rsync -a "$${MOUNTPOINT}/$(_APPNAME)" $(MOZ_PKG_DIR) || cleanup 1; \
+  rm -rf $(_ABS_DIST)/unpack.tmp; \
+  mkdir -p $(_ABS_DIST)/unpack.tmp; \
+  $(_ABS_MOZSRCDIR)/build/package/mac_osx/unpack-diskimage $(UNPACKAGE) /tmp/$(MOZ_PKG_APPNAME)-unpack $(_ABS_DIST)/unpack.tmp; \
+  rsync -a "$(_ABS_DIST)/unpack.tmp/$(_APPNAME)" $(MOZ_PKG_DIR); \
   test -n "$(MOZ_PKG_MAC_DSSTORE)" && \
-    { rsync -a "$${MOUNTPOINT}/.DS_Store" "$(MOZ_PKG_MAC_DSSTORE)" || cleanup 1; }; \
+    rsync -a "$(_ABS_DIST)/unpack.tmp/.DS_Store" "$(MOZ_PKG_MAC_DSSTORE)"; \
   test -n "$(MOZ_PKG_MAC_BACKGROUND)" && \
-    { rsync -a "$${MOUNTPOINT}/.background/`basename "$(MOZ_PKG_MAC_BACKGROUND)"`" "$(MOZ_PKG_MAC_BACKGROUND)" || cleanup 1; }; \
+    rsync -a "$(_ABS_DIST)/unpack.tmp/.background/`basename "$(MOZ_PKG_MAC_BACKGROUND)"`" "$(MOZ_PKG_MAC_BACKGROUND)"; \
   test -n "$(MOZ_PKG_MAC_ICON)" && \
-    { rsync -a "$${MOUNTPOINT}/.VolumeIcon.icns" "$(MOZ_PKG_MAC_ICON)" || cleanup 1; }; \
-  cleanup 0; \
+    rsync -a "$(_ABS_DIST)/unpack.tmp/.VolumeIcon.icns" "$(MOZ_PKG_MAC_ICON)"; \
+  rm -rf $(_ABS_DIST)/unpack.tmp; \
   if test -n "$(MOZ_PKG_MAC_RSRC)" ; then \
     cp $(UNPACKAGE) $(MOZ_PKG_APPNAME).tmp.dmg && \
     hdiutil unflatten $(MOZ_PKG_APPNAME).tmp.dmg && \
     { /Developer/Tools/DeRez -skip plst -skip blkx $(MOZ_PKG_APPNAME).tmp.dmg > "$(MOZ_PKG_MAC_RSRC)" || { rm -f $(MOZ_PKG_APPNAME).tmp.dmg && false; }; } && \
     rm -f $(MOZ_PKG_APPNAME).tmp.dmg; \
   fi; \
   $(NULL)
 # The plst and blkx resources are skipped because they belong to each