Home | History | Annotate | Download | only in livemedia
      1 #!/usr/bin/bash
      2 #
      3 # CDDL HEADER START
      4 #
      5 # The contents of this file are subject to the terms of the
      6 # Common Development and Distribution License (the "License").
      7 # You may not use this file except in compliance with the License.
      8 #
      9 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
     10 # or http://www.opensolaris.org/os/licensing.
     11 # See the License for the specific language governing permissions
     12 # and limitations under the License.
     13 #
     14 # When distributing Covered Code, include this CDDL HEADER in each
     15 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     16 # If applicable, add the following below this CDDL HEADER, with the
     17 # fields enclosed by brackets "[]" replaced with your own identifying
     18 # information: Portions Copyright [yyyy] [name of copyright owner]
     19 #
     20 # CDDL HEADER END
     21 #
     22 # Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
     23 # Use is subject to license terms.
     24 #
     25 # This script pulls in binaries from various locations and builds
     26 # a complete bootable CD and memory based filesystem image of
     27 # OpenSolaris. Finally it generates an iso image that can be burned
     28 # onto the CDROM to get a bootable OpenSolaris Live DVD.
     29 #
     30 # This script performs the following steps:
     31 #
     32 # 1) Load the configuration file build_live_dvd.conf
     33 #
     34 # 2) Remove the proto directory if it exists. This directory will
     35 #    contain the complete OpenSolaris filesystem image
     36 #
     37 # 3) Install the complete set of packages from a Solaris Express image
     38 #    to the proto area.
     39 #
     40 # 4) Copy lists of files/binaries/directories defined in various
     41 #    packages under the packages directory.
     42 #
     43 # 5) Copy skeleton scripts and configuration files contained in the
     44 #    bootcd_skel directory. These files contain the essential customizations
     45 #    necessary to make our OpenSolaris Live DVD work.
     46 #
     47 # 6) Create our minimal root filesystem image that will be mounted as
     48 #    the ramdisk. This is essentially a file that contains a ufs
     49 #    filesystem image. This file is loaded into memory by grub and is
     50 #    ultimately mounted by the kernel via the ramdisk driver.
     51 #
     52 # 7) Copy a predefined list of files onto our minimal root. The files in
     53 #    copied into this minimal root (ramdisk) are carefully chosen to
     54 #    minimize the size of the miniroot and reduce memory usage. This
     55 #    miniroot contains files that are absolutely necessary to boot till
     56 #    the point where /usr is mounted from the DVD. This split mount
     57 #    is the essential character of a Live DVD.
     58 #
     59 # 8) Create some essential symbolic links in /dev in the miniroot. These
     60 #    are used much before devfsadm can run. In the normal case where Solaris
     61 #    is installed onto a hard disk, the installer executes devfsadm to
     62 #    pre-populate /dev on the hard disk before the newly installed OS boots
     63 #    for the first time. Since this cannot happen with a Live DVD, we need
     64 #    to forcibly create the symlinks here even though /devices is empty. The
     65 #    symlinks will point to valid /devices entries when our Live DVD boots.
     66 #
     67 # 9) Create other necessary symlinks in the miniroot. These include some
     68 #    SMF links that indicate the default inetd service profile.
     69 #
     70 # 10) Gzip the file containing the miniroot. Grub will unzip it when it loads
     71 #     the file into memory. The file is then copied into the default location
     72 #     proto/boot/solaris.
     73 #
     74 # 11) mkisofs is invoked to build a bootable iso image containing the
     75 #     entire contents of our proto directory. Grub's eltorito stage2 bootloader
     76 #     is used, that enables booting directly off a DVD. We violate the ISO9660
     77 #     specs somewhat to accomodate file properties essential for a proper Unix
     78 #     file/directory layout.
     79 #
     80 # 12) If requested, transform the ISO image into a UFS filesystem suitable for
     81 #     copying to a USB storage device, typically flash memory.  This allows
     82 #     creating copies of the USB image to take 10 minutes or so.  The usbcopy
     83 #     script included with this kit is used to copy the image to the USB stick.
     84 
     85 # 
     86 # Load our configuration
     87 #
     88 
     89 source build_live_dvd.conf
     90 source build_live_dvd.lib
     91 
     92 # Set up root of build area
     93 if [ -n $PREFIX_DATASET ]; then
     94 	zfs list $PREFIX_DATASET >/dev/null 2>&1 || zfs create $PREFIX_DATASET
     95 	if [ $? != 0 ] ; then
     96 		echo "Unable to create dataset $PREFIX_DATASET"
     97 		exit 1
     98 	fi
     99 fi	
    100 [ -d $PREFIX ] || mkdir $PREFIX
    101 
    102 (
    103 echo "=== $0 started at `date`"
    104 
    105 #
    106 # Initial sanity check
    107 #
    108 if [ -z "$BOOTCD_PROTO" -o "$BOOTCD_PROTO" = "/" ]; then
    109 	echo "You must specify either PROTO_DATASET or BOOTCD_PROTO in the"
    110 	echo "configuration file.  Aborting."
    111 	exit 1
    112 fi
    113 
    114 soldprodlofi=""
    115 # Config specified an ISO image, mount it up
    116 if [ -n "$SOLPRODUCTISO" ]; then
    117 	solprodlofi=`lofiadm -a $SOLPRODUCTISO`
    118 	if [ $? != 0 ]; then
    119 		echo "Unable to create loopback device for $SOLPRODUCTISO"
    120 		exit 1
    121 	fi
    122 	[ -d $SOLPRODUCT ] || mkdir -p $SOLPRODUCT
    123 	mount -F hsfs $solprodlofi $SOLPRODUCT
    124 fi
    125 
    126 if [ ! -d "$PKGREPOS" ]; then
    127     echo "$SOLPRODUCT is not a Solaris Nevada image!"
    128     umount $SOLPRODUCT
    129     lofiadm -d $solprodlofi
    130     exit 1
    131 fi
    132 
    133 [ -d $TMPDIR ] || mkdir $TMPDIR
    134 
    135 TARGET=/
    136 
    137 cd $PREFIX
    138 
    139 MNT=$PREFIX/bootcd_rootfs
    140 
    141 # If we're configured to use a ZFS dataset, then set it up if necessary
    142 # or figure out which snapshots already exist
    143 NEED_PKGS=true
    144 NEED_POSTRUN=true
    145 NEED_SKELETON=true
    146 if [ -n "$PROTO_DATASET" ]; then
    147 	zfs list $PROTO_DATASET >/dev/null 2>&1 || zfs create $PROTO_DATASET
    148 	zfs set snapdir=hidden $PROTO_DATASET
    149 	PKG_SNAPSHOT=$PROTO_DATASET@pkg
    150 	POSTRUN_SNAPSHOT=$PROTO_DATASET@postrun
    151 	SKELETON_SNAPSHOT=$PROTO_DATASET@skeleton
    152 	zfs list $SKELETON_SNAPSHOT >/dev/null 2>&1 && NEED_SKELETON=false
    153 	zfs list $POSTRUN_SNAPSHOT >/dev/null 2>&1 && NEED_POSTRUN=false
    154 	zfs list $PKG_SNAPSHOT >/dev/null 2>&1 && NEED_PKGS=false
    155 else
    156 	echo "Cleaning up $BOOTCD_PROTO"
    157 	rm -rf $BOOTCD_PROTO
    158 	mkdir $BOOTCD_PROTO
    159 fi
    160 
    161 #
    162 # Minimal directory structure
    163 #
    164 echo "Creating basic directory structure"
    165 mkdirs $BOOTCD_PROTO $LIVEKIT/mkbootcd.files.minimal
    166 
    167 # If we already have the snapshot of this stage, skip
    168 if [ $NEED_PKGS = true ]; then
    169 
    170 	#
    171 	# Generate package list from media
    172 	#
    173 
    174 	# Create admin file for non-interactive pkgadd's
    175 	ADMIN_FILE=$TMPDIR/admin
    176 	cat << \ADMIN_EOF > $ADMIN_FILE
    177 mail=
    178 instance=unique
    179 partial=nocheck
    180 runlevel=nocheck
    181 idepend=nocheck
    182 rdepend=nocheck
    183 space=nocheck
    184 setuid=nocheck
    185 conflict=nocheck
    186 action=nocheck
    187 networktimeout=60
    188 networkretries=3
    189 authentication=quit
    190 keystore=/var/sadm/security
    191 proxy=
    192 basedir=default
    193 ADMIN_EOF
    194 
    195 	echo "Generating ordered package list from $PKGREPOS and installing to $BOOTCD_PROTO"
    196 
    197 	/usr/bin/perl $LIVEKIT/proc_toc.pl SUNWCXall $SOLPRODUCT | /usr/ccs/bin/tsort | grep -v "INFORM: cycle" | grep -v "SUNWdummy" > $TMPDIR/ordered
    198 	perl $LIVEKIT/rev_file.pl $TMPDIR/ordered | while read pkg
    199 	do
    200 		if [ -d $PKGREPOS/$pkg ]
    201 		then
    202 			pkgadd -n -a $ADMIN_FILE -d $PKGREPOS -R $BOOTCD_PROTO $pkg
    203 		else
    204 			pkgi="${pkg}.i"
    205 			if [ -d $PKGREPOS/$pkgi ]
    206 			then
    207 				pkgadd -n -a $ADMIN_FILE -d $PKGREPOS -R $BOOTCD_PROTO $pkgi
    208 			fi
    209 		fi
    210 		if [[ $? -ne 0 ]]
    211 		then
    212 			echo "******* Install of $pkg failed *******"
    213 		fi
    214 	done
    215 
    216         # Install Developer Tools if present and requested
    217         if [ "$INSTALL_DEVTOOLS" = true -a  -x $SOLPRODUCT/DeveloperTools/install_devtools.sh ]
    218         then
    219                 $SOLPRODUCT/DeveloperTools/install_devtools.sh -R $BOOTCD_PROTO
    220         fi
    221 
    222 	# Save snapshot if possible to skip this on next build
    223 	[ -n "$PKG_SNAPSHOT" ] && zfs snapshot $PKG_SNAPSHOT
    224 fi
    225 
    226 # Unmount the ISO if specified
    227 if [ -n "$SOLPRODUCTISO" ]; then
    228 	umount $SOLPRODUCT
    229 	lofiadm -d $solprodlofi
    230 fi
    231 
    232 if [ $NEED_SKELETON = true ]; then
    233 	[ -n "$PKG_SNAPSHOT" ] && zfs rollback $PKG_SNAPSHOT
    234 	#
    235 	# Copy extra binaries from various packages including
    236 	# Free and Open Source software packages
    237 	#
    238 	# This loop goes through all the subdirectories of PACKAGEDIR
    239 	# if the subdirectory is mentioned in PACKAGEDIR/buildpkg.list
    240 	# then that package has been installed in TARGET
    241 	# and the binaries should be transferred from TARGET to BOOTCD_PROTO/TARGET.
    242 	# Otherwise the package binaries are in the same subdirectory
    243 	# of TARGET/<package> and should be transferred to BOOTCD_PROTO.
    244 	#
    245 	echo "Copying Package files"
    246 	
    247 	#
    248 	# Minimal package registry
    249 	#
    250 	mkdir -p $BOOTCD_PROTO/pkgs
    251 	
    252 	for d in `cat $PACKAGEDIR/cdpkg.list`
    253 	do
    254 	    # If package includes an installation script, use it
    255 	    if [[ -x $PACKAGEDIR/$d/install.live ]]; then
    256 		echo $d
    257 		$PACKAGEDIR/$d/install.live $PACKAGEDIR/$d $BOOTCD_PROTO
    258 		continue
    259 	    fi
    260 	    # Install using file list
    261 	    flist=""
    262 	    if [[ -f "$PACKAGEDIR/$d/${d}.files.livecd" ]]
    263 	    then
    264 		flist="$PACKAGEDIR/$d/${d}.files.livecd"
    265 	
    266 	    elif [[ -f "$PACKAGEDIR/$d/${d}.files" ]]
    267 	    then
    268 		flist="$PACKAGEDIR/$d/${d}.files"
    269 	    fi
    270 	
    271 	    if [[ "x$flist" != "x"  ]]
    272 	    then
    273 		echo $d
    274 		grep "^$d/" $PACKAGEDIR/buildpkg.list > /dev/null
    275 		if [ $? -ne 0 ]
    276 		then
    277 		    mkdir -p "$BOOTCD_PROTO/pkgs/$d"
    278 		    cp "$flist" "$BOOTCD_PROTO/pkgs/$d"
    279 	
    280 		    if [ -f "$PACKAGEDIR/$d/installprefix" ]
    281 		    then
    282 			pref=`cat "$PACKAGEDIR/$d/installprefix"`
    283 			copyfiles "$PACKAGEDIR/$d" "$BOOTCD_PROTO/$pref" "$flist"
    284 		    else
    285 			copyfiles "$PACKAGEDIR/$d" "$BOOTCD_PROTO" "$flist"
    286 		    fi
    287 		else
    288 		    mkdir -p "$BOOTCD_PROTO/pkgs/$d"
    289 		    cp "$flist" "$BOOTCD_PROTO/pkgs/$d"
    290 	
    291 		    if [ -f "$PACKAGEDIR/$d/installprefix" ]
    292 		    then
    293 			pref=`cat "$PACKAGEDIR/$d/installprefix"`
    294 			copyfiles "$TARGET" "$BOOTCD_PROTO/$pref" "$flist"
    295 		    else
    296 			copyfiles "$TARGET" "$BOOTCD_PROTO/$TARGET" "$flist"
    297 		    fi
    298 		fi
    299 	    fi
    300 	done
    301 	
    302 	#
    303 	# Copy all the basic customizations required for the Live DVD to
    304 	# work. These are called the skeleton customisation files.
    305 	#
    306 	cd $LIVEKIT
    307 	echo "Copying skeleton files"
    308 	# First save the originals for use in installation
    309 	while read t m p f; do
    310 		[ -f $BOOTCD_PROTO/$f ] && echo $f
    311 	done <$BOOTCD_SKEL/bootcd_skel.files | (cd $BOOTCD_PROTO; cpio -o -O skeleton.cpio)
    312 	# Now copy skeleton into place
    313 	copyfiles "$BOOTCD_SKEL" "$BOOTCD_PROTO" $BOOTCD_SKEL/bootcd_skel.files
    314 	
    315 	#
    316 	# Remove basic registration files from GNOME login session
    317 	# Does not make much sense in a LiveDVD and is a perf hog
    318 	#
    319 	rm ${BOOTCD_PROTO}/usr/dt/config/Xsession.d/1001.swupnot
    320 	rm ${BOOTCD_PROTO}/usr/dt/config/Xsession.d/1099.br
    321 	
    322 	# Copy installer into place
    323 	pkgadd -n -R $BOOTCD_PROTO -d $LIVEKIT/SUNWgui-install.pkg SUNWgui-install
    324 	cd $BOOTCD_PROTO/usr/share/gui-install
    325 	bzip2 -dc $LIVEKIT/gui-install-dummy-txt.tar.bz2 | tar xf -
    326 	cd $LIVEKIT
    327 	cp $LIVEKIT/dummy_install $BOOTCD_PROTO/usr/bin
    328 
    329 	[ -n "$SKELETON_SNAPSHOT" ] && zfs snapshot $SKELETON_SNAPSHOT
    330 fi
    331 
    332 #
    333 # Pre-configure Gnome databases and SMF repository
    334 # 
    335 if [ $NEED_POSTRUN = false ]; then
    336 	zfs rollback -r $POSTRUN_SNAPSHOT
    337 else
    338 	[ -n "$SKELETON_SNAPSHOT" ] && zfs rollback -r $SKELETON_SNAPSHOT
    339 
    340 	echo "Configuring Gnome"
    341 	[ -x $BOOTCD_PROTO/var/lib/postrun/postrun-runq ] && chroot $BOOTCD_PROTO /var/lib/postrun/postrun-runq
    342 
    343 	echo "Creating font cache"
    344 	[ -x $BOOTCD_PROTO/usr/bin/fc-cache ] && chroot $BOOTCD_PROTO /usr/bin/fc-cache --force
    345 
    346 	echo "Preloading SMF repository"
    347 	export LIVEKIT
    348 	$LIVEKIT/mkrepo $BOOTCD_PROTO
    349 
    350 	[ -n "$POSTRUN_SNAPSHOT" ] && zfs snapshot $POSTRUN_SNAPSHOT
    351 fi
    352 
    353 #
    354 # Create the boot archive. This is a UFS filesystem image in a file
    355 # that is loaded into RAM by Grub. A file is created using mkfile
    356 # and is added as a block device using lofiadm. newfs is then used
    357 # to create a UFS filesystem on the lofi device and then it is
    358 # mounted and all the files required for a minimal root fs are
    359 # copied.
    360 #
    361 echo "Initializing Boot Archive"
    362 
    363 rm -f ${BOOT_ARCHIVE}
    364 /usr/sbin/mkfile ${RAMDISK_SIZE}k $BOOT_ARCHIVE
    365 
    366 lofidev=`/usr/sbin/lofiadm -a $BOOT_ARCHIVE`
    367 if [ $? != 0 ] ; then
    368     echo "Unable to create loopback device for $BOOT_SARCHIVE"
    369     exit 2
    370 fi
    371           
    372 rlofidev=`echo $lofidev | sed s/lofi/rlofi/`
    373 newfs -m 0 $rlofidev < /dev/null 2> /dev/null
    374 [ -d $MNT ] || mkdir $MNT
    375 mount -o nologging $lofidev $MNT
    376 rmdir ${MNT}/lost+found
    377 
    378 echo "Copying files to Boot Archive"
    379 cd $LIVEKIT
    380 copyfiles "$BOOTCD_PROTO" "$MNT" `pwd`/mkbootcd.files.minimal
    381 
    382 #
    383 # Additional /var /etc setup. Putting these in the ramdisk will
    384 # increase ramdisk size substantially, so these are left on the
    385 # cd with symlinks from the ramdisk.
    386 #
    387 # Ideally these should be in another compressed file mounted via
    388 # lofi to conserve space and get a big performance increase. 
    389 #
    390 cd ${MNT}/etc
    391 ln -sf /.cdrom/etc/gtk
    392 ln -sf /.cdrom/etc/gtk-2.0
    393 ln -sf /.cdrom/etc/cacao
    394 ln -sf /.cdrom/etc/lu
    395 ln -sf /.cdrom/etc/usb
    396 ln -sf /.cdrom/etc/orbitrc
    397 ln -sf /.cdrom/etc/gconf
    398 ln -sf /.cdrom/etc/gnome-vfs-2.0
    399 ln -sf /.cdrom/etc/gnome-vfs-mime-magic
    400 ln -sf /.cdrom/etc/gnopernicus-1.0
    401 ln -sf /.cdrom/etc/gimp
    402 ln -sf /.cdrom/etc/wgetrc
    403 ln -sf /.cdrom/etc/sfw
    404 ln -sf /.cdrom/etc/scrollkeeper.conf
    405 ln -sf /.cdrom/etc/sound
    406 ln -sf /.cdrom/etc/esd.conf
    407 ln -sf /.cdrom/etc/xml
    408 ln -sf /.cdrom/etc/xpdfrc
    409 ln -sf /.cdrom/etc/xdg
    410 
    411 cd ${MNT}/var/sadm
    412 ln -s /.cdrom/var/sadm/install
    413 ln -s /.cdrom/var/sadm/install_data
    414 ln -s /.cdrom/var/sadm/wbem
    415 ln -s /.cdrom/var/sadm/system
    416 ln -s /.cdrom/var/sadm/spool
    417 ln -s /.cdrom/var/sadm/softinfo
    418 
    419 cd ${MNT}/var
    420 ln -s /.cdrom/var/cc-ccr
    421 
    422 echo "$VOLUMEID" > $MNT/.volumeid
    423 chmod 0444 $MNT/.volumeid
    424 chown root:root $MNT/.volumeid
    425 
    426 #
    427 # Unmount the lofi device and remove it. Then gzip the file
    428 # containing the root fs image. Grub will decompress it while
    429 # loading.
    430 #
    431 echo "Archiving Boot Archive"
    432 
    433 cd $PREFIX
    434 lockfs -f $MNT
    435 umount $MNT
    436 rmdir $MNT
    437 lofiadm -d $BOOT_ARCHIVE
    438  
    439 cd $PREFIX
    440 
    441 rm -f ${BOOT_ARCHIVE}.gz
    442 gzip -f $BOOT_ARCHIVE
    443 mv ${BOOT_ARCHIVE}.gz $BOOT_ARCHIVE
    444 chmod a+r $BOOT_ARCHIVE
    445 
    446 if [[ "x$1" = "x-nocd" ]]
    447 then
    448     exit 0
    449 fi
    450 
    451 cd "$BOOTCD_PROTO"
    452 
    453 echo "Generating usr filesystem image"
    454 if [ -f $LIVEKIT/iso.sort ]; then
    455         mkisofs -o solaris -sort $LIVEKIT/iso.sort -N -l -R -U -allow-multidot -no-iso-translate -cache-inodes -d -D -V "compress" usr
    456 else
    457         mkisofs -o solaris -N -l -R -U -allow-multidot -no-iso-translate -cache-inodes -d -D -V "compress" usr
    458 fi
    459 rm -rf usr
    460 
    461 echo "Compressing usr filesystem image"
    462 time $LIVEKIT/packages/clofi/lcompress solaris 65536 2048
    463 rm solaris
    464 
    465 echo "Generating opt filesystem image"
    466 mkisofs -o solarisopt -N -l -R -U -allow-multidot -no-iso-translate -cache-inodes -d -D -V "compress" opt
    467 rm -rf opt
    468 
    469 echo "Compressing opt filesystem image"
    470 time $LIVEKIT/packages/clofi/lcompress solarisopt 65536 2048
    471 rm solarisopt
    472 
    473 echo "Generating var/sadm/pkg filesystem image"
    474 mkisofs -o solarispkg -N -l -R -U -allow-multidot -no-iso-translate -cache-inodes -d -D -V "compress" var/sadm/pkg
    475 rm -rf var/sadm/pkg/*
    476 
    477 echo "Compressing var/sadm/pkg filesystem image"
    478 time $LIVEKIT/packages/clofi/lcompress solarispkg 65536 2048
    479 rm solarispkg
    480 
    481 cd $PREFIX
    482 echo "Making final ISO image"
    483 rm -f $ISO_FILE
    484 
    485 mkisofs -o $ISO_FILE -b boot/grub/stage2_eltorito -c .catalog -no-emul-boot -boot-load-size 4 -boot-info-table -N -l -R -U -allow-multidot -no-iso-translate -cache-inodes -d -D -V "$VOLUMEID" "$BOOTCD_PROTO"
    486 
    487 echo "ISO creation completed at `date`"
    488 
    489 cd $LIVEKIT
    490 
    491 # Generate USB image if requested
    492 [ "$GEN_USB_IMG" = "true" ] && $LIVEKIT/usbgen
    493 
    494 echo "=== $0 completed at `date`"
    495 exit 0
    496 
    497 ) 2>&1 | tee $PREFIX/$0.log
    498