#!/bin/bash # # This script will create LiveCD based on # The Synergy Linux distribution # prog_name=`basename "$0"` # check kernel release function get_src_kernel_rel { if [[ -n "$kernel_rel" ]]; then rel=$(ls -1 $1/lib/modules/) [ "$(echo $rel | wc -w )" -ne 1 ] && echo "Can't read kernel release in $1 (found: $rel)" && return 1 echo $rel fi } # copy module with depends function copy_module { for modname in $@ do module_with_deps=$(grep -P "/$modname.ko(.gz)?:" $sys_source/lib/modules/$kernel_rel/modules.dep | sed -e s/:// ) [ -z "$module_with_deps" ] && module_with_deps=$modname && echo "No entries found in modules.dep for $modname" for modpath in $module_with_deps do dstdir=$(dirname $tmp_initrd/lib/modules/$kernel_rel/$modpath) [ ! -d $dstdir ] && mkdir -p $dstdir echo " - module: lib/modules/$kernel_rel/$modpath" cp $sys_source/lib/modules/$kernel_rel/$modpath $dstdir done done } # copy directory of modules but not check depends function copy_modules_dir { for moddirname in $@ do [ ! -d $sys_source/lib/modules/$kernel_rel/$moddirname ] && die "Directory /lib/modules/$kernel_rel/$moddirname not found!" dstdir=$(dirname $tmp_initrd/lib/modules/$kernel_rel/$moddirname) [ ! -d $dstdir ] && mkdir -p $dstdir echo " - modules: lib/modules/$kernel_rel/$moddirname" cp -r $sys_source/lib/modules/$kernel_rel/$moddirname $dstdir done } # find© firmware for modules copied into initrd skeleton function findAndCopyFirmwareFiles { # copy firmware loader script # cp $sys_source/lib/firmware/firmware-loader.sh $tmp_initrd/lib/firmware || return 1 # search for all modules for modname in $(find $tmp_initrd/lib/modules/$kernel_rel/ -type f) do # get all firmware file names for this module firmwareFiles=$(modinfo $modname | grep '^firmware:\ ' | sed 's/.*\ //') || return 1 for firmwareFile in $firmwareFiles do # find file path firmwareDirs="lib/firmware lib/firmware/updates" unset firmwareDir for firmwareDir in $firmwareDirs do [ -f $sys_source/$firmwareDir/$firmwareFile ] && firmwareDirFound=$firmwareDir && continue done [ -z $firmwareDirFound ] && echo "No firmware: $firmwareFile found" # copy files to initrd skeleton dstFirmDir=$(dirname $tmp_initrd/$firmwareDirFound/$firmwareFile) [ ! -d $dstFirmDir ] && mkdir -p $dstFirmDir echo " - $firmwareDirFound/$firmwareFile" cp $sys_source/$firmwareDirFound/$firmwareFile $dstFirmDir done done } # create dev nodes in the directory function createSpecialDevFiles { [ ! -d "$1" ] && die "$ is not a directory" echo "Creating devices in $1" mknod $1/console c 5 1 mknod $1/null c 1 3 mknod $1/zero c 1 5 mknod $1/kmsg c 1 11 mknod $1/fb0 c 29 0 ln -s /proc/self/fd $1/fd ln -s $/fd/0 $1/stdin ln -s $/fd/1 $1/stdout ln -s $/fd/2 $1/stderr } function copy_libs { #Make sure we have input [[ $# < 2 ]] && echo "No vaild input: copy_libs \"binary\" \"destination\" " #Check if the paths are vaild echo "what am I" $tmp_initrd/bin/$(basename $1) [[ ! -e $tmp_initrd/bin/$(basename $1) ]] && echo "Not a valid input $1" && return 1 [[ -d $2 ]] || echo "No such directory $2 creating..."&& mkdir -p "$2" #Get the binary library dependencies echo "Collecting the shared library dependencies for $1..." deps=$(chroot $sys_source ldd $1 |cut -d'>' -f2 |sed 's/(0x[^[:space:]]*//g' ) #deps=$(ldd $1 |cut -d'>' -f2 | awk '{print $1}') echo "Copying the dependencies for $1 to $2" #Copy the libs for dep in $deps do lib_link=$(readlink -m $dep) if [[ ! -z $(readlink $dep) ]] && [[ ! -f $tmp_initrd/lib/$(basename $dep) ]] && [[ ! -f $tmp_initrd/lib/$(basename $lib_link) ]]; then cp -df $lib_link $tmp_initrd/lib/ ln -sf /lib/$(basename $lib_link) $tmp_initrd/lib/$(basename $dep) echo "found lib link $(basename $dep) $tmp_initrd/lib/$(basename $lib_link)" else if [[ ! -f $2$(basename $dep) ]] && [[ ! -f $tmp_initrd/lib/$(basename $lib_link) ]]; then echo "Copying $dep to $2" cp -df "$sys_source$dep" $tmp_initrd/lib/ else echo "lib $2$(basename $dep) exists" fi fi done } function find_copy_bin { #Make sure we have input [[ $# < 2 ]] && echo "No vaild input: find_bin \"binary\" \"destination\" " #Check if the paths are vaild #[[ ! -e $sys_source$1 ]] && echo "Not a vaild input $1" && return 1 [[ -d $2 ]] || echo "No such directory $2 creating..."&& mkdir -p "$2" #Copy binary found_bin=$(chroot $sys_source find /*bin/ /usr/*bin/ -type f | grep -w -m1 "$1$") echo "copying $found_bin to $2" if [[ -f $sys_source$found_bin ]]; then cp -d "$sys_source$found_bin" "$2" copy_libs $found_bin $tmp_initrd/lib/ else echo "$found_bin file not found" fi } function find_copy_busybox { #find and copy busybox #if busybox.static and busybox shared is installed it's assumed #that busybox static should be default otherwise it wouldn't be installed #if static is not found use the shared version and copy the libs as well locate_bbox=$(find $sys_source/*bin/ $sys_source/usr/*bin/ -executable -type f -name busybox* -print | tr " " "\n" ) if [[ $(echo $locate_bbox) == *"static"* ]]; then bbox_bin=$(echo $locate_bbox |tr " " "\n"|grep -m1 'static') ln -sf $(basename $bbox_bin) $tmp_initrd/bin/busybox if [[ $1 == 1 ]]; then echo $(basename $bbox_bin) exit 0 fi else bbox_bin=$(echo $locate_bbox |tr " " "\n"|grep -m1 'busybox') if [[ $1 == 1 ]]; then echo $(basename $bbox_bin) exit 0 fi echo "not static copying libs" copy_libs $bbox_bin $tmp_initrd/lib/ fi [[ -d $1 ]] || echo "No such directory $1 creating..."&& mkdir -p "$1" if [[ $1 != 1 ]]; then echo "copying busybox: $bbox_bin" cp -df $bbox_bin $1 fi } function create_initrd { #make root dirs mkdir $tmp_initrd/{proc,sys,dev} mkdir -p $tmp_initrd/usr/share mkdir -p $tmp_initrd/var/udev mkdir -p $tmp_initrd/run/udev #make mnt dirs mkdir -p $tmp_initrd/mnt/{device,liveroot,work,upper,newroot} [ -d $sys_source/lib64 ] && libDir=lib64 || libDir=lib # guess 'lib' dir name for x86_64 arch initrd_tools_dir=/usr/$libDir/initrd echo "Creating initrd skeleton: $tmp_initrd" #cp -r $mkroot/$templatesDir/initrd/* $tmp_initrd echo "Creating Folders" mkdir $tmp_initrd/bin mkdir $tmp_initrd/dev mkdir -p $tmp_initrd/etc/udev mkdir -p $tmp_initrd/lib/firmware mkdir -p $tmp_initrd/lib/modules mkdir -p $tmp_initrd/lib64/firmware mkdir -p $tmp_initrd/lib64/modules mkdir -p $tmp_initrd/mnt/device mkdir -p $tmp_initrd/mnt/liveroot mkdir -p $tmp_initrd/mnt/newroot mkdir -p $tmp_initrd/mnt/tmpfs mkdir $tmp_initrd/proc mkdir $tmp_initrd/sys mkdir -p $tmp_initrd/usr/share echo "Copying files from /usr/share/makelive" cp /usr/share/makelive/pcimodules $tmp_initrd/bin/ cp /usr/share/makelive/ld.so.conf $tmp_initrd/etc/ cp /usr/share/makelive/udev.conf $tmp_initrd/etc/udev/ cp /usr/share/makelive/init $tmp_initrd/ # create devices createSpecialDevFiles $tmp_initrd/dev # demod in source sys if needed [ ! -f $sys_source/lib/modules/$kernel_rel/modules.dep ] && echo "Running depmod..." && chroot $sys_source depmod -a -b / $kernel_rel echo "Copying kernel modules to initrd skeleton..." copy_module loop overlay ext2 ext3 ext4 lvm xfs squashfs vfat rfkill drm cdrom isofs ahci udf copy_module mii p4-clockmod usb-storage atl2 i2c-algo-bit i2c-core copy_modules_dir kernel/drivers/scsi kernel/drivers/ata kernel/drivers/cpufreq kernel/drivers/net/ethernet/atheros/ kernel/drivers/i2c copy_modules_dir kernel/drivers/gpu/drm kernel/fs/isofs [ -d $sys_source/lib/modules/$kernel_rel/kernel/fs/aufs ] && echo "found aufs module" && aufs_module_found=1 && copy_module aufs echo "Copying firmware files to initrd skeleton..." #findAndCopyFirmwareFiles || exit 1 # gunzip modules, we will compress whole initrd image # find $tmp_initrd/lib/modules/$kernel_rel -type f -name \*.xz -exec xz -d \{\} \; depmod -a -b $tmp_initrd $kernel_rel # Set Plymouth Theme ** We need a new option for this, hard coding no good ** # chroot $sys_source /usr/sbin/plymouth-set-default-theme synergy # chroot $sys_source /usr/libexec/plymouth/plymouth-generate-initrd echo "Adding binaries..." find_copy_bin kmod $tmp_initrd/bin/ find_copy_bin udevadm $tmp_initrd/bin/ #do not fail on these 2 not all systems have them find_copy_bin udevd $tmp_initrd/bin/ #cp -d $sys_source/lib/systemd/systemd-udevd $tmp_initrd/bin/ find_copy_bin mount $tmp_initrd/bin/ || return 1 find_copy_bin umount $tmp_initrd/bin/ || return 1 find_copy_bin killall $tmp_initrd/bin/ find_copy_bin mke2fs $tmp_initrd/bin/ || return 1 # cp -d $sys_source/bin/plymouth $tmp_initrd/bin/ || return 1 # cp -d $sys_source/sbin/plymouthd $tmp_initrd/bin/ || return 1 find_copy_busybox $tmp_initrd/bin/ || return 1 ln -sf kmod $tmp_initrd/bin/depmod # ln -sf `find_copy_busybox 1` $tmp_initrd/bin/mount || return 1 # ln -sf `find_copy_busybox 1` $tmp_initrd/bin/umount || return 1 ln -sf `find_copy_busybox 1` $tmp_initrd/bin/awk || return 1 ln -sf `find_copy_busybox 1` $tmp_initrd/bin/cut || return 1 ln -sf `find_copy_busybox 1` $tmp_initrd/bin/dmesg || return 1 ln -sf `find_copy_busybox 1` $tmp_initrd/bin/grep || return 1 ln -sf `find_copy_busybox 1` $tmp_initrd/bin/head || return 1 ln -sf `find_copy_busybox 1` $tmp_initrd/bin/ln || return 1 ln -sf `find_copy_busybox 1` $tmp_initrd/bin/losetup || return 1 ln -sf `find_copy_busybox 1` $tmp_initrd/bin/lsmod || return 1 ln -sf `find_copy_busybox 1` $tmp_initrd/bin/mdev || return 1 ln -sf `find_copy_busybox 1` $tmp_initrd/bin/mkdir || return 1 ln -sf `find_copy_busybox 1` $tmp_initrd/bin/mknod || return 1 ln -sf `find_copy_busybox 1` $tmp_initrd/bin/rmmod || return 1 ln -sf `find_copy_busybox 1` $tmp_initrd/bin/sed || return 1 ln -sf `find_copy_busybox 1` $tmp_initrd/bin/sh || return 1 ln -sf `find_copy_busybox 1` $tmp_initrd/bin/sleep || return 1 ln -sf `find_copy_busybox 1` $tmp_initrd/bin/sort || return 1 ln -sf `find_copy_busybox 1` $tmp_initrd/bin/switch_root || return 1 ln -sf `find_copy_busybox 1` $tmp_initrd/bin/tail || return 1 ln -sf `find_copy_busybox 1` $tmp_initrd/bin/uname || return 1 ln -sf `find_copy_busybox 1` $tmp_initrd/bin/cat || return 1 ln -sf `find_copy_busybox 1` $tmp_initrd/bin/cp || return 1 ln -sf `find_copy_busybox 1` $tmp_initrd/bin/dd || return 1 ln -sf `find_copy_busybox 1` $tmp_initrd/bin/find || return 1 ln -sf `find_copy_busybox 1` $tmp_initrd/bin/ls || return 1 ln -sf `find_copy_busybox 1` $tmp_initrd/bin/modprobe || return 1 ln -sf `find_copy_busybox 1` $tmp_initrd/bin/pidof || return 1 #Purely for Troubleshooting and Awesomeness ln -sf `find_copy_busybox 1` $tmp_initrd/bin/vi || return 1 echo "Adding libraries..." cp $sys_source/etc/ld.so.conf $tmp_initrd/etc # cp -r $sys_source/etc/plymouth $tmp_initrd/etc/ # cp -r $sys_source/usr/share/plymouth $tmp_initrd/usr/share/ if [ $arch = 'x86_64' ]; then mkdir -p $tmp_initrd/usr/lib64 # cp -r $sys_source/usr/lib64/plymouth $tmp_initrd/usr/lib64/ # cp -rfd $sys_source/usr/lib64/libply* $tmp_initrd/usr/lib64/ # cp -rfd $sys_source/usr/lib64/libpng12* $tmp_initrd/usr/lib64/ # cp -rfd $sys_source/usr/lib64/libpng15* $tmp_initrd/usr/lib64/ else mkdir -p $tmp_initrd/usr/lib # cp -r $sys_source/usr/lib/plymouth $tmp_initrd/usr/lib/ # cp -rfd $sys_source/usr/lib/libply* $tmp_initrd/usr/lib/ # cp -rfd $sys_source/usr/lib/libpng12* $tmp_initrd/usr/lib/ # cp -rfd $sys_source/usr/lib/libpng15* $tmp_initrd/usr/lib/ fi ldconfig -r $tmp_initrd chown -R root:root $tmp_initrd/* echo "Writing $VOLID LABEL into: $volid_file" echo "$VOLID" > $volid_file make_cleanup $tmp_initrd # bootsplash # if [ $bootsplash_arg -eq 1 ]; then # echo "Creating bootsplash" # /bin/splash.bin -s -f $bootsplash > $tmp_initrd/bootsplash # fi echo "Creating initramfs image: $1" cd $tmp_initrd # find . | cpio -H newc -o | $compr > $1 find . | cpio -H newc -o | gzip > $1 [ $? -eq 0 ] && echo "Image saved as $1 (size: $(stat -c %s $1))" || die "Creating image failed!" } # return application related libraries function get_app_libs { [ ! -x "$1" ] && "Error: $1 is not executable file" chroot $sys_source ldd $1 | grep '/lib' | sed -e 's/\ (.*//' -e 's/.*=>\ //' -e "s/[\ \t]//g" } function die { echo "Error: $@" exit 1 } function print_help { echo "$prog_name usage: $prog_name /source_directory /image.iso [OPTIONS]" echo " -h|--help - print this message" echo " --lzma - use lzma compression instead gzip" echo " --gzip - use gzip compression (default)" echo -e " --tpl=tpl-dir - templates dir ("templates" by default)" echo " --bootsplash=config - enable bootsplash (default no)" echo "" echo " $prog_name script creates a live cd/dvd system based on Synergy Linux" echo " installed into directory." echo " example 1:" echo " # $prog_name /my-sys-dir /my-live.iso" echo " example 2:" echo " # $prog_name /my-sys-dir /my-live.iso --tpl=templates-my --lzma" } function make_cleanup { echo "Running cleanup of $1..." find $1 -name \*~ -exec rm \{\} \; find $1 -name .svn -type d -exec rm -rf \{\} \; 2> /dev/null rm -rf $1/initrd } ##### MAIN ##### templatesDir=templates bootsplash_arg=1 for arg in $@ do case $arg in --lzma) compr=lzma; squashfscompr=xz ;; --kernel=*) kernel_rel=$(echo $arg | sed 's/.*kernel=//;s/--.*//') ;; --label=*) VOLID=$(echo $arg | sed 's/.*VOLID=//;s/--.*//') ;; --gzip) compr=gzip; squashfscompr=gzip ;; --tpl=*) templatesDir=$(echo $arg | sed 's/.*tpl=//;s/--.*//') ;; --bootsplash=*) bootsplash_arg=1 bootsplash=$(echo $arg | sed 's/.*bootsplash=//;s/--.*//') ;; -h|--help) print_help exit 0 ;; -*) echo "Invalid option: $arg. Use -h to print help" print_help exit 1 ;; *) [ -z $sys_source ] && sys_source=$arg && continue [ -z $dst_iso ] && [ ! -z $sys_source ] && dst_iso=$arg ;; esac done [ ! $(whoami) = 'root' ] && die "You need superuser privileges, try 'su' or 'sudo'" [ -z $sys_source ] && die "Missing arg: source directory. Use -h to print help." [ -z $dst_iso ] && die "Missing arg: iso image. Use -h to print help" [ -z $compr ] && compr=gzip # gzip is default compression method [ ! -d $sys_source ] && die "$sys_source is not a directory" mkroot=$(dirname $0) # read configuration from ~/.mkliverc [ -f ~/.mkliverc ] && . ~/.mkliverc # preparing temp dirs rm -rf /tmp/$0_tmp_* # Try and Guess arch [ -d $sys_source/lib64 ] && arch=x86_64 || arch=i686 # If VOLID is not defined grep version from release rpm [ -z "$VOLID" ] && VOLID=`chroot $sys_source cat /etc/redhat-release | awk -F" " '{print $1"-"$2"_"$4}'`-$arch # default VOLID tmp_iso_root=$(mktemp -d /tmp/$(basename $0)_tmp_iso__XXXXXX) tmp_initrd=$(mktemp -d /tmp/$(basename $0)_tmp_initrd__XXXXXX) volid_file=$tmp_initrd/DEV_LABEL live_rootfs_archive=squashfs.img kernel_rel=$(get_src_kernel_rel $1) [ $? -ne 0 ] && die "Kernel release not found: "$kernel_rel echo "::: $prog_name :::" echo "found kernel: $kernel_rel" echo "compression method: $compr" echo "initrd temporary dir: $tmp_initrd" echo "iso temporary dir: $tmp_iso_root" echo "templates directory: $mkroot/$templatesDir" echo "application: $APPLICATION" echo "preparer: $PREPARER" echo "volid: $VOLID" echo "" # does templates exist #[ ! -d $mkroot/$templatesDir ] && die "templates dir: $mkroot/$templatesDir does not exist." # does bootsplash configuration exist if [ $bootsplash_arg -eq 1 ]; then [ ! -f $bootsplash ] && die "bootsplash configuration: $bootsplash does not exist." fi # is destination exists if [ -a $dst_iso ] then echo "Warning: $dst_iso file already exists." echo "Do you wish to overwrite? [N/y]" read anykey [ ! "$anykey" = 'y' ] && die "Interrupted." || rm -f $dst_iso fi # creating initrd: temp live root echo "Copying kernel and basic tools..." #cp -r $mkroot/$templatesDir/isolinux $tmp_iso_root mkdir -p $tmp_iso_root/isolinux cp /usr/*/syslinux/ldlinux.c32 $tmp_iso_root/isolinux/ cp /usr/*/syslinux/libcom32.c32 $tmp_iso_root/isolinux/ cp /usr/*/syslinux/libutil.c32 $tmp_iso_root/isolinux/ cp /usr/*/syslinux/chain.c32 $tmp_iso_root/isolinux/ cp /usr/*/syslinux/hdt.c32 $tmp_iso_root/isolinux/ cp /usr/*/syslinux/isolinux.bin $tmp_iso_root/isolinux/ cp /usr/*/syslinux/reboot.c32 $tmp_iso_root/isolinux/ cp /usr/*/syslinux/vesamenu.c32 $tmp_iso_root/isolinux/ cp /usr/share/makelive/isolinux.cfg $tmp_iso_root/isolinux/ cp /usr/share/makelive/splash.jpg $tmp_iso_root/isolinux/ cp /usr/share/makelive/help.msg $tmp_iso_root/isolinux/ cp /usr/share/makelive/memtest86 $tmp_iso_root/isolinux/ cp /usr/share/hwdata/pci.ids $tmp_iso_root/isolinux if [ -f $sys_source/boot/vmlinuz-$(echo $kernel_rel) ]; then cp $sys_source/boot/vmlinuz-$(echo $kernel_rel) $tmp_iso_root/isolinux/vmlinuz else die "No Suitable vmlinuz found for kernel: "$kernel_rel fi make_cleanup $tmp_iso_root # create image create_initrd $tmp_iso_root/isolinux/initrd.img || die "Creating initrd image failed." cp $tmp_iso_root/isolinux/initrd.img /tmp/ # create live echo "Creating squashfs filesystem: $tmp_iso_root/$live_rootfs_archive..." mkdir -p $tmp_iso_root/LiveOS/ # Test cli installer, so copy over #cp -f $mkroot/$templatesDir/synergy-install-cli $sys_source/usr/sbin/ #cp -f $mkroot/$templatesDir/synergy-install-gui $sys_source/usr/sbin/ #cp -f $mkroot/$templatesDir/auto-part $sys_source/usr/sbin/ mksquashfs $sys_source $tmp_iso_root/LiveOS/$live_rootfs_archive -comp $squashfscompr -e /tmp -e /root/rpms -e /root/rpmbuild -e /root/packages -e /root/building -e /proc/ -e /sys/ -e /dev/ -e /run/ > /dev/null || die "Creating live rootfs failed" echo "Creating ISO image: $dst_iso ($VOLID)..." mkisofs -o $dst_iso --publisher "Unity Linux" -b isolinux/isolinux.bin -c isolinux/boot.cat \ -no-emul-boot -boot-load-size 4 -boot-info-table -l -R \ -A "$APPLICATION" -V "$VOLID" -p "$PREPARER" \ -r $tmp_iso_root \ || die "Creating iso image failed." rm -rf $tmp_iso_root rm -rf $tmp_initrd echo "Image $dst_iso seems to be ready"