#!/bin/bash # read (source) the config file . ./x2go-tce-config # Create Timestamp LBX2GO_TIMESTAMP=$(date +"%Y%m%d%H%M%S") # Log all output to a logfile in /tmp exec > >(tee "/tmp/$LBX2GO_TIMESTAMP.log") 2>&1 # Set Directory name LBX2GO_TCEDIR="./live-build-x2go-${LBX2GO_TIMESTAMP}-${LBX2GO_IMAGETYPE}-$(echo $LBX2GO_ARCH | awk '{print $2}')-${LBX2GO_CONFIG##*/}" if [ -z "$LBX2GO_ARCH" ] || ( echo "$LBX2GO_ARCH" | grep -q "arm" && [ -z "$LBX2GO_ARCH_MODEL" ] ) || [ -z "$LBX2GO_SPACE" ] || [ -z "$LBX2GO_CONFIG" ] || [ -z "$LBX2GO_DEFAULTS" ] || [ -z "$LBX2GO_DEBVERSION" ] || [ -z "$LBX2GO_IMAGETYPE" ] || [ -z "$LBX2GO_TIMESTAMP" ] || [ -z "$LBX2GO_BOOTLOADERPARAMNAME" ] || [ -z "$LBX2GO_BOOTLOADER" ] || [ -z "$LBX2GO_ARCHIVE_AREAS" ]; then echo -e "One or more of the following variables is unset:" echo -e "LBX2GO_ARCH: '${LBX2GO_ARCH}'" echo "$LBX2GO_ARCH" | grep -q "arm" && echo -e "LBX2GO_ARCH_MODEL: '${LBX2GO_ARCH_MODEL}'" echo -e "LBX2GO_SPACE: '${LBX2GO_SPACE}'" echo -e "LBX2GO_DEFAULTS: '${LBX2GO_DEFAULTS}'" echo -e "LBX2GO_DEBVERSION: '${LBX2GO_DEBVERSION}'" echo -e "LBX2GO_CONFIG: '${LBX2GO_CONFIG}'" echo -e "LBX2GO_IMAGETYPE: '${LBX2GO_IMAGETYPE}'" echo -e "LBX2GO_TIMESTAMP: '${LBX2GO_TIMESTAMP}'" echo -e "LBX2GO_BOOTLOADERPARAMNAME: '${LBX2GO_BOOTLOADERPARAMNAME}'" echo -e "LBX2GO_BOOTLOADER: '${LBX2GO_BOOTLOADER}'" echo -e "LBX2GO_ARCHIVE_AREAS: '${LBX2GO_ARCHIVE_AREAS}'" echo -e "Please visit http://wiki.x2go.org/doku.php/doc:howto:tce" echo -e "and read up on the general prerequisites for X2Go-TCE" else # This will create a timestamped subdirectory for the build mkdir -p $LBX2GO_TCEDIR cd $LBX2GO_TCEDIR X2GO_LBCONFIG_STRING=$(cat <>config/package-lists/raspi.list.chroot fi if [ "$LBX2GO_ARCH_MODEL" = "Pi3" ] ; then # modules required for Raspberry Pi 3 LAN echo "crc16" >> config/includes.chroot/etc/initramfs-tools/modules echo "mii" >> config/includes.chroot/etc/initramfs-tools/modules echo "smsc95xx" >> config/includes.chroot/etc/initramfs-tools/modules echo "usbcore" >> config/includes.chroot/etc/initramfs-tools/modules echo "usbnet" >> config/includes.chroot/etc/initramfs-tools/modules echo "fake-hwclock" >>config/package-lists/raspi.list.chroot echo "usbutils" >>config/package-lists/raspi.list.chroot # firmware for basic raspi functions - required for boot on Pi3 echo "raspi3-firmware/buster" >>config/package-lists/raspi.list.chroot # standard linux kernel - for Pi3 echo "linux-image-arm64/buster" >>config/package-lists/raspi.list.chroot elif [ "$LBX2GO_ARCH_MODEL" = "Pi4" ] ; then # bullseye and newer do not need this if [ "${LBX2GO_DEBVERSION}" = "buster" ]; then # firmware for basic raspi functions - required for boot on Pi4 echo "raspi3-firmware/buster-backports" >>config/package-lists/raspi.list.chroot echo "raspi-firmware/buster-backports" >>config/package-lists/raspi.list.chroot # newer linux kernel - required for pi4/pi400 echo "linux-image-arm64/buster-backports" >>config/package-lists/raspi.list.chroot fi else echo "WARNING: ARM Platform selected, but unknown model: '$LBX2GO_ARCH_MODEL'. Assuming no additional packages/patches are required." fi fi # This is for minidesktop builds only if [ -f config/package-lists/firefox-langpacks.list.chroot ]; then if [ -n "$LBX2GO_LANG" ]; then for LBX2GO_SINGLE_LANG in $(echo "$LBX2GO_LANG" | tr ';' ' '); do echo "LANG: '$LBX2GO_SINGLE_LANG'" sed -i -e 's/#firefox-esr-l10n-'$LBX2GO_SINGLE_LANG'$/firefox-esr-l10n-'$LBX2GO_SINGLE_LANG'/' config/package-lists/firefox-langpacks.list.chroot done else rm config/package-lists/firefox-langpacks.list.chroot fi fi if [ "$LBX2GO_TCE_SHRINK" = "true" ] ; then echo '#!/bin/sh' >./config/hooks/0112-remove-folders.hook.chroot echo 'set -e' >>./config/hooks/0112-remove-folders.hook.chroot echo '# Remove folders' >>./config/hooks/0112-remove-folders.hook.chroot echo 'rm -rf ./usr/share/doc/*' >>./config/hooks/0112-remove-folders.hook.chroot echo 'rm -rf ./usr/share/locale/*' >>./config/hooks/0112-remove-folders.hook.chroot echo 'rm -rf ./usr/share/man/*' >>./config/hooks/0112-remove-folders.hook.chroot [ "$LBX2GO_IMAGETYPE" != "netboot" ] && echo 'rm -rf ./var/lib/apt/lists/*' >>./config/hooks/0112-remove-folders.hook.chroot chmod 755 ./config/hooks/0112-remove-folders.hook.chroot fi if [ -n "$LB_APT_HTTP_PROXY" ] || [ -n "$LB_APT_FTP_PROXY" ]; then echo "NOTICE: apt proxy variable(s) is/are set." echo "NOTICE: Trying to use the proxy for all downloads." echo "NOTICE: If this fails, look for #SETPROXY in the $0 source." # Here, we should have reached a point where it is safe to point all proxy variables # at the apt-cacher-ng proxy. If you're seeing errors during your build that hint # at files not being downloaded, disable these three entries. export https_proxy=$LB_APT_HTTP_PROXY export http_proxy=$LB_APT_HTTP_PROXY export ftp_proxy=$LB_APT_FTP_PROXY fi # This is part of our experimental ARM support # It is used when building for the ARM architecture (on Intel/AMD hardware and on ARM). # It makes some necessary changes, and also tries to speed up squashfs creation when it # detects a crossbuild environment. if echo $LBX2GO_ARCH | grep -q 'arm'; then # This command removes all references to fuseext, freerdp-nightly, and x2gothinclient from the # package list files. Currently needed as there are no ARM packages for any of these. echo "WARNING: Removing all references to fuseext,freerdp-nightly and x2gothinclient from the build." sed -e 's/^.*fuseext.*$//g' -e 's/^.*freerdp-nightly.*$//g' -e 's/^.*x2gothinclient.*$//g' -i ./config/package-lists/* # This command removes the X2Go repository from the directory where additional # archives are stored. Currently needed as the X2Go repository offers no arm64 # packages, but Debian Buster does - so that's what we're falling back to. echo "WARNING: Removing all references to the X2Go repository from the build." rm ./config/archives/*x2go* # The following is a hack to reduce squashfs creation time in a crossbuild environment. # We're replacing mksquashfs in the changeroot with a wrapper script that drops the # original mksquashfs call into a file. if (uname -r | grep -q 'i.86' || uname -r | grep -q 'amd64') ; then # We need to do this as a background task, waiting for the mksquashfs executable to # appear in the changeroot; as the changeroot will only be created later on, once # lb build is called. # The other background task waits until the command file has been created, then # it applies some necessary patches to it, and starts the mksquashfs command natively # on the build host, rather than in the changeroot environment. # This is because in the changeroot, we'd be running the ARM mksquashfs in a qemu # software emulation of the ARM architecture, while on the host, we can use all the # native, raw CPU power and cores available to us. # To make sure we don't have any lingering processes in the background, we're passing # our own PID along to the background tasks, and tell them to terminate if our PID # disappears while they're still in their waiting/looping state. MASTERPID=$$ # Replace mksquashfs in chroot with script # (script will undo this upon completion) ( # wait until the chroot has been populated or until our parent process dies while ! [ -x ./chroot/usr/bin/mksquashfs ]; do ps $MASTERPID >/dev/null || exit 1 sleep 1 done # make sure we don't overwrite the real executable if it has already been # moved out of the way if ! [ -x ./chroot/usr/bin/mksquashfs.real ]; then cp ./chroot/usr/bin/mksquashfs ./chroot/usr/bin/mksquashfs.real fi echo '#!/bin/bash' >./chroot/usr/bin/mksquashfs # log the name we've been called with and all parameters into this file echo 'echo "$0 $@" >/tmp/filesystem.squashfs.temp' >>./chroot/usr/bin/mksquashfs # once the native mksquashfs is complete, we will remove this file echo 'while [ -f /tmp/filesystem.squashfs.temp ]; do' >>./chroot/usr/bin/mksquashfs echo ' sleep 1' >>./chroot/usr/bin/mksquashfs echo 'done' >>./chroot/usr/bin/mksquashfs # so let's wait until it has been removed before deleting ourselves ... echo 'rm /usr/bin/mksquashfs' >>./chroot/usr/bin/mksquashfs # ... and moving the real executable back into its place echo 'mv /usr/bin/mksquashfs.real /usr/bin/mksquashfs' >>./chroot/usr/bin/mksquashfs chmod 755 ./chroot/usr/bin/mksquashfs ) & # start the native mksquashfs after patching the parameters ( # wait until the trigger file has been created or until our parent process dies while ! [ -f ./chroot/tmp/filesystem.squashfs.temp ]; do ps $MASTERPID >/dev/null || exit 1 sleep 1 done # using any of the available filters (x86, arm, armthumb) for the # -Xbcj command results in an unusable squashfs on arm, so we drop the # parameter completely if it's there. # also, all absolute paths (detected by beginning with " /") need to be # prefixed with "./chroot" so the mksquashfs outside the chroot knows where # to look for the corresponding paths/files. sed -e 's/ -Xbcj x86/ /g' -e 's# /# ./chroot/#g' -i \ ./chroot/tmp/filesystem.squashfs.temp #needs switch from e.g. /bin/mksquashfs to $(which mksquashfs) sed -e "s#^.*mksquashfs#$(which mksquashfs)#g" -i \ ./chroot/tmp/filesystem.squashfs.temp # now let's make this executable chmod 755 ./chroot/tmp/filesystem.squashfs.temp # we also need to add some more excludes because they shouldn't end up # in the squashfs - no idea why we don't need them while inside the chroot ... echo 'proc/*' >>./chroot/excludes echo 'sys/*' >>./chroot/excludes echo 'dev/pts/*' >>/.chroot.excludes # now let's execute the script and, if it terminates without an error, # we'll move the newly created squashfs into the chroot where the chrooted # mksquashfs command would have created it; if that worked as well, we'll # remove the script file so our dummy mksquashfs inside the chroot knows # it's time to terminate itself. ./chroot/tmp/filesystem.squashfs.temp && \ mv ./filesystem.squashfs ./chroot/ && \ rm ./chroot/tmp/filesystem.squashfs.temp ) & fi fi if lb build ; then echo -e "Build is done: '$LBX2GO_TCEDIR'" ln $(realpath ./chroot/vmlinuz) ./x2go-tce-vmlinuz ln $(realpath ./chroot/initrd.img) ./x2go-tce-initrd.img ln ./binary/live/filesystem.squashfs ./x2go-tce-filesystem.squashfs if [ "$LBX2GO_IMAGETYPE" = "hdd" ] ; then ln ./live-image-$(echo $LBX2GO_ARCH | awk '{print $2}').img \ ./x2go-tce-live-image-$(echo $LBX2GO_ARCH | awk '{print $2}').img fi # This is part of our experimental ARM support if [ "$LBX2GO_IMAGETYPE" = "hdd" ] && echo $LBX2GO_ARCH | grep -q "arm" ; then # after the build, let's determine the name of our image file ... IMAGEFILE="./x2go-tce-live-image-$(echo $LBX2GO_ARCH | awk '{print $2}').img" # ... and change the partition type to reflect the file system actually in use for partition 1 # ("b" is FAT32) sfdisk --part-type $IMAGEFILE 1 b # next, we need to patch two things inside the image, so we need to set up a loop device for it. FREELOOP=$(losetup -f) # note that this could become a TOCTOU issue if more than 1 process tries to use loop devices # as the image is a full disk image containing a partition, we need to jump to the position where the first partition starts losetup -o 1048576 $FREELOOP $IMAGEFILE # now let's mount it mkdir -p ./tempmount mount $FREELOOP ./tempmount # purge this dir, so we have enough space; we'll return to fill it later rm ./tempmount/live/* # first, we copy the contents of the boot/firmware/ folder to the root directory, because that is where these files are needed # see if inplace helps against out of space errors rsync -aP --inplace ./chroot/boot/firmware/* ./tempmount mkdir -p ./tempmount/live/ rsync -aP ./binary/live/*.squashfs ./tempmount/live/ # next, we replace the "root=" parameter with the parameters needed for live-booting sed -e 's#root=/dev/mmcblk0p2 #'"$LBX2GO_BOOTAPPEND_LIVE"' #' -i ./tempmount/cmdline.txt # here comes the cleanup part sync umount $FREELOOP losetup -d $FREELOOP rmdir ./tempmount fi if [ "$LBX2GO_IMAGETYPE" = "netboot" ] ; then if [ "$LBX2GO_NOSQUASHFS" = "true" ] ; then (cd binary; echo live$'\n'live/filesystem.squashfs |cpio -o -H newc | gzip --fast) >./x2go-tce-filesystem.cpio.gz cat ./x2go-tce-initrd.img ./x2go-tce-filesystem.cpio.gz >./x2go-tce-initrd-with-fs.img || exit 1 rm ./x2go-tce-filesystem.cpio.gz # keeping these doesn't hurt, but feel free to rm them as well # rm ./x2go-tce-filesystem.squashfs ./x2go-tce-initrd.img fi fi if [ "$LBX2GO_IMAGETYPE" = "iso" ] || [ "$LBX2GO_IMAGETYPE" = "iso-hybrid" ] ; then genisoimage -o ./x2go-tce-squashfs-only.iso -R -J -graft-points live/filesystem.squashfs=./x2go-tce-filesystem.squashfs if [ -e ./live-image-$(echo $LBX2GO_ARCH | awk '{print $2}').hybrid.iso ] ; then ln ./live-image-$(echo $LBX2GO_ARCH | awk '{print $2}').hybrid.iso \ ./original-x2go-tce-live-image-$(echo $LBX2GO_ARCH | awk '{print $2}').hybrid.iso elif [ -e ./live-image-$(echo $LBX2GO_ARCH | awk '{print $2}').iso ] ; then ln ./live-image-$(echo $LBX2GO_ARCH | awk '{print $2}').iso \ ./original-x2go-tce-live-image-$(echo $LBX2GO_ARCH | awk '{print $2}').iso fi mv ./x2go-tce-filesystem.squashfs ./original-x2go-tce-filesystem.squashfs fi # create timestamp file stat -c %Y ./config/includes.chroot/lib >./x2go-tce-timestamp touch -m -d @$(cat x2go-tce-timestamp) x2go-tce-timestamp if [ "$LBX2GO_GETSRC" = "true" ] ; then if lb source debian ; then echo -e "Source files have been downloaded: '$LBX2GO_TCEDIR'" else echo -e "Source download failed: '$LBX2GO_TCEDIR'" fi else lb clean rm -rf ./cache fi else echo -e "Build failed: '$LBX2GO_TCEDIR'" if [ "$LBX2GO_IMAGETYPE" = "hdd" ] ; then echo "Looks like you tried to build an hdd image." echo "Older (pre-Debian-Buster) releases of live-build show a harmless error during" echo "the build, that can be safely ignored - but will still get you a 'Build failed'" echo "message in turn. So if you're running an older Debian release, you might want to" echo "look at the content of your build directory - maybe your build was successful" echo "after all, and this script was merely unable to detect it (computers are dumb)." fi fi cd .. fi