Livecd-make
From ElphelWiki
Revision as of 12:25, 4 March 2006 by 198.60.22.24 (talk)
#!/bin/sh # Make a clone from existed knoppix live-cd or dvd NOFORK=false; [ -z $REFRESH ] && export REFRESH=true; [ -z $PHASE ] && export PHASE=10 [ -z "$BEST" ] && export BEST=-b [ -z $NOSKIPDEBS ] && export NOSKIPDEBS=true; [ -z $PAUSE ] && export PAUSE=false; [ -z $DVD ] && export DVD=false; while true ; do case $1 in -d) NOFORK=true ;; '') if $NOFORK ; then break ; fi on_exit() { rm -f CDMAKE$$.tmp } trap on_exit 0 1 2 3 15 mkfifo CDMAKE$$.tmp tee livecd-make.log <CDMAKE$$.tmp & if ! $0 -d 2>CDMAKE$$.tmp ; then echo "WAS ERRORS! See report in livecd-make.log" fi exit 0 ;; unpack) PHASE=1 ;; remove) PHASE=2 ;; update) PHASE=3 ;; patch) PHASE=4 ;; quick) BEST=' ' ;; dvd) DVD=true ;; pause) PAUSE=true ;; no-update) NOSKIPDEBS=false ;; no-refresh) REFRESH=false; ;; *) echo "Usage: $0 [-d] [no-refresh] [no-upate] [quick] [unpack|remove|update|patch] unpack - stop after unpack source distro into ''./new/'' remove - stop after remove packages update - stop after install new packages patch - stop after patches and scripts pause - wait CR after each phase quick - not use ''best'' compression dvd - make dvd image - not delete most packages and split root, quick is recommended no-update - do not remove & install packages no-refresh - do not remove old ''./new/'' & unpack -d - do not redirect stderr to logfile" exit 1 ;; esac shift done read CDVER DATE < version date >&2 query() { set +x echo -n "$1 [$2] " >&2 read answer if [ -z $answer ] ; then answer=$2 ; fi set -x } set -e -x # Exit if any command fails, print command before execute if type dialog ; then gauge() { set +x lim=$1 x=1 while read j ; do echo $(( x++ * 100 / lim )) ; done | dialog --gauge "$2" 8 50 } elif [ -n "$DISPLAY" ] && type Xdialog ; then gauge() { set +x lim=$1 x=1 while read j ; do echo $(( x++ * 100 / lim )) ; done | Xdialog --gauge "$2" 8 50 } else gauge() { set +x #echo $2 lim=$1 x=1 [ -z $COLUMNS ] && COLUMNS=80 while read j ; do echo -ne "\33[2K $(( x++ * 100 / lim ))% ${j:0:$((COLUMNS-5))}\r"; done echo -ne "\33[2K" } fi CSRC=SRC/KNOPPIX/KNOPPIX UCSRC=KNOPPIX.iso if [ -b /dev/cdrom ] ; then CDROM=/dev/cdrom CDRW="0,0,0" elif [ -b /dev/cdroms/cdrom0 ] ; then CDROM=/dev/cdroms/cdrom0 CDRW=`readlink -f $CDROM` CDRW=${CDRW%cd}generic fi not_empty() { test -n "$1" && test -L "$1" -o -e "$1" } # Mount knoppix CD or image if ! [ -s $CSRC ]; then query "Knoppix CD or image location" "$CDROM" SRC="$answer" if ! [ -b $SRC ] ; then LOOP=",loop" ; fi [ -d SRC ] || mkdir SRC mount -o ro$LOOP $SRC SRC else echo "Comressed image found" fi RTSRCZ=( SRC/boot/isolinux/minirt*.gz ) query "Enter default language" us lang=$answer if ! [ -s newcd/KNOPPIX/KNOPPIX ] || ! not_empty newcd/boot/isolinux/minirt* ; then if ! not_empty new/initrd*/* && not_empty bkinitrd/*/* ; then rm -rf new/initrd*/ mv -f bkinitrd/* new fi if ! grep -q "$CDVER" new/etc/knoppix-version 2> /dev/null || ! not_empty new/initrd*/* ; then if [ $PHASE -gt 3 ] ; then # test for virtual memory size vmemsz=$( expr $( cat /proc/meminfo | grep '[mp]Free' | sed -e 's/.*: *//' -e 's/ k.*/ +/' ) 0 ) if [ $vmemsz -lt 1200000 ] ; then echo "$vmemsz kB free virtual memory detected This script needs 1.2GB of memory or swap space to build the CD image. If you have enough free space on your hard drive you may safely answer \"yes\" to the following question." query "Do you want to use 1.2GB of your disk space for the temporary swap file" yes case $answer in [Yy]*) dd if=/dev/zero of=swapfile bs=1M count=1200 mkswap swapfile swapon swapfile esac else echo "$vmemsz kB free virtual memory - OK" fi fi # first try to use cloop module # Mount inner iso image for i in "" 2 3 4 5 ; do if ! not_empty UCSRC$i/new/* ; then insmod cloop >& /dev/null || true test -e $CSRC$i || continue [ -d UCSRC$i/new ] || mkdir -p UCSRC$i/new if ! ( [ -b /dev/cloop/0 ] && losetup /dev/cloop/$((i+0)) $CSRC$i && mount /dev/cloop/$((i+0)) UCSRC$i/new ) ; then # Uncompress inner iso image if ! [ -s $UCSRC$i ] ; then echo Uncompress image $i... extract_compressed_fs $CSRC$i 2>&1 > $UCSRC$i | gauge $(( `ls -s $CSRC$i | sed 's/[^0-9 ].*//'` / 23 )) "Uncompress inner image $i..." else echo "Uncompressed image found" fi mount -o ro,loop $UCSRC$i UCSRC$i/new fi else echo "Uncompressed image seems to be already mounted" fi done read verison j < UCSRC/new/etc/knoppix-version KVERS=( `echo UCSRC/new/lib/modules/*.*.* | sed -e 's![^ ]*/!-!g'` ) if [ -d new ] ; then umount new/usr/src/debs new/proc || true umount new || true $REFRESH && rm -rfv new | gauge 135369 "Remove old directory for extracting files" fi if ! [ -d new ]; then for i in "" 2 3 4 5 ; do [ -e UCSRC$i/new ] || continue echo Extract files from the inner image $i cp -v -a -u UCSRC$i/new . 2>&1 | gauge 126000 "Extract files from the inner image $i" done fi #Uncompress initrd echo "Extract initrd image(s)" [ -d RT ] || mkdir RT umount RT || true for i in "${RTSRCZ[@]}" ; do rdimg=${i/*\//} rdimg=${rdimg/.gz/} gzip -d < $i > $rdimg.orig mount -o loop $rdimg.orig RT rddir=new/${rdimg/minirt/initrd} [ -e $rddir/linuxrc ] && continue [ -d $rddir ] && rmdir $rddir cp -a RT $rddir umount RT done [ $PHASE -lt 2 ] && exit $PAUSE && echo "KNOPPIX root file system unpacked to directory 'new'. Next phase deletes some packages and files. Press Enter to continue" && read j #------------- Modify Live CD -------------- read j j HOSTKVERS j < /proc/version TMPMOD=false remove() { if [ -s $2 ] ; then echo "$1 $2" eval "local -a lst=( $(cat $2) )" [ -z $lst ] && return 0 chroot new sh -c "$3 ${lst[*]}" || true fi } update() { [ -s "$debs/${1##[^0-9]*}apt-get-list" ] && if chroot . apt-get install `cat $debs/${1##[^0-9]*}apt-get-list` ; then true else case $? in 100) chroot . apt-get -f install chroot . apt-get install `cat $debs/${1##[^0-9]*}apt-get-list` ;; *) echo $? ; false esac fi aliens=( $debs/$1*.{rpm,tar.gz,tgz} ) [ -z $aliens ] || chroot . alien "${aliens[@]}" local -a lst=( $debs/$1*.deb *.deb ) [ -s "$lst" ] || return 0 chroot . dpkg -i --force-overwrite ${lst[@]} rm *.deb || true } if $NOSKIPDEBS ; then if ! [ -d new/lib/modules/$HOSTKVERS ] ; then # for buggy packets cp -a /lib/modules/$HOSTKVERS new/lib/modules/ TMPMOD=true fi if $DVD; then remove "Remove packages listed in" debs/00remove-debs-DVD "dpkg -P" remove "Remove files listed in" debs/00remove-files-DVD "rm -rf" else remove "Remove packages listed in" debs/00remove-debs "dpkg -P" remove "Remove files listed in" debs/00remove-files "rm -rf" fi $TMPMOD && rm -rf new/lib/modules/$HOSTKVERS [ $PHASE -lt 3 ] && exit $PAUSE && echo "Some packages and files listed in debs/00remove* are deleted. Next phase installs new packages and deletes listed in debs/zzremove*. Press Enter to continue" && read j echo Install new packages cd new mkdir -p usr/src/debs touch etc/fstab shopt -s nullglob debs=usr/src/debs mount --bind ../debs $debs mv etc/resolv.conf etc/resolv.conf.orig cp /etc/resolv.conf etc/resolv.conf if ! chroot . apt-get update -u ; then query "Continue" yes case $answer in [Yy]*) ;; *) exit 1 esac fi update 00 update 01 update 02 update '0[^0-2]' update '[^0]' chroot . apt-get -f install -u chroot . apt-get clean mv etc/resolv.conf.orig etc/resolv.conf umount usr/src/debs rmdir usr/src/debs cd .. NEWKVERS=( `echo new/lib/modules/*.*.* | sed -e 's![^ ]*/!-!g'` ) if $DVD; then remove "Remove packages listed in" debs/zzremove-debs-DVD "dpkg -P" remove "Remove files listed in" debs/zzremove-files-DVD "rm -rf" else remove "Remove packages listed in" debs/zzremove-debs "dpkg -P" remove "Remove files listed in" debs/zzremove-files "rm -rf" fi COLUMNS=140 chroot new dpkg -l > packages.txt rm new/etc/fstab || true fi # $NOSKIPDEBS [ $PHASE -lt 4 ] && exit $PAUSE && echo "All package add/remove operations is complete Next phase try and apply patches placed in 'patches' directory. Press Enter to continue" && read j echo Test patches mkdir -p patches-results cd new set +x st=() errors=false n=0 for i in ../patches/* ; do if [ -d $i ] ; then st[$n]=true elif [ -x $i ] ; then if ! $i --dry-run >& ../patches-results/${i/*\//}-exec; then st[$n]=true errors=true else mv ../patches-results/${i/*\//}-exec ../patches-results/${i/*\//}-exec-OK fi else case "$i" in *.tar.bz2) st[$n]="tar -xjf" ;; *) if patch -f -p0 --dry-run -i $i >& ../patches-results/${i/*\//}-p0 ; then st[$n]="patch -f -p0 -i" mv ../patches-results/${i/*\//}-p0 ../patches-results/${i/*\//}-p0-OK elif patch -f -p1 --dry-run -i $i >& ../patches-results/${i/*\//}-p1 ; then st[$n]="patch -f -p1 -i" rm ../patches-results/${i/*\//}-p0 mv ../patches-results/${i/*\//}-p1 ../patches-results/${i/*\//}-p1-OK else st[$n]=true errors=true fi esac fi let ++n done n=0 echo "Tests results" >&2 for i in ../patches/* ; do echo -ne " ${i/*\//} \t " >&2 case "${st[$n]}" in true) echo ERROR >&2 ;; tar*) echo "OK (tar)" >&2 ;; *-p0" "*) echo "OK (patch -p0)" >&2 ;; *-p1" "*) echo "OK (patch -p1)" >&2 ;; '') echo "OK (executable)" >&2 ;; esac let ++n done if $errors ; then query "Some patches are not applyable, see messages in directory 'patches-results' Do You want to continue without failed pathes" no case "$answer" in [yY]*) ;; *) echo "You may rerun script after corrections with next parameters: no-update no-refresh" exit 1 ; esac else echo "All patches OK">&2 fi echo Applay patches to root file system set -x n=0 for i in ../patches/* ; do ${st[$n]} $i let ++n done echo Update menus #order files in directory mkdir etc/menu-methods.new mv etc/menu-methods/* etc/menu-methods.new/ rmdir etc/menu-methods mv etc/menu-methods.new etc/menu-methods chroot . update-menus -v echo Update modules in initrd if [ -x initrd/modules/cloop.ko ] ; then SUF=ko else SUF=o fi (find initrd/modules -name '*.'$SUF ; cat <<-EOF ;) | while read i ; do initrd/modules/floppy.$SUF initrd/modules/scsi/usb-ehci.$SUF initrd/modules/scsi/usb-uhci.$SUF initrd/modules/scsi/usb-ohci.$SUF initrd/modules/scsi/usbcore.$SUF initrd/modules/scsi/usb_hcd.$SUF EOF b=${i/*\//} j=( `find lib/modules/ -name "$b" -or -name "${b/.o/.ko}"` ) if [ -s "$j" ]; then # [ "$j" -nt "$i" ] && cp -avf "$j" "$i" else b="${b/usb-/}" b="${b/.o/-hcd.o}" j=( `find lib/modules/ -name "$b" -or -name "${b/.o/.ko}"` ) if [ -s "$j" ]; then cp -avf "$j" "$i" else rm -fv $i fi fi done DEFKERNEL=`readlink vmlinuz` ln -sf ../vmlinuz boot/vmlinuz ln -sf System.map-${DEFKERNEL##*-} boot/System.map KH=( usr/src/kernel-headers-* ) ln -sf ${KH##*/} usr/src/kernel-headers echo Update dynamic library cache chroot . ldconfig echo Update molule dependencies for i in boot/System.map-* ; do [ -d lib/modules/${i##*-} ] && chroot . depmod -ae -F /$i ${i##*-} done echo Remove backups find . -name '*.orig' -o -name '*~' | xargs rm -fv echo "$verison-$CDVER $DATE" > etc/knoppix-version cd .. rm -rf split?/ else echo Patched Knoppix found fi # grep -q "$CDVER" ... umount UCSRC*/new RT || true for i in 0 1 2 3 4 5 ; do losetup -d /dev/cloop/$i || true done rmmod cloop || true [ $PHASE -lt 5 ] && exit $PAUSE && echo "All changes are complete Next phase make new comressed file system image. Press Enter to continue" && read j echo Make new compressed file system image... rm -rf new/.rr_moved $UCSRC* if ! not_empty new/inird*/* ; then rm -rf bkinitrd mkdir -p bkinitrd for i in new/initrd* ; do mv $i bkinitrd mkdir $i done fi umount new/proc || true rm -rf new/tmp/* if $DVD && ! not_empty split?/* ; then echo Split the file system ... cd new du -s opt/* usr/lib/* usr/share/* usr/* * | ../smartsplit.pl 4128768 > ../split-plan ##! Names in * must not contain space! for i in 0 1 2 3 4 5 6 7 ; do files=$( grep ^$i < ../split-plan | cut -d ' ' -f 4- ) test -z "$files" && break; rm -rf ../split$i mkdir ../split$i cp -al --parents $files ../split$i done cd .. fi mkdir -p newcd/KNOPPIX if $DVD; then for i in split? ; do KN=${i/split/KNOPPIX} KN=${KN/0/} mkisofs -quiet -hide-rr-moved -R $i | create_compressed_fs - $BEST 65536 2>&1 > newcd/KNOPPIX/$KN | gauge 60600 "Make new compressed file system image..." done else mkisofs -quiet -hide-rr-moved -R -U -sort iso-order -pad -x '/inird*/*' new | create_compressed_fs - $BEST 65536 2>&1 > newcd/KNOPPIX/KNOPPIX | gauge 30300 "Make new compressed file system image..." fi rm -rf new/initrd* mv bkinitrd/* new else echo New compressed file system image found fi # [ -s newcd/KNOPPIX/KNOPPIX ] ... echo "Make new initrd" mkdir -p newcd/boot/isolinux for i in new/initrd*/ ; do DSIZE=`du -s $i` OUT=newcd/boot/isolinux/minirt${i##*initrd} OUT=${OUT%/} dd if=/dev/zero of=$OUT count=$(( ${DSIZE%%[^0-9]*} + 4000 )) bs=1k INODES=`ls -R $i | wc -l` mke2fs -Fv -N $(( INODES + 6000 )) -m 0 $OUT mount -o loop $OUT RT rm -rf RT/lost+found cp -va $i/* RT/ umount RT gzip -9 $OUT done cp -f new/boot/vmlinuz newcd/boot/isolinux/linux if which rdev; then RDEV=rdev; else RDEV=new/usr/sbin/rdev; fi $RDEV newcd/boot/isolinux/linux /dev/ram3 umount RT UCSRC*/new new || true #rm -rf new echo Make CD image ... mkdir -p newcd/KNOPPIX/ newcd/m23 touch newcd/KNOPPIX/KNOPPIX2 newcd/m23image.bz2 newcd/mdk.tb2 newcd/m23.tb2\ newcd/m23/m23_0.4.99_halfBaked-pre3_knoppix.iso cp -auv SRC/* newcd/ $DVD || rm -rf newcd/*m23* newcd/mdk* newcd/books \ newcd/boot/isolinux/*m23* find newcd/KNOPPIX -size 0 | xargs rm -f i=" s/^KBDMAP german.kbd/#&/" case "$lang" in de) i="" ;; esac sed -e "s/lang=[a-z]\+/lang=$lang/$i" SRC/boot/isolinux/isolinux.cfg > newcd/boot/isolinux/isolinux.cfg umount SRC || true mkisofs -pad -l -r -J -m Demos -m LinuxTag -m Talks -V "$CDVER" -no-emul-boot \ -boot-load-size 4 -boot-info-table -b boot/isolinux/isolinux.bin \ -c boot/isolinux/boot.cat -hide-rr-moved -o knoppix-$CDVER.iso newcd $FNAME #rm -rf KNOPPIX isolinux.cfg isolinux.bin SRC UCSRC* minirt24.gz echo New CD image in knoppix-$CDVER.iso query "Do You want to record new CD" no case "$answer" in [yY]*) echo "cdrecord -v speed=50 dev=$CDRW driveropts=burnfree -eject knoppix-$CDVER.iso" cdrecord -v speed=50 dev=$CDRW driveropts=burnfree -eject knoppix-$CDVER.iso esac