Do-pkg 6.29 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11
#!/usr/bin/perl -w
#
# Do-pkg - convert a binary distribution into a Mac OS X PKG and put it
# inside a Disk Image (.dmg)
#
# Use the "--help" option for more info!
#
# written by Lenz Grimmer <lenz@mysql.com>
#

use Getopt::Long;
12
Getopt::Long::Configure ("bundling");
13

14
$opt_dry_run= undef;
15
$opt_help= undef;
16 17
$opt_log= undef;
$opt_mail= "";
18
$opt_suffix= undef;
19
$opt_verbose= undef;
20 21 22
$opt_version= undef;

GetOptions(
23
	"dry-run",
24
	"help|h",
25 26
	"log|l:s",
	"mail|m=s",
27
	"suffix=s",
28
	"verbose|v",
29 30 31
	"version=s",
) || &print_help;

32 33 34 35 36 37 38 39 40 41 42
# Include helper functions
chomp($PWD= `pwd`);
$LOGGER= "$PWD/logger.pm";
if (-f $LOGGER)
{
	do "$LOGGER";
}
else
{
	die "ERROR: $LOGGER cannot be found!\n";
}
43 44 45 46 47 48 49 50

$PM= "/Developer/Applications/PackageMaker.app/Contents/MacOS/PackageMaker";
$TMP= "/tmp/PKGBUILD";
$PKGROOT= "$TMP/PMROOT";
$PKGDEST= "$TMP/PKG";
$RESOURCE_DIR= "$TMP/Resources";
$SUFFIX= $opt_suffix;
$VERSION= $opt_version;
51
($MAJOR, $MINOR, $RELEASE)= split(/\./, $VERSION);
52 53
$NAME= "mysql$SUFFIX-$VERSION";
chomp($HOST= `hostname`);
54
chomp($ID= `whoami`);
55 56
$HOST=~ /^([^.-]*)/;
$HOST= $1;
57 58
$LOGFILE= "$PWD/Logs/$HOST-$MAJOR.$MINOR$SUFFIX.log";
$BUILDDIR= "$PWD/$HOST";
59 60 61 62 63 64
$SUPFILEDIR= <$BUILDDIR/mysql*-$VERSION/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 /;

65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
&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;
		}
	}
}
84 85

# Creating the UFS disk image requires root privileges
86
die("You must be root to run this script!") if ($ID ne "root" && !$opt_dry_run);
87 88 89

foreach $file ($TAR, $INFO, $DESC)
{
90
	&abort("Unable to find $file!") if (!-f $file);
91 92 93
}

# Remove old temporary build directories first
94 95 96
&logger("Cleaning up temporary build directories");
&run_command("rm -rf $TMP", "Could not clean up $TMP!");
&logger("Creating temp directories");
97 98 99 100
foreach $dir ($TMP, $PKGROOT, $PKGDEST, $RESOURCE_DIR)
{
	if (!-d $dir)
	{
101
		&run_command("mkdir $dir", "Could not make directory $dir!");
102 103 104 105 106
	}
}

foreach $resfile (@RESOURCES)
{
107 108
	$command= "cp $SUPFILEDIR/$resfile $RESOURCE_DIR";
	&run_command($command, "Error while copying $SUPFILEDIR/$resfile to $RESOURCE_DIR");
109 110 111
}

# Extract the binary tarball and create the "mysql" symlink
112 113 114 115
&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!");
116 117

# Now build the PGK using PackageMaker
118 119 120 121 122
# 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!");
123

124 125
&logger("Removing $PKGROOT");
&run_command("rm -rf $PKGROOT", "Unable to remove $PKGROOT!");
126 127 128

# Determine the size of the Disk image to be created and add a 5% safety
# margin for filesystem overhead
129 130 131 132 133 134 135 136
&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");
}
137

138
&abort("Zero bytes? Something is wrong here!") if ($size == 0);
139 140 141

# Now create and mount the disk image
$TMPNAME= $NAME . ".tmp";
142 143 144 145 146
&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!");
147 148

# Install the PKG into the .dmg
149 150 151 152 153 154 155 156 157 158 159 160
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!");
161 162

# Final cleanups
163 164 165 166
&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!");
167

168
&logger("SUCCESS: $NAME.dmg created.") if (!$opt_dry_run);
169 170 171 172
exit 0;

sub print_help
{
173 174 175 176 177 178
	my $message= $_[0];
	if ($message ne "")
	{
		print "\n";
		print "ERROR: $message\n";
	}
179 180
	print <<EOF;

181
Usage: Do-pkg <options> --suffix=<suffix> --version=<version>
182 183 184 185 186 187 188 189 190 191

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:

192
    --dry-run                 Dry run without executing
193
-h, --help                    Print this help
194 195 196 197 198 199 200
-l, --log[=<filename>]        Write a log file [to <filename>]
                              (default is "$LOGFILE")
-m, --mail=<address>          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
201 202
    --suffix=<suffix>         The package suffix (e.g. "-standard" or "-pro)
    --version=<version>       The MySQL version number (e.g. 4.0.11-gamma)
203
-v, --verbose                 Verbose execution
204 205 206 207

EOF
	exit 1;
}