#!/bin/sh set -e UPDATE_TO="${UPDATE_TO:-no}" TIMESTAMP_SAVE="$(date -u +%Y%m%dT%H%M%SZ)" TEMP_DIR="/dev/shm/temp-livegui-save-changes" mkdir -p ${TEMP_DIR}/root.dir if [ "${UPDATE_TO}" != "no" ] && [ -f "${UPDATE_TO}" ] && [[ "$(file -b ${UPDATE_TO})" =~ "ISO 9660 CD-ROM filesystem data" ]]; then echo "Updating/saving persistent image against file \"${UPDATE_TO}\"..." mkdir -p ${TEMP_DIR}/{iso,livecd} mount -o loop "${UPDATE_TO}" ${TEMP_DIR}/iso mount -t squashfs ${TEMP_DIR}/iso/image.squashfs ${TEMP_DIR}/livecd TIMESTAMP_ORIG="$(ls -v ${TEMP_DIR}/iso/snapshots | tail -n 1 | sed -e 's/gentoo-//' -e 's/.tar.bz2.DIGESTS//')" else if [ "${UPDATE_TO}" != "no" ]; then UPDATE_TO="no" fi echo "Saving persistent image against current environment..." TIMESTAMP_ORIG="$(ls -v /mnt/cdrom/snapshots | tail -n 1 | sed -e 's/gentoo-//' -e 's/.tar.bz2.DIGESTS//')" fi mount -o bind / ${TEMP_DIR}/root.dir rsync -XxAaHm --exclude /tmp/ --exclude /var/tmp/ --exclude /dev/ \ $(mountpoint -q /home && echo -n '--exclude /home/') \ $([ "${UPDATE_TO}" != "no" ] && \ echo -n '--exclude /bin/ --exclude /lib/ --exclude /lib64/ --exclude /opt/ --exclude /sbin/ --exclude /usr/ --exclude /var/db/pkg/') \ --compare-dest=/mnt/livecd ${TEMP_DIR}/root.dir/ ${TEMP_DIR}/new.dir umount ${TEMP_DIR}/root.dir cd ${TEMP_DIR}/new.dir #TODO: find a safer line to replace this for i in `find . -type d | sort -r`; do if [ -z "$(ls -A ${i})" ]; then rmdir "${i}"; fi; done; if [ "${UPDATE_TO}" != "no" ]; then cd etc for i in `find . -type f`; do if [ -f "${TEMP_DIR}/livecd/etc/${i}" ] && ! [[ "$(md5sum ${TEMP_DIR}/livecd/etc/${i})" =~ "$(md5sum ${i} | sed -e 's/ .*//')" ]]; then cp -a "${TEMP_DIR}/livecd/etc/${i}" $(echo -n "${i}" | sed -E "s@($(dirname ${i}))(\/)([^\/]*$)@\1/._cfg0001_\3@") fi done mkdir -p ${TEMP_DIR}/overlay/{work,upper,merge} mount -t overlay overlay -olowerdir=${TEMP_DIR}/new.dir:${TEMP_DIR}/livecd,workdir=${TEMP_DIR}/overlay/work,upperdir=${TEMP_DIR}/overlay/upper ${TEMP_DIR}/overlay/merge mount -t proc /proc ${TEMP_DIR}/overlay/merge/proc mount --rbind /sys ${TEMP_DIR}/overlay/merge/sys mount --bind /dev ${TEMP_DIR}/overlay/merge/dev mount --bind /dev/pts ${TEMP_DIR}/overlay/merge/dev/pts mount --bind /dev/mqueue ${TEMP_DIR}/overlay/merge/dev/mqueue mount -t tmpfs tmpfs ${TEMP_DIR}/overlay/merge/dev/shm mount --bind /run ${TEMP_DIR}/overlay/merge/run for i in `grep -Eh "^(DISTDIR|PKGDIR|location)" /etc/portage/make.conf /etc/portage/repos.conf/* | sed -e 's/.*=//' -e 's/[" ]//g'`; do [ -d "${i}" ] && mkdir -p ${TEMP_DIR}/overlay/merge${i} && mount -o bind ${i} ${TEMP_DIR}/overlay/merge${i} done cd ${TEMP_DIR}/overlay/merge/var rm db && ln -s ../usr/livecd/db db CHROOT_EMERGE='' if [ -f "${TEMP_DIR}/overlay/merge/usr/bin/emerge" ]; then CHROOT_EMERGE="${CHROOT_EMERGE} && source /etc/profile && emerge --sync && emerge -vquakND @world" CHROOT_EMERGE="${CHROOT_EMERGE} && (([ -L '/usr/bin/smart-live-rebuild' ] && smart-live-rebuild -- -aq) || true)" CHROOT_EMERGE="${CHROOT_EMERGE} && etc-update" fi until chroot ${TEMP_DIR}/overlay/merge /bin/bash -c "etc-update${CHROOT_EMERGE}"; do echo "chroot, etc-update, or package update did not exit cleanly... fix what failed in this chroot shell, exit 0, then try again." chroot ${TEMP_DIR}/overlay/merge /bin/bash done mkdir -p ${TEMP_DIR}/final.dir cd ${TEMP_DIR}/final.dir rsync -XxAaHm --exclude /tmp/ --exclude /var/tmp/ --exclude /dev/ \ $(mountpoint -q /home && echo -n '--exclude /home/') \ --compare-dest=${TEMP_DIR}/livecd ${TEMP_DIR}/overlay/merge/ ${TEMP_DIR}/final.dir umount -R ${TEMP_DIR}/{overlay/merge,livecd,iso} #TODO: find a safer line to replace this for i in `find . -type d | sort -r`; do if [ -z "$(ls -A ${i})" ]; then rmdir "${i}"; fi; done; fi mksquashfs . ../persist-${TIMESTAMP_ORIG}-${TIMESTAMP_SAVE}.squashfs -comp gzip -b 131072 echo "Persistent image saved as ${TEMP_DIR}/persist-${TIMESTAMP_ORIG}-${TIMESTAMP_SAVE}.squashfs ... Copy it to your boot medium."