Sunday, 10 April 2022

Custom live Linux USB image: Working around locked down ThinkPad

At work we are getting pushed into a hot-desking setup and each member of staff is being moved onto a thin client ThinkPad. Of course a thin client is nothing more than a customised and stripped down Windows 10 build that connects to the firm's virtual desktop infrastructure, via a combination of CiscoConnect and VMWare Horizon client.

Since we're being forced to carry the ThinkPad to and from the hot-desk office, I'm going to use the ThinkPad for my own dev purposes en route. The ThinkPad's BIOS is not locked down so we can get into the boot menu via F12 or the BIOS setup via Enter but setting my own dev environment is not straight forward.

The ThinkPad is a reasonably spec'd contemporary corpoarte laptop running a quad core 11th Gen Intel i5-1145G7 with 16GB of RAM and a 512GB SSD running some form of Windows 10. In years gone by, we'd simply boot a live USB image and then carve out a slice on the NFTS disk but with Windows 10 we have bitlocker that requires a key to access the partition - this essentially prevents us from partitioning the SSD.

This doesn't prevent us from achieving our goal though and simply means we have to continue to use the live USB image with a persistance. Whilst a standard live image is useful for basic tasks, we can customise a base image with specific development packages along with creating an overlay system.

Creating a custom live image can be achieved through a remix and using a flattened file:
https://github.com/whatdoineed2do/fedora-remix $ ksflatten --config kickstarts/remix-cinnamon.ks --output fedora-kickstarts.ks $ livemedia-creator \ --resultdir=results/remix --make-iso --no-virt \ --project=Fedora --releasever=35 --ks=fedora-kickstarts.ks # and test the output image $ qemu-kvm -m 2560 -cdrom result/remix/images/boot-efi.iso
The process of generating the custom image is a lengthy process, even with a wired Gbit network connection running on a core i7-1165G7 machine with an SSD - the generation of the USB image taking least 80 minutes: downloading the RPMs, installing, building the squashfs filesystem and then generating the final ISO image. Once built, installing the image to an USB stick is still a little tricky. The stock Fedora 35 livecd-iso-to-disk util generates USB sticks that were NOT bootable although livemedia-creator on same ISO was succesful but will use the entire storage of the USB device.

Using the livecd-tools from the development repo resolves the boot issue and only uses the space of USB image, allowing us to create additional partitions on the remaining free USB space.
$ git clone https://github.com/livecd-tools/livecd-tools $ ./livecd-tools/tools/livecd-iso-to-disk.sh \ --format 8196,ext4 --efi --reset-mbr \ --home-size-mb 2048 --unencrypted-home \ fedora-live-image.iso /dev/sdx # creates 3 partitions created # force re-read of partition table and create our data partition of relevent size and write out $ partprobe /dev/sdx $ fdisk /dev/sdx ... $ mkfs.ext4 /dev/sdx4
With this step we have a usable live USB stick, with a persistent home directory, that we can use on the ThinkPad.

Booting the live image from a 16Gb USB stick, we inspect the system to reveal:
$ inxi -F System: Host: localhost-live Kernel: 5.16.18-200.fc35.x86_64 arch: x86_64 bits: 64 Desktop: Cinnamon v: 5.2.7 Distro: Fedora release 35 (Thirty Five) Machine: Type: Convertible System: LENOVO product: 20VLS1JC28 v: ThinkPad L13 Yoga Gen 2 serial: >superuser required< Mobo: LENOVO model: 20VLS1JC28 v: SDK0J40697 WIN serial: >superuser required< UEFI: LENOVO v: R1PET19W (1.11 ) date: 12/08/2021 Battery: ID-1: BAT0 charge: 29.1 Wh (63.1%) condition: 46.1/46.0 Wh (100.2%) volts: 15.7 min: 15.4 CPU: Info: quad core model: 11th Gen Intel Core i5-1145G7 bits: 64 type: MT MCP cache: L2: 5 MiB Speed (MHz): avg: 688 min/max: 400/4400 cores: 1: 631 2: 569 3: 685 4: 938 5: 908 6: 524 7: 585 8: 664 Graphics: Device-1: Intel TigerLake-LP GT2 [Iris Xe Graphics] driver: i915 v: kernel Device-2: Chicony ThinkPad T490 Webcam type: USB driver: uvcvideo Display: x11 server: X.Org v: 1.20.14 driver: X: loaded: modesetting unloaded: fbdev,vesa gpu: i915 resolution: 1920x1080~60Hz OpenGL: renderer: Mesa Intel Xe Graphics (TGL GT2) v: 4.6 Mesa 21.3.8 Audio: Device-1: Intel Tiger Lake-LP Smart Sound Audio driver: snd_hda_intel Sound Server-1: ALSA v: k5.16.18-200.fc35.x86_64 running: yes Sound Server-2: PipeWire v: 0.3.49 running: yes Network: Device-1: Intel Wi-Fi 6 AX201 driver: iwlwifi IF: wlp0s20f3 state: up mac: 84:14:xx:xx:xx:xx Device-2: Intel Ethernet I219-LM driver: e1000e IF: enp0s31f6 state: down mac: 48:2a:xx:xx:xx:xx Bluetooth: Device-1: Intel AX201 Bluetooth type: USB driver: btusb Report: bt-adapter ID: hci0 state: up address: 84:14:xx:xx:xx:xx Drives: Local Storage: total: 491.5 GiB used: 15.36 GiB (3.1%) ID-1: /dev/nvme0n1 vendor: Toshiba model: N/A size: 476.94 GiB ID-2: /dev/sda type: USB vendor: SanDisk model: Cruzer Blade size: 14.56 GiB Partition: ID-1: / size: 7.78 GiB used: 7.04 GiB (90.5%) fs: ext4 dev: /dev/dm-0 Swap: ID-1: swap-1 type: zram size: 8 GiB used: 0 KiB (0.0%) dev: /dev/zram0 Sensors: System Temperatures: cpu: 1.0 C mobo: N/A Fan Speeds (RPM): cpu: 33280 fan-1: Info: Processes: 286 Uptime: 14m Memory: 15.33 GiB used: 2.54 GiB (16.6%) Shell: Bash inxi: 3.3.14
The system usage above is generated with firefox running but we can see there is plenty of resources available.

VMWare Horizon

It can be useful to run the live Linux USB image even when at the office such as when theres a need for a lab or isolated environment but still with easy access to the work infrastructure. Obviously, we can do this with running VMWare Horizon off the live image - having the local dependancies for installing VMWare Horizon is the easiest way to achieve this rather than embedding this into the live image itself, particularly if the remote VMWare Horizon server requirements change.

The latest Fedora 35 the lastest version of python (version 3.10) is incompatable with the VMWare Horizon installer but this an easy fix.
$ mkdir ~/vmware/ # pull down compat python $ dnf --downloadonly --downloaddir=~/vmware install python3.9 # Obtain VMware with installation parameters here
To aid usability, create an install/run script that can also be used by a desktop icon launcher - we add desktop notifications via a libnotify util.
$ cat > ~/vmware/vmware-view.sh << EOF #!/bin/bash WHERE=$(dirname $0) which vmware-view 2>&1 >/dev/null if [ $? -ne 0 ]; then notify-send "VMware Horizon" "installing..." TK_8=${WHERE}/tk-8.6.10-7.fc35.x86_64.rpm PYTHON_39=${WHERE}/python3.9-3.9.12-1.fc35.x86_64.rpm VMHORIZON=${WHERE}/VMware-Horizon-Client-2203-8.5.0-19586897.x64.bundle # sudo dnf -y install python3.9 && cd /usr/bin && rm python3 && ln -s python3.9 python3 echo "installing Python 3.9" sudo rpm -i ${TK_8} ${PYTHON_39} [ $? -ne 0 ] && notify-send -u critical "VMware Horizon" "failed to install deps..." && exit -1 (cd /usr/bin && sudo ln -sf python3.9 python3) echo "installing VMWare Horizon" && \ sudo env TERM=dumb VMWARE_EULAS_AGREED=yes \ ${VMHORIZON} \ --console --required \ --set-setting vmware-horizon-integrated-printing vmipEnable no \ --set-setting vmware-horizon-usb usbEnable yes \ --set-setting vmware-horizon-smartcard smartcardEnable no \ --set-setting vmware-horizon-rtav rtavEnable yes \ --set-setting vmware-horizon-tsdr tsdrEnable no \ --set-setting vmware-horizon-scannerclient scannerEnable no \ --set-setting vmware-horizon-serialportclient serialportEnable no \ --set-setting vmware-horizon-mmr mmrEnable yes \ --set-setting vmware-horizon-media-provider mediaproviderEnable no \ --set-setting vmware-horizon-teams-optimization teamsOptimizationEnable yes (cd /usr/bin && sudo ln -sf python3.10 python3) which vmware-view 2>&1 >/dev/null [ $? -ne 0 ] && notify-send -u critical "VMware Horizon" "failed to install..." && exit -1 fi notify-send "VMware Horizon" "starting..." exec vmware-view "$@" EOF $chmod a+x ~/vmware/vmware-view.sh
Once succesfully installed, we can further tailor how VMWare Horizon runs and as we need:
# Add a desktop icon $ cat > ~/Desktop/VMWare\ Horizon.desktop << EOF [Desktop Entry] Name=VMWare Horizon #Exec=vmware-view --serverURL==vmdesktop.foo.com --tokenUserName=foobar --userName=foobar --password=letmein123 --domainName="domain.foo.com" --desktopSize=large Exec=~/vmware/vmware-view.sh --tokenUserName=foobar Comment= Terminal=false Icon=vmware Type=Application EOF # See configuration reference - tokenUserName is not available as a default $ cat > ~/.vmware/view-preferences << EOF view.autoConnectBroker = 'vmdesktop.foo.com' view.defaultBroker = 'vmdesktop.foo.com' view.defaultUser = 'foobar' view.defaultDomain = 'domain.foo.com' view.defaultPassword = 'letmein123' view.defaultDesktopSize = '3' view.deviceID = '55:44:33:22:11:00' EOF $ chmod 600 ~/.vmware/view-preferences
Since this installation is not persisted, it will run in RAM. Similar steps can be applied for Zoom which at this point has no non-standard dependencies.

Further Customisations

Upon restart (first time is a little slower) you can set the keyboard layout to non-US format.
# start firefox (slow first time) and force the browser to use mem for cache and the vaapi h/w accelerated backend for video playback about:config -> browser.cache.disk.enable = false -> media.ffmpeg.vaapi.enabled = true # fix prompt $ echo 'export PS1="[\j] \u: \e[92m\]\w\e[0m\] $ "' >> ~/.bashrc # disable SELinux $ sudo setenforce 0

So, How does it run

In general it works well. Booting to the (auto logging) desktop takes about 65 seconds from the point of power on, hitting F12 and selecting the kernel from grub.

I use this en-route to/from work on my own non-work coding projects since I'd be carrying another laptop anyway. Using the live image off a USB stick works as I simply put a few hair ties together and hook the USB stick to the screen hinge so its always attached/available. Typically I'm working on C/C++ projects that is on the ext4 partition. As we are writing a lot of small files when compiling etc you do notice performance is a little slow at times. Browsing using firefox is not bad but again be aware of the small writes aren't great even with the disk cache all in RAM as above.

Running IntelliJ is very painful and slow though but this is pretty much because of the number of apparent disk reads/writes/indexing it makes to its underlying caches. Compiling java directly is fine - even with the persistent home directory, I've moved the maven/gradle caches onto the ext4 partition
although as with the rest of the tooling, it never seems to be a RAM exhaustion problem - the machine's 16GB of ram seemingly more than enough.

Of course, we could put this image onto an external SSD but you'd have to be lugging around a SSD and at which point we might as well go all out and install Linux to the external SSD.

Custom Kickstart file

Generated based on https://github.com/tierratelematics/fedora-remix
# Generated by pykickstart v3.34 #version=DEVEL # X Window System configuration information xconfig --startxonboot # Keyboard layouts keyboard 'gb' # Root password rootpw --iscrypted --lock locked # System language lang en_GB.UTF-8 # Shutdown after installation shutdown # Network information network --bootproto=dhcp --device=link --activate # Firewall configuration firewall --enabled --service=mdns # Use network installation url --mirrorlist="https://mirrors.fedoraproject.org/mirrorlist?repo=fedora-$releasever&arch=$basearch" repo --name="fedora" --mirrorlist=https://mirrors.fedoraproject.org/mirrorlist?repo=fedora-$releasever&arch=$basearch repo --name="updates" --mirrorlist=https://mirrors.fedoraproject.org/mirrorlist?repo=updates-released-f$releasever&arch=$basearch repo --name="fedora-cisco-openh264" --metalink=https://mirrors.fedoraproject.org/metalink?repo=fedora-cisco-openh264-$releasever&arch=$basearch repo --name="rpmfusion-free" --metalink=https://mirrors.rpmfusion.org/metalink?repo=free-fedora-$releasever&arch=$basearch repo --name="rpmfusion-free-updates" --metalink=https://mirrors.rpmfusion.org/metalink?repo=free-fedora-updates-released-$releasever&arch=$basearch repo --name="rpmfusion-nonfree" --metalink=https://mirrors.rpmfusion.org/metalink?repo=nonfree-fedora-$releasever&arch=$basearch repo --name="rpmfusion-nonfree-updates" --metalink=https://mirrors.rpmfusion.org/metalink?repo=nonfree-fedora-updates-released-$releasever&arch=$basearch repo --name="rpmfusion-free-tainted" --metalink=https://mirrors.rpmfusion.org/metalink?repo=free-fedora-tainted-$releasever&arch=$basearch repo --name="rpmfusion-nonfree-tainted" --metalink=https://mirrors.rpmfusion.org/metalink?repo=nonfree-fedora-tainted-$releasever&arch=$basearch # System timezone timezone Europe/London # SELinux configuration selinux --enforcing # System services services --disabled="sshd,NetworkManager-wait-online" --enabled="NetworkManager" # System bootloader configuration bootloader --location=none # Clear the Master Boot Record zerombr # Partition clearing information clearpart --all # Disk partitioning information part / --fstype="ext4" --size=8500 part / --size=8192 %post # FIXME: it'd be better to get this installed from a package cat > /etc/rc.d/init.d/livesys << EOF #!/bin/bash # # live: Init script for live image # # chkconfig: 345 00 99 # description: Init script for live image. ### BEGIN INIT INFO # X-Start-Before: display-manager chronyd ### END INIT INFO . /etc/init.d/functions if ! strstr "\`cat /proc/cmdline\`" rd.live.image || [ "\$1" != "start" ]; then exit 0 fi if [ -e /.liveimg-configured ] ; then configdone=1 fi exists() { which \$1 >/dev/null 2>&1 || return \$* } livedir="LiveOS" for arg in \`cat /proc/cmdline\` ; do if [ "\${arg##rd.live.dir=}" != "\${arg}" ]; then livedir=\${arg##rd.live.dir=} continue fi if [ "\${arg##live_dir=}" != "\${arg}" ]; then livedir=\${arg##live_dir=} fi done # enable swaps unless requested otherwise swaps=\`blkid -t TYPE=swap -o device\` if ! strstr "\`cat /proc/cmdline\`" noswap && [ -n "\$swaps" ] ; then for s in \$swaps ; do action "Enabling swap partition \$s" swapon \$s done fi if ! strstr "\`cat /proc/cmdline\`" noswap && [ -f /run/initramfs/live/\${livedir}/swap.img ] ; then action "Enabling swap file" swapon /run/initramfs/live/\${livedir}/swap.img fi mountPersistentHome() { # support label/uuid if [ "\${homedev##LABEL=}" != "\${homedev}" -o "\${homedev##UUID=}" != "\${homedev}" ]; then homedev=\`/sbin/blkid -o device -t "\$homedev"\` fi # if we're given a file rather than a blockdev, loopback it if [ "\${homedev##mtd}" != "\${homedev}" ]; then # mtd devs don't have a block device but get magic-mounted with -t jffs2 mountopts="-t jffs2" elif [ ! -b "\$homedev" ]; then loopdev=\`losetup -f\` if [ "\${homedev##/run/initramfs/live}" != "\${homedev}" ]; then action "Remounting live store r/w" mount -o remount,rw /run/initramfs/live fi losetup \$loopdev \$homedev homedev=\$loopdev fi # if it's encrypted, we need to unlock it if [ "\$(/sbin/blkid -s TYPE -o value \$homedev 2>/dev/null)" = "crypto_LUKS" ]; then echo echo "Setting up encrypted /home device" plymouth ask-for-password --command="cryptsetup luksOpen \$homedev EncHome" homedev=/dev/mapper/EncHome fi # and finally do the mount mount \$mountopts \$homedev /home # if we have /home under what's passed for persistent home, then # we should make that the real /home. useful for mtd device on olpc if [ -d /home/home ]; then mount --bind /home/home /home ; fi [ -x /sbin/restorecon ] && /sbin/restorecon /home if [ -d /home/liveuser ]; then USERADDARGS="-M" ; fi } findPersistentHome() { for arg in \`cat /proc/cmdline\` ; do if [ "\${arg##persistenthome=}" != "\${arg}" ]; then homedev=\${arg##persistenthome=} fi done } if strstr "\`cat /proc/cmdline\`" persistenthome= ; then findPersistentHome elif [ -e /run/initramfs/live/\${livedir}/home.img ]; then homedev=/run/initramfs/live/\${livedir}/home.img fi # if we have a persistent /home, then we want to go ahead and mount it if ! strstr "\`cat /proc/cmdline\`" nopersistenthome && [ -n "\$homedev" ] ; then action "Mounting persistent /home" mountPersistentHome fi if [ -n "\$configdone" ]; then exit 0 fi # add liveuser user with no passwd action "Adding live user" useradd \$USERADDARGS -c "Live System User" liveuser passwd -d liveuser > /dev/null usermod -aG wheel liveuser > /dev/null # Remove root password lock passwd -d root > /dev/null # turn off firstboot for livecd boots systemctl --no-reload disable firstboot-text.service 2> /dev/null || : systemctl --no-reload disable firstboot-graphical.service 2> /dev/null || : systemctl stop firstboot-text.service 2> /dev/null || : systemctl stop firstboot-graphical.service 2> /dev/null || : # don't use prelink on a running live image sed -i 's/PRELINKING=yes/PRELINKING=no/' /etc/sysconfig/prelink &>/dev/null || : # turn off mdmonitor by default systemctl --no-reload disable mdmonitor.service 2> /dev/null || : systemctl --no-reload disable mdmonitor-takeover.service 2> /dev/null || : systemctl stop mdmonitor.service 2> /dev/null || : systemctl stop mdmonitor-takeover.service 2> /dev/null || : # don't start cron/at as they tend to spawn things which are # disk intensive that are painful on a live image systemctl --no-reload disable crond.service 2> /dev/null || : systemctl --no-reload disable atd.service 2> /dev/null || : systemctl stop crond.service 2> /dev/null || : systemctl stop atd.service 2> /dev/null || : # turn off abrtd on a live image systemctl --no-reload disable abrtd.service 2> /dev/null || : systemctl stop abrtd.service 2> /dev/null || : # Don't sync the system clock when running live (RHBZ #1018162) sed -i 's/rtcsync//' /etc/chrony.conf # Mark things as configured touch /.liveimg-configured # add static hostname to work around xauth bug # https://bugzilla.redhat.com/show_bug.cgi?id=679486 # the hostname must be something else than 'localhost' # https://bugzilla.redhat.com/show_bug.cgi?id=1370222 hostnamectl set-hostname "localhost-live" EOF # bah, hal starts way too late cat > /etc/rc.d/init.d/livesys-late << EOF #!/bin/bash # # live: Late init script for live image # # chkconfig: 345 99 01 # description: Late init script for live image. . /etc/init.d/functions if ! strstr "\`cat /proc/cmdline\`" rd.live.image || [ "\$1" != "start" ] || [ -e /.liveimg-late-configured ] ; then exit 0 fi exists() { which \$1 >/dev/null 2>&1 || return \$* } touch /.liveimg-late-configured # read some variables out of /proc/cmdline for o in \`cat /proc/cmdline\` ; do case \$o in ks=*) ks="--kickstart=\${o#ks=}" ;; xdriver=*) xdriver="\${o#xdriver=}" ;; esac done # if liveinst or textinst is given, start anaconda if strstr "\`cat /proc/cmdline\`" liveinst ; then plymouth --quit /usr/sbin/liveinst \$ks fi if strstr "\`cat /proc/cmdline\`" textinst ; then plymouth --quit /usr/sbin/liveinst --text \$ks fi # configure X, allowing user to override xdriver if [ -n "\$xdriver" ]; then cat > /etc/X11/xorg.conf.d/00-xdriver.conf <> /etc/fstab << EOF vartmp /var/tmp tmpfs defaults 0 0 EOF # work around for poor key import UI in PackageKit rm -f /var/lib/rpm/__db* echo "Packages within this LiveCD" rpm -qa --qf '%{size}\t%{name}-%{version}-%{release}.%{arch}\n' |sort -rn # Note that running rpm recreates the rpm db files which aren't needed or wanted rm -f /var/lib/rpm/__db* # go ahead and pre-make the man -k cache (#455968) /usr/bin/mandb # make sure there aren't core files lying around rm -f /core* # remove random seed, the newly installed instance should make it's own rm -f /var/lib/systemd/random-seed # convince readahead not to collect # FIXME: for systemd echo 'File created by kickstart. See systemd-update-done.service(8).' \ | tee /etc/.updated >/var/.updated # Drop the rescue kernel and initramfs, we don't need them on the live media itself. # See bug 1317709 rm -f /boot/*-rescue* # Disable network service here, as doing it in the services line # fails due to RHBZ #1369794 /sbin/chkconfig network off # Remove machine-id on pre generated images rm -f /etc/machine-id touch /etc/machine-id %end %post --nochroot # For livecd-creator builds only (lorax/livemedia-creator handles this directly) if [ -n "$LIVE_ROOT" ]; then cp "$INSTALL_ROOT"/usr/share/licenses/*-release-common/* "$LIVE_ROOT/" # only installed on x86, x86_64 if [ -f /usr/bin/livecd-iso-to-disk ]; then mkdir -p "$LIVE_ROOT/LiveOS" cp /usr/bin/livecd-iso-to-disk "$LIVE_ROOT/LiveOS" fi fi %end %post # cinnamon configuration # create /etc/sysconfig/desktop (needed for installation) cat > /etc/sysconfig/desktop <> /etc/rc.d/init.d/livesys << EOF # set up lightdm autologin sed -i 's/^#autologin-user=.*/autologin-user=liveuser/' /etc/lightdm/lightdm.conf sed -i 's/^#autologin-user-timeout=.*/autologin-user-timeout=0/' /etc/lightdm/lightdm.conf #sed -i 's/^#show-language-selector=.*/show-language-selector=true/' /etc/lightdm/lightdm-gtk-greeter.conf # set Cinnamon as default session, otherwise login will fail sed -i 's/^#user-session=.*/user-session=cinnamon/' /etc/lightdm/lightdm.conf # no updater applet in live environment rm -f /etc/xdg/autostart/org.mageia.dnfdragora-updater.desktop # this goes at the end after all other changes. chown -R liveuser:liveuser /home/liveuser restorecon -R /home/liveuser EOF %end %post echo "" echo "POST desktop-base ************************************" echo "" # Antialiasing by default. # Set Noto fonts as preferred family. cat > /etc/fonts/local.conf << EOF_FONTS <?xml version="1.0"?> <!DOCTYPE fontconfig SYSTEM "fonts.dtd"> <fontconfig> <!-- Settins for better font rendering --> <match target="font"> <edit mode="assign" name="rgba"><const>rgb</const></edit> <edit mode="assign" name="hinting"><bool>true</bool></edit> <edit mode="assign" name="hintstyle"><const>hintfull</const></edit> <edit mode="assign" name="antialias"><bool>true</bool></edit> <edit mode="assign" name="lcdfilter"><const>lcddefault</const></edit> </match> <!-- Local default fonts --> <!-- Serif faces --> <alias> <family>serif</family> <prefer> <family>Noto Serif</family> <family>DejaVu Serif</family> <family>Liberation Serif</family> <family>Times New Roman</family> <family>Nimbus Roman No9 L</family> <family>Times</family> </prefer> </alias> <!-- Sans-serif faces --> <alias> <family>sans-serif</family> <prefer> <family>Noto Sans</family> <family>DejaVu Sans</family> <family>Liberation Sans</family> <family>Arial</family> <family>Nimbus Sans L</family> <family>Helvetica</family> </prefer> </alias> <!-- Monospace faces --> <alias> <family>monospace</family> <prefer> <family>Noto Sans Mono Condensed</family> <family>DejaVu Sans Mono</family> <family>Liberation Mono</family> <family>Courier New</family> <family>Andale Mono</family> <family>Nimbus Mono L</family> </prefer> </alias> </fontconfig> EOF_FONTS # Set a colored prompt cat > /etc/profile.d/color-prompt.sh << EOF_PROMPT ## Colored prompt if [ -n "\$PS1" ]; then if [[ "\$TERM" == *256color ]]; then if [ \${UID} -eq 0 ]; then PS1='\[\e[91m\]\u@\h \[\e[93m\]\W\[\e[0m\]\\$ ' else PS1='\[\e[92m\]\u@\h \[\e[93m\]\W\[\e[0m\]\\$ ' fi else if [ \${UID} -eq 0 ]; then PS1='\[\e[31m\]\u@\h \[\e[33m\]\W\[\e[0m\]\\$ ' else PS1='\[\e[32m\]\u@\h \[\e[33m\]\W\[\e[0m\]\\$ ' fi fi fi EOF_PROMPT cat > /usr/sbin/backup_for_upgrade.sh << 'BACKUPSCRIPT_EOF' #!/bin/bash if [ "$(id -u)" != "0" ]; then echo "This script must be run as root" 1>&2 exit 1 fi USER="$(logname)" MOUNTPOINT_DEST="/home" DEST="/home/backup-$USER@$HOSTNAME-$(date '+%Y%m%d_%H%M%S')" PATHS_TO_BACKUP=( usr/local etc root ) mkdir -p "$DEST" cd $DEST umask 0066 echo "Saving lists of installed packages" id > id.txt dnf list installed > dnf_list_installed.txt rpm -qa > rpm-qa.txt flatpak list > flatpak_list.txt snap list > snap_list.txt # backup folders for path in "${PATHS_TO_BACKUP[@]}" do echo "Backing up $path" tar cjpf "backup-$(echo $path | tr / _).tar.bz2" -C / "$path" done echo "All done. Files are in $DEST" BACKUPSCRIPT_EOF chmod +x /usr/sbin/backup_for_upgrade.sh semanage fcontext -a -t unconfined_exec_t '/usr/local/sbin/firstboot' cat > /usr/local/sbin/firstboot << 'FIRSTBOOT_EOF' #!/bin/bash extcode=0 shopt -s nullglob for src in /usr/local/sbin/firstboot_*.sh; do echo "firstboot: running $src" $src if [ $? -ne 0 ]; then mv $src $src.failed echo "Script failed! Saved as: $src.failed" extcode=1 else echo "Script completed" rm $src fi done if [[ $exitcode == 0 ]]; then semanage fcontext -a -t unconfined_exec_t '/usr/local/sbin/firstboot' rm /usr/local/sbin/firstboot fi exit $extcode FIRSTBOOT_EOF chmod +x /usr/local/sbin/firstboot cat > /usr/local/sbin/firstboot_anaconda.sh << 'ANACONDA_EOF' #!/bin/bash dnf remove -y anaconda ANACONDA_EOF chmod +x /usr/local/sbin/firstboot_anaconda.sh cat > /usr/local/sbin/firstboot_noatime.sh << 'NOATIME_EOF' #!/bin/bash gawk -i inplace '/^[^#]/ {if (($3 == "ext4" || $3 == "btrfs") && !match($4, /noatime/)) { $4=$4",noatime" } } 1' /etc/fstab NOATIME_EOF chmod +x /usr/local/sbin/firstboot_noatime.sh %end %post echo "" echo "POST desktop-cinnamon ************************************" echo "" cat > /etc/mpv/mpv.conf << EOF hwdec=vaapi EOF %end %post echo "" echo "POST nonfree **************************************" echo "" # Enable Cisco Open H.264 repository dnf config-manager --set-enabled fedora-cisco-openh264 cat > /usr/local/sbin/firstboot_flathub.sh << 'FLATHUB_EOF' #!/bin/bash flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo FLATHUB_EOF chmod +x /usr/local/sbin/firstboot_flathub.sh %end %post echo "" echo "POST development-base ************************************" echo "" cat > /etc/sysctl.d/10-remix-inotify.conf << INOTIFY_EOF # remix - increase max inotify watches fs.inotify.max_user_watches=524288 INOTIFY_EOF mkdir /net mkdir -p /export/public chmod 1775 /export/public cat > /etc/exports << EOF /export/public *(ro,sync,root_squash) EOF cat >> /etc/vimrc << EOF set ai sw=4 :nnoremap :nohlsearch/ EOF cat >> /etc/inputrc << EOF set show-all-if-ambiguous on set editing-mode vi EOF cat >> /etc/profile.d/colorls.sh << EOF alias ls='ls -F --color=auto' 2>/dev/null EOF %end %packages @^cinnamon-desktop-environment @anaconda-tools @development-tools @networkmanager-submodules @x86-baremetal-tools aajohan-comfortaa-fonts aircrack-ng alsa-lib-devel anaconda anaconda-install-env-deps anaconda-live autoconf autofs automake avahi-devel bison chkconfig dracut-live exfat-utils fedora-release-cinnamon fedora-workstation-repositories ffmpeg-devel file-roller-nautilus flex fuse-exfat g++ gawk gcc gdb gettext-devel git glibc-all-langpacks google-noto-sans-fonts google-noto-sans-mono-fonts google-noto-serif-fonts gparted gperf gstreamer1-libav gstreamer1-plugins-bad-free gstreamer1-plugins-bad-freeworld gstreamer1-plugins-good gstreamer1-plugins-ugly gstreamer1-plugins-ugly-free gstreamer1-vaapi initscripts intel-media-driver inxi jq json-c-devel kernel kernel-modules kernel-modules-extra libconfuse-devel libcurl-devel liberation-s*-fonts libevent-devel libgcrypt-devel libplist-devel libreoffice-langpack-en libsodium-devel libtool libunistring-devel libva libva-utils libwebsockets-devel mpv mxml-devel nfs-utils nodejs npm ntpsec pkgconfig podman protobuf-c-devel rhythmbox rpmfusion-*-appstream-data rpmfusion-free-release rpmfusion-free-release-tainted rpmfusion-nonfree-release rpmfusion-nonfree-release-tainted seahorse seahorse-nautilus sqlite sqlite-devel strace tcpdump telnet unar unrar valgrind vim-default-editor vim-enhanced wireshark zlib-devel -abrt* -device-mapper-multipath -fcoe-utils -fedora-release-notes -hexchat -pidgin -rsyslog -sendmail -thunderbird -xreader %end

No comments:

Post a Comment