FDF / SSP. |
|
#!/bin/sh #======== # Screaming CuckooBroad Associates 2021 # -=[zkp]=- for gnu/linux/x11 # resides in /usr/bin (in ${PATH} for all users) # usage: $(zkp) alone returns kpZone path # user as parm 1 runs the install (requires root) UNX=/etc/kpzone/kData/unx [ -z $1 ] && echo -n ${UNX} && exit 0 [ $1 = root ] && HOM=/root || HOM=/home/$1 ln -sfn ${HOM}/kpZone /etc/kpzone cp -fp ${UNX}/sh/zkp /usr/bin cp -fp ${UNX}/= /usr/bin exit 0
========================================================= FrugalDriver Framework w/ SSP : Freqently Asked Questions the best live GNU/Linux/X11 : v0.022 =========================================================Q: What is this about ?
A: The FrugalDriver Framework is a means of administering bootable linux images in a robust, flexible, & secure way. FDF/SSP owes its existence to 3 fortuitous technical achievements of the Linux world, to wit:
1. The ability of GRUB2 to boot most modern ISO images directly 2. The practice of running Linux "live", meaning with its root filesystem mounted in RAM 3. The squashfs technology which can create compressed readonly mountable filesystems from a distros packagesMost modern GNU/Linux/X11 distros continue to have conventional installers, despite the live ISOs they ship being fully functional systems on their own. A traditional installation often becomes a snarly cumulative heap of package installs, configs, & upgrades which sometimes cannot be backed out or undone even with the most powerful packagemanagers & wellintentioned admin philosophies. With FDF/SSP all of this is simply unnecessary. The framework uses a not uncommon approach of livebooting the vanilla ISO, & then applying all discretionary user customisations with each boot in the form of curated package installs & freshly restored configs.
Q: So how does it work ?
A: An ordinary install of GRUB2 is done to a boot partition on any device: harddisk, flashdrive, whatever. A separate partition is established for the ISO images which are written unaltered to a Linux filesystem. Then a 3rd partition is used for the user specific control data, which are (1) salient portions of the ${HOME} directory, (2) packages from the supported repo converted to SSPs (Symlinkable Squashfs Packages) to be hooked into the live system, & (3) a user invoked script to apply the inittime customisations to the vanilla booted image. When a distro is booted, the filemanager is invoked to mount the control partition (if necessary) & drill down to the initthis.cfg script which is executed in a terminal. The script finishes by restarting the X11 session so when you login again you are presented with your fully customised system with your favourite packages & modifications, running live in system memory.
A: First & foremost FDF/SSP completely obviates the need for a conventional install. The system resides in RAM so changes to it arent persistent unless you explicitly want them to be. This results in a great deal of flexibility in the inevitable experimentation with packages & configs, without having to rely on a packagemanagers undo function or full system restores to recover from maladventurous customisations. The completely unaltered as-shipped system is available with every boot for reference, & the supported packagemanager is consulted so that all intended dependencies are met. Acquired packages are converted to SSPs which are mounted readonly & hooked into the live system not by union mounts but by ordinary symlinks.
With a little care FDF/SSP makes system updates swift & trivial. For example when the monthly snapshot of a rolling ISO appears, it is simply dropped into the ISO partition & booted. In many cases user installed packages dont have to be reacquired as there are no changes to them & they continue to work with the new ISO. Until they dont, whereupon its generally pretty obvious & they can be replaced as needed & not until. SSPs often prove to be surprisingly cross-distro, but when they arent you can merely unmount them or at the worst reboot & they are completely uninstalled.
One advantage of running live is being able selectively to backup parts of ${HOME}. At this writing my ${HOME} is nearly 54M [sic] because of the runtime caches & such, much of which is better off in RAM than on physical media. Yet the image of ${HOME} restored at boottime can be less than 800K, because it consists only of tested & necessary configs specifically copied there.
Finally, FDF/SSP works with virtually *any* distro, effectively turning any modern LiveISO into a standalone admin / rescue resource, which can also serve as the principal session. Because unaltered ISOs & a simple GRUB2 config are used, it doesnt matter where the user control data resides. This makes it fairly trivial to set up on-the-metal multibooting systems on any device(s) & migrate them to other media easily along with their succinct collections of user modifications.
Q: How is it done ?
A: Easy. First you need a GRUB2 stanza to boot your ISO. An Xubuntu example would be:
menuentry "-rwxr-xr-x xubuntu-core 22.10 from ISO (loop ISF)" { echo ooo set isofile="iso/iso2210/xubuntu-22.10-core-amd64.iso" loopback aloop (hd0,4)/ini_xubuntu/$isofile linux (aloop)/casper/vmlinuz audit=0 selinux=0 $vomit boot=casper live-media-path=/casper iso-scan/filename=/ini_xubuntu/$isofile fsck.mode=skip initrd (aloop)/casper/initrd }In the control partition establish a directory ini_xubuntu which has at minimum 4 items: a ${HOME} directory named for the user account, the user-invokable initthis.cfg (see example below), & the repo_deb & repo_ssp which contain the acquired & generated packages respectively. On debian distros downloaded debs can be copied from /var/cache/apt/archives to the repo_deb where they can be kept sorted by package for auditing purposes.
drwxrwxrwx 9 1000 1000 4096 Aug 2 12:16 . drwxr-xr-x 3 1000 1000 4096 Jul 31 07:16 .. drwxr-xr-x 3 xubuntu xubuntu 4096 Aug 2 11:56 repo_deb drwxr-xr-x 10 xubuntu xubuntu 4096 Aug 7 12:12 repo_ssp drwxr-xr-x 17 xubuntu xubuntu 4096 Jun 24 12:10 xubuntu lrwxrwxrwx 1 root root 37 Jul 31 07:16 initthis.cfg -> xubuntu/kpZone/kData/unx/initthis.cfg drwxrwxr-x 8 xubuntu xubuntu 4096 Nov 12 05:53 . drwxrwxr-x 3 xubuntu xubuntu 4096 Oct 18 09:42 .. drwxrwxr-x 2 xubuntu xubuntu 4096 Oct 19 08:08 .gftp drwxrwxr-x 2 xubuntu xubuntu 4096 Oct 18 12:27 .gkrellm drwxrwxr-x 2 xubuntu xubuntu 4096 Oct 18 10:21 .hexchat drwxrwxr-x 2 xubuntu xubuntu 4096 Oct 18 09:53 .mc drwxrwxr-x 2 xubuntu xubuntu 4096 Nov 12 05:51 .openbox drwxrwxr-x 2 xubuntu xubuntu 4096 Oct 18 09:42 .vfu -rw-r--r-- 1 xubuntu xubuntu 38304 Aug 13 16:18 chkservice_0.1-3_amd64.deb -rw-r--r-- 1 xubuntu xubuntu 62608 Apr 5 2018 qiv_2.3.1-1build1_amd64.deb -rw-r--r-- 1 xubuntu xubuntu 729348 Jun 21 2018 rxvt-unicode_9.22-4_amd64.deb -rw-r--r-- 1 xubuntu xubuntu 78532 Apr 5 2018 xfishtank_2.5-1build1_amd64.deb -rw-r--r-- 1 xubuntu xubuntu 733712 Jun 25 2013 xfwm4-themes_4.10.0-2_all.deb -rw-r--r-- 1 xubuntu xubuntu 171144 Jan 31 2018 xpenguins_2.2-11_amd64.debThe process is controlled entirely by 5 simple scripts: fdfctl, mksspfs, fdfact / fdflnk, & fdfget. fdfctl generally processes an entire directory at a time, calling mksspfs to convert distro sourced packages, running fdfact to activate the resulting SSPs (ie mounting them & symlinking them to the live filesystem via fdflnk), or maintaining symlinks in the top level of the repo_deb & repo_ssp, which determine whether a package will be installed by the initthis.cfg at startup. With fdfctl 0.23 an fdfget script has been introduced which can somewhat simplify the package acquisition process for supported distros.
#!/bin/sh #======== # fdfctl for frugaldriver framework # script to perform a function # on a directory of packages # functions (parm 1): # ssp : generate SSPs # sym : (default) establish symlinks one dirlevel up # del : delete symlinks one dirlevel up # get : acquire repo package (parm 2) # tgz : extract all tarballs # deb : install all packages: deb # rpm : install all packages: rpm # pac : install all packages: pkg.tar.xz # uid : recursively normalise ownerships # act : activate all SSPs @ optional subdir (parm 2) echo ooo echo fdfctl v0.24 date +%G%b%d%a.%P%H:%M:%S uname -srm [ ! -z $1 ] && FNC=$1 || FNC=sym [ ! -z $2 ] && MDR=$2 || MDR=ssp case ${FNC} in get ) $(zkp)/sh/fdfget $2 ;; deb ) sudo dpkg --install *.deb ;; rpm ) sudo rpm -v --install *.rpm ;; tgz ) find . -name "*.tgz" -exec sudo tar -C / --overwrite -xzf {} \; ;; pac ) sudo pacman -U --noconfirm --noprogressbar --cachedir . * 2>/dev/null ;; uid ) sudo chown -R $(id -u):$(id -g) . ;; * ) for i in * do case ${FNC} in del ) rm -f ../${i} ;; ssp ) $(zkp)/sh/mksspfs ${i} ;; act ) sudo $(zkp)/sh/fdfact ${MDR} ${i} ;; sym ) [ -f ${i} ] && ln -sf ${PWD##*/}/${i} ../${i} ;; * ) echo "$0: read source for doc" ;; esac done ;; esac exit 0 #!/bin/sh #======== echo ooo echo mksspfs v1.027 date +%G%b%d%a.%P%H:%M:%S uname -srm # script to rebundle software from gnu/linux repos # creates SSP: symlinkable squashfs package # (with no parm merely gens from prebuilt sspbuild) TMPDIR=/tmp/sspbuild if [ -z $1 ]; then PKG=sspbuild else rm -rf ${TMPDIR} ; mkdir ${TMPDIR} ; DIR=${PWD} for i in .tar.xz .tar.zst .deb .xpak .rpm .tbz2 .tazpkg .eopkg .xbps do if echo $1 | grep -i ${i}$ ; then PKG=${1%%${i}} ; cd ${TMPDIR} case "${i}" in ".tar.xz" | ".tar.zst" ) #--( archlinux )--# for SUF in tar.xz tar.zst do case "${SUF}" in "tar.xz" ) TYP="-J" ;; "tar.zst" ) TYP="-I zstd" ;; esac tar ${TYP} -xvf ${DIR}/$1 && rm -f .* >/dev/null 2>&1 done ;; ".deb" ) #--( debian )--# for SUF in gz xz lzma zst do case "${SUF}" in "gz" ) TYP="-z" ;; "xz" ) TYP="-J" ;; "lzma" ) TYP="--lzma" ;; "zst" ) TYP="-I zstd" ;; esac ARG=data.tar.${SUF} ar -xv ${DIR}/$1 ${ARG} ; tar ${TYP} -xvf ${ARG} 2>/dev/null && rm -f ${ARG} done ;; ".xpak" ) #--( gentoo )--# tar -xvf ${DIR}/$1 ;; ".rpm" ) #--( red space hat )--# command -v bsdtar && bsdtar -xf - <${DIR}/$1 || rpm2cpio ${DIR}/$1 | cpio -idm ;; ".tbz2" ) #--( sabayon )--# tar -xjvf ${DIR}/$1 ;; ".tazpkg" ) #--( slitaz )--# cpio -iF ${DIR}/$1 && unlzma fs.cpio.lzma && cpio -iF fs.cpio && rm -f * ; mv fs/* . && rmdir fs ;; ".eopkg" ) #--( solus )--# unzip ${DIR}/$1 && unxz install.tar.xz && tar -xvf install.tar && rm -f *.xml install.tar ;; ".xbps" ) #--( void )--# tar -I zstd -xvf ${DIR}/$1 && rm -f *.plist >/dev/null 2>&1 ;; * ) #--( oops )--# echo error: ${i} ;; esac fi done fi # singlethreaded tar while KPID=$(pidof tar) do : done # here we go ... chmod 755 ${TMPDIR} rm -rf /tmp/${PKG}.ssp echo 'executing mksquashfs ...' mksquashfs ${TMPDIR} /tmp/${PKG}.ssp -all-root -comp xz ls -al /tmp/${PKG}*.ssp* exit 0 #!/bin/sh #======== # fdfact v0.03 for frugaldriver framework # activates specified SSP (parm 2) # at specified mountpoint below /var/fdf (parm 1) # run as root MPT=/var/fdf/$1/$2 mkdir -p ${MPT} mount -t squashfs -o ro $2 ${MPT} 2>/dev/null $(zkp)/sh/fdflnk ${MPT} exit 0 #!/bin/sh #======== # echo ooo env printf "fdflnk v0.08 : $1\n" # date +%G%b%d%a.%P%H:%M:%S # uname -srm # run as root # script to symlink a directory tree to root filesystem [ -d $1 ] && cd $1 || exit 1 for i in $(find) do if [ "${i}" != "." ]; then RES=$1/${i} # echo ${RES} ${i} if [ -h ${RES} ]; then cp -fpP ${RES} /${i} elif [ -d ${i} ]; then [ ! -d /${i} ] && mkdir /${i} && chmod 755 /${i} else ln -sf ${RES} /${i} fi fi done exit 0 #!/bin/sh #======== # fdfget for frugaldriver framework # script to acquire &/or activate an optional package # echo ooo msgtag="fdfget v0.10 :" # date +%G%b%d%a.%P%H:%M:%S # uname -srm [ -z $1 ] && exit 1 || pkg_name=$1 fdf_base=/tmp/.X11-snog/init rssp=${fdf_base}/repo_ssp/.optional # no ssp means reacquire if [ ! -d ${rssp}/.${pkg_name} ]; then # determine & profile the distro pmdir1=/var/cache/dnf # fedora pmdir2=/var/cache/pacman/pkg # arch btw pmdir3=/var/cache/zypp/packages # opensuse pmdir4=/var/cache/apt/archives # debianesque if [ -d ${pmdir1} ]; then pm_base=${pmdir1} pkg_suf=rpm clean_command="dnf clean packages" get_command="dnf install --downloadonly" elif [ -d ${pmdir2} ]; then pm_base=${pmdir2} pkg_suf=zst clean_command="rm -f ${pm_base}/*.${pkg_suf}" get_command="pacman -Syw" elif [ -d ${pmdir3} ]; then pm_base=${pmdir3} pkg_suf=rpm clean_command="rm -rf ${pm_base}/*" get_command="zypper in -d --no-recommends" elif [ -d ${pmdir4} ]; then pm_base=${pmdir4} grep -iq altlinux /etc/os-release [ $? = 0 ] && pkg_suf=rpm || pkg_suf=deb clean_command="rm -f ${pm_base}/*.${pkg_suf}" get_command="apt-get install -d" else echo unknown distro ; exit 1 fi # clear fdf/pm & install rm -f /tmp/*.ssp sudo ${clean_command} echo ${msgtag} issuing command: ${get_command} ${pkg_name} sudo ${get_command} ${pkg_name} return_code=$? echo ${msgtag} received return code: ${return_code} if [ ${return_code} = 0 ]; then # populate the packages rpkg=${fdf_base}/repo_${pkg_suf}/.void rm -rf ${rpkg}/.${pkg_name} && mkdir -p ${rpkg}/.${pkg_name} cd ${rpkg}/.${pkg_name} && find ${pm_base}/ -name *.${pkg_suf} -exec cp -fp {} . \; if [ $(ls | wc -l) != 0 ]; then # gen & deploy the ssps $(zkp)/sh/fdfctl ssp && mkdir -p ${rssp}/.${pkg_name} cd ${rssp}/.${pkg_name} && cp -fp /tmp/*.ssp . fi fi fi # activate the ssps echo ${msgtag} activating ${pkg_name} cd ${rssp}/.${pkg_name} && $(zkp)/sh/fdfctl act # clean up rm -f /tmp/*.ssp exit 0Q: What exactly does an initthis.cfg look like ?
A: On Xubuntu-core, for example, it would look like this:
#!/bin/sh #======== # initthis.cfg for Xubuntu-minimal 24.04 # runs xubuntu in frugal mode from live install media # user invoked via Thunar from partition mounted via udisksctl mount -b # customises session from persistent user settings, repos, & scripted configs # ================= # standard prologue # ================= env printf "...\n" env printf "initthis.cfg in progress\n" # echo -e "\033[1;34m$(date +%G%b%d%a.%P%H:%M:%S)\033[0m" env printf "\033[1;34m$(date +%G%b%d%a.%P%H:%M:%S)\033[0m\n" env printf "\033[1;32m .SNOG is Not Overwhelmingly GNUlike. \033[0m\n" env printf "\033[1;32m _______ _______ _______ _______ \033[0m\n" env printf "\033[1;32m | __|| | || || __| \033[0m\n" env printf "\033[1;32m |__ || || - || | | \033[0m\n" env printf "\033[1;32m |_______||__|____||_______||_______| Linux \033[0m\n" # ============================= # ${HOME} directory linkage &c. # ============================= # snoginit sudo pkill -x Thunar sudo pkill -x xfconfd cd $(dirname $0) ; INI=/tmp/.X11-snog ; mkdir ${INI} ; ln -sfn ${PWD} ${INI}/init # homedir cp -fpr ${USER} /home sudo ${HOME}/kpZone/kData/unx/sh/zkp ${USER} # sysreq sudo sysctl kernel.sysrq=1 # ========================= # boottime package installs # ========================= # tarballs cd ${INI}/init/repo_tgz && $(zkp)/sh/fdfctl tgz >/dev/null 2>&1 # packages cd ${INI}/init/repo_deb ls -ahlGL *.deb 2>/dev/null && $(zkp)/sh/fdfctl deb >/dev/null 2>&1 & # ls -ahlGL *.deb 2>/dev/null && xterm -geom -264-100 -fg blue -e sudo dpkg --install *.deb # symlinkable squashfs packages cd ${INI}/init/repo_ssp && $(zkp)/sh/fdfctl act # ============ # user configs # ============ # systemwide sudo $(zkp)/sh/rc_init # thunar pugd fail udisksctl mount -b /dev/sdb1 # ============================== # give control to the ui session # ============================== # pause grep -iq fdf.log /proc/cmdline && read aparm # refresh xfce4-session-logout # sudo pkill -x xfce4-terminal # sudo pkill -x lightdm env printf "\033[1;34minitthis.cfg complete\033[0m\n" exit 0Q: What does the booted system look like ?
A: One difference visavis a conventional install is that the installed packages are mounted as loop devices:
Filesystem Size Used Avail Use% Mounted on udev 939M 0 939M 0% /dev tmpfs 193M 1.3M 191M 1% /run /dev/sda5 110G 93G 12G 89% /isodevice /dev/loop0 1.5G 1.5G 0 100% /cdrom /dev/loop1 1.4G 1.4G 0 100% /rofs /cow 962M 43M 919M 5% / tmpfs 962M 1.7M 960M 1% /dev/shm tmpfs 5.0M 8.0K 5.0M 1% /run/lock tmpfs 962M 0 962M 0% /sys/fs/cgroup tmpfs 962M 240K 962M 1% /tmp /dev/loop2 384K 384K 0 100% /opt/ssp/amx-ristretto_0.8.0-0mx150+1_amd64.ssp /dev/loop3 128K 128K 0 100% /opt/ssp/arc-beaver-0.4.1-3-x86_64.pkg.ssp /dev/loop4 128K 128K 0 100% /opt/ssp/chkservice_0.1-3_amd64.ssp /dev/loop5 1.2M 1.2M 0 100% /opt/ssp/chromium-codecs.ssp /dev/loop6 640K 640K 0 100% /opt/ssp/gftp-common_2.0.19-5_amd64.ssp /dev/loop7 256K 256K 0 100% /opt/ssp/gftp-gtk_2.0.19-5_amd64.ssp /dev/loop8 128K 128K 0 100% /opt/ssp/gftp-text_2.0.19-5_amd64.ssp /dev/loop9 128K 128K 0 100% /opt/ssp/gftp_2.0.19-5_all.ssp /dev/loop10 768K 768K 0 100% /opt/ssp/gkrellm_2.3.10-2_amd64.ssp /dev/loop11 128K 128K 0 100% /opt/ssp/gkrellmoon64.ssp /dev/loop12 1.3M 1.3M 0 100% /opt/ssp/hexchat-common_2.14.2-2_all.ssp /dev/loop13 384K 384K 0 100% /opt/ssp/hexchat_2.14.2-2_amd64.ssp /dev/loop14 128K 128K 0 100% /opt/ssp/libgnutls-openssl27_3.6.4-2ubuntu1_amd64.ssp /dev/loop15 256K 256K 0 100% /opt/ssp/libgtksourceview2.0-0_2.10.5-2ubuntu2_amd64.ssp /dev/loop16 640K 640K 0 100% /opt/ssp/libgtksourceview2.0-common_2.10.5-2ubuntu2_all.ssp /dev/loop17 128K 128K 0 100% /opt/ssp/libncurses5_6.1+20180210-4ubuntu1_amd64.ssp /dev/loop18 128K 128K 0 100% /opt/ssp/libntlm0_1.5-1_amd64.ssp /dev/loop19 128K 128K 0 100% /opt/ssp/libobrender32v5_3.6.1-7ubuntu2_amd64.ssp /dev/loop20 128K 128K 0 100% /opt/ssp/libobt2v5_3.6.1-7ubuntu2_amd64.ssp /dev/loop21 128K 128K 0 100% /opt/ssp/libssh2-1_1.8.0-2_amd64.ssp /dev/loop22 1.8M 1.8M 0 100% /opt/ssp/mc-data_3%3a4.8.21-1_all.ssp /dev/loop23 512K 512K 0 100% /opt/ssp/mc_3%3a4.8.21-1_amd64.ssp /dev/loop24 256K 256K 0 100% /opt/ssp/obconf_1%3a2.0.4+git20150213-2_amd64.ssp /dev/loop25 384K 384K 0 100% /opt/ssp/openbox_3.6.1-7ubuntu2_amd64.ssp /dev/loop26 78M 78M 0 100% /opt/ssp/opera-sandbox.ssp /dev/loop27 128K 128K 0 100% /opt/ssp/qiv_2.3.1-1build1_amd64.ssp /dev/loop28 1.3M 1.3M 0 100% /opt/ssp/rxvt-unicode_9.22-4_amd64.ssp /dev/loop29 128K 128K 0 100% /opt/ssp/trcm-customstylescript.ssp /dev/loop30 18M 18M 0 100% /opt/ssp/trcm-opera1216.ssp /dev/loop31 128K 128K 0 100% /opt/ssp/trcm-theme_NOX.ssp /dev/loop32 128K 128K 0 100% /opt/ssp/trcm-theme_zoncolorEvening.ssp /dev/loop33 1.8M 1.8M 0 100% /opt/ssp/trcmcore.ssp /dev/loop34 256K 256K 0 100% /opt/ssp/vfu_4.15-trcm_amd64.ssp /dev/loop35 67M 67M 0 100% /opt/ssp/vivaldi-sandbox.ssp /dev/loop36 128K 128K 0 100% /opt/ssp/xfishtank_2.5-1build1_amd64.ssp /dev/loop37 256K 256K 0 100% /opt/ssp/xpenguins_2.2-11_amd64.ssp tmpfs 193M 8.0K 193M 1% /run/user/999 /dev/sdb1 2.3G 1.9G 398M 83% /media/xubuntu/UD01_sysQ: How would you sum up the philosophy of the FrugalDriver Framework ?
A: FDF/SSP is the result of running GNU/Linux/X11 according to the time tested & venerable principles:
1. Solve the Right Problem 2. Start with Something You Know Works 3. Always be Able to Go Back, & Failing that, be Able to Start Over"It is easier to start with something fixed & break it a piece at a time, than it is to start with something broken & fix it a piece at a time." --me
|
|
part of the CircleOmega organisation |