#!/usr/bin/perl -w # # Do-pkg - convert a binary distribution into a Mac OS X PKG and put it # inside a Disk Image (.dmg) # # The script currently assumes the following environment (which should exist # like that, if the Do-compile script was used to build the binary # distribution) # # - there must be a binary distribution (*.tar.gz) in the directory # `hostname` of the current directory # - the extracted and compiled source tree should be located in the # `hostname` directory, too # # Use the "--help" option for more info! # # written by Lenz Grimmer # use Getopt::Long; Getopt::Long::Configure ("bundling"); $opt_dry_run= undef; $opt_help= undef; $opt_log= undef; $opt_mail= ""; $opt_skip_dmg= undef; $opt_suffix= undef; $opt_verbose= undef; $opt_version= undef; GetOptions( "dry-run", "help|h", "log|l:s", "mail|m=s", "skip-dmg|skip-disk-image|s", "suffix=s", "verbose|v", "version=s", ) || &print_help; # Include helper functions chomp($PWD= `pwd`); $LOGGER= "$PWD/logger.pm"; if (-f "$LOGGER") { do "$LOGGER"; } else { die "ERROR: $LOGGER cannot be found!\n"; } $PM= "/Developer/Applications/PackageMaker.app/Contents/MacOS/PackageMaker"; $TMP= $ENV{TMPDIR}; $TMP eq "" ? $TMP= $TMP . "/PKGBUILD": $TMP= "/tmp/PKGBUILD"; $PKGROOT= "$TMP/PMROOT"; $PKGDEST= "$TMP/PKG"; $RESOURCE_DIR= "$TMP/Resources"; $SUFFIX= $opt_suffix; $VERSION= $opt_version; ($MAJOR, $MINOR, $RELEASE)= split(/\./, $VERSION); $NAME= "mysql$SUFFIX-$VERSION"; chomp($HOST= `hostname`); chomp($ID= `whoami`); $HOST=~ /^([^.-]*)/; $HOST= $1; $LOGFILE= "$PWD/Logs/$HOST-$MAJOR.$MINOR$SUFFIX.log"; $BUILDDIR= "$PWD/$HOST"; $SRCBASEDIR= <$BUILDDIR/mysql*-$VERSION>; $SUPFILEDIR= <$SRCBASEDIR/support-files/MacOSX>; $TAR= <$BUILDDIR/$NAME-apple-darwin*-powerpc.tar.gz>; $INFO= <$SUPFILEDIR/Info.plist>; $DESC= <$SUPFILEDIR/Description.plist>; @RESOURCES= qw/ ReadMe.txt postinstall preinstall /; @LICENSES= ("$SRCBASEDIR/COPYING","$SRCBASEDIR/MySQLEULA.txt"); &print_help("") if ($opt_help || !$opt_suffix || !$opt_version); # # Override predefined Log file name # if (defined $opt_log) { if ($opt_log ne "") { if ($opt_log =~ /^\/.*/) { $LOGFILE= $opt_log; } else { $LOGFILE= $PWD . "/" . $opt_log; } } } # Creating the UFS disk image requires root privileges die("You must be root to run this script!") if ($ID ne "root" && !$opt_dry_run); foreach $file ($TAR, $INFO, $DESC) { &abort("Unable to find $file!") unless (-f "$file"); } # Remove old temporary build directories first &logger("Cleaning up temporary build directories"); &run_command("rm -rf $TMP", "Could not clean up $TMP!"); &logger("Creating temp directories"); foreach $dir ($TMP, $PKGROOT, $PKGDEST, $RESOURCE_DIR) { if (!-d $dir) { &run_command("mkdir $dir", "Could not make directory $dir!"); } } foreach $resfile (@RESOURCES) { $command= "cp $SUPFILEDIR/$resfile $RESOURCE_DIR"; &run_command($command, "Error while copying $SUPFILEDIR/$resfile to $RESOURCE_DIR"); } # Search for license file foreach $license (@LICENSES) { if (-f "$license") { $command= "cp $license $RESOURCE_DIR/License.txt"; &run_command($command, "Error while copying $license to $RESOURCE_DIR"); } } &abort("Could not find a license file!") unless (-f "$RESOURCE_DIR/License.txt"); # Extract the binary tarball and create the "mysql" symlink &logger("Extracting $TAR to $PKGROOT"); &run_command("gnutar zxf $TAR -C $PKGROOT", "Unable to extract $TAR!"); &run_command("cd $PKGROOT ; ln -s mysql* ./mysql", "Unable to create symlink!"); &run_command("chown -R root.wheel $PKGROOT/*", "Cannot chown $PKGROOT!"); # Now build the PGK using PackageMaker # The "|| true" is a nasty hack to work around a problem with Package Maker # returning a non-zero value, even though the package was created correctly &logger("Running PackageMaker"); $command= "$PM -build -p $PKGDEST/$NAME.pkg -f $PKGROOT -r $RESOURCE_DIR -i $INFO -d $DESC || true"; &run_command($command, "Error while building package!"); &logger("Removing $PKGROOT"); &run_command("rm -rf $PKGROOT", "Unable to remove $PKGROOT!"); if ($opt_skip_dmg) { &logger("SUCCESS: Package $PKGDEST/$NAME.pkg created"); exit 0; } # Determine the size of the Disk image to be created and add a 5% safety # margin for filesystem overhead &logger("Determining required disk image size for $PKGDEST"); if (! $opt_dry_run) { chomp($_= `du -sk $PKGDEST`); @size= split(); $size= int($size[0]+($size[0]*0.05)); &logger("Disk image size: $size KB"); } &abort("Zero bytes? Something is wrong here!") if ($size == 0); # Now create and mount the disk image $TMPNAME= $NAME . ".tmp"; &logger("Creating temporary Disk image $TMPNAME.dmg"); $command= "hdiutil create $TMPNAME -size ${size}k -ov -fs UFS -volname $NAME"; &run_command($command, "Unable to create disk image $TMPNAME.dmg!"); &logger("Attaching Disk image $TMPNAME.dmg"); &run_command("hdid $TMPNAME.dmg", "Unable to attach $TMPNAME.dmg!"); # Install the PKG into the .dmg chomp($mountpoint=`mount | grep "\/Volumes\/$NAME" | cut -f3 -d" "`) if (!$opt_dry_run); &logger("Copying $PKGDEST/$NAME.pkg to Disk image /Volumes/$NAME"); &run_command("ditto $PKGDEST /Volumes/$NAME", "Could not copy $PKGDEST to /Volumes/$NAME!"); &run_command("ditto $RESOURCE_DIR/ReadMe.txt /Volumes/$NAME", "Could not copy $RESOURCE_DIR/ReadMe.txt to /Volumes/$NAME!"); chomp($mountpoint=`mount | grep "\/Volumes\/$NAME" | cut -f1 -d" "`) if (!$opt_dry_run); &abort("/Volumes/$NAME not attached!") if (!$mountpoint && !$opt_dry_run); &logger("Unmounting $mountpoint"); &run_command("hdiutil detach $mountpoint", "Unable to detach $mountpoint"); &run_command("rm -f $NAME.dmg", "Unable to remove $NAME.dmg!") if (-f "$NAME.dmg"); &logger("Compressing disk image"); $command= "hdiutil convert $TMPNAME.dmg -format UDZO -imagekey zlib-level=9 -o $NAME.dmg"; &run_command($command, "Unable to compress disk image!"); # Final cleanups &logger("Removing $TMPNAME.dmg"); &run_command("rm -f $TMPNAME.dmg", "Unable to remove $TMPNAME.dmg!"); &logger("Removing $TMP"); &run_command("rm -rf $TMP", "Unable to remove $TMP!"); &logger("SUCCESS: $NAME.dmg created.") if (!$opt_dry_run); exit 0; sub print_help { my $message= $_[0]; if ($message ne "") { print "\n"; print "ERROR: $message\n"; } print < --suffix= --version= Creates a Mac OS X installation package (PKG) and stores it inside a Disk Image (.dmg) file. You need to create a binary distribution tarball with scripts/make_binary_distribution first! NOTE: You need to run this script with root privileges (required to create the disk image) Options: --dry-run Dry run without executing -h, --help Print this help -l, --log[=] Write a log file [to ] (default is "$LOGFILE") -m, --mail=
Mail a failure report to the given address (and include a log file snippet, if logging is enabled) Note that the \@-Sign needs to be quoted! Example: --mail=user\\\@domain.com -s, --skip-disk-image Just build the PKG, don't put it into a disk image afterwards --suffix= The package suffix (e.g. "-standard" or "-pro) --version= The MySQL version number (e.g. 4.0.11-gamma) -v, --verbose Verbose execution EOF exit 1; }