Created
August 31, 2023 13:19
-
-
Save rokiden/e3ba8c587a6475f959bd2ce09ff9dfd0 to your computer and use it in GitHub Desktop.
Script for converting Fedora LiveCD to LiveUSB with persistence
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Script for converting Fedora (and maybe other dracut-based) LiveCD to LiveUSB | |
# with persistence. Only UEFI boot supported. Tested with Fedora 37. | |
# | |
# Usage: | |
# ./fedora_to_usb.sh path/to/mounted/livecd /dev/sdX | |
# | |
# Result USB partitioning: | |
# GPT, 2 partitions: | |
# - "EFI" (vfat 256MB) for GRUB and kernel | |
# - "EXT" (ext4 rest of USB device) for SquashFS, OverlayFS and "updates" | |
# | |
# Expected LiveCD content: | |
# - boot -> for BIOS boot, ignored | |
# - EFI -> copy to EFI part | |
# - Fedora-Legal-README.txt -> ignored | |
# - images -> copy to EFI part | |
# - LICENSE -> ignored | |
# - LiveOS -> copy to EXT part | |
# | |
# Persistence: | |
# - EXT:/overlayfs contains files diff to SquashFS, saved automatically | |
# - EXT:/updates contains files to copy to root at every boot, filled manually | |
# | |
# Configuration: | |
# - EFI:/EFI/BOOT/grub.cfg patched, editable grub cfg. Original moved to .bak | |
# - rd.live.overlay.readonly=0 and rd.live.overlay.reset=0 can be changed | |
# before boot in grub menu with "e" key. | |
# - EXT:/updates can be used to provide pre-config for SquashFS. | |
# - etc/fstab, symlinks for systemd services(to /dev/null for disable), | |
# binaries, sshd_config, etc. | |
# | |
# Example: | |
# | |
# updates | |
# ├── etc | |
# │ ├── fstab | |
# │ ├── NetworkManager | |
# │ │ └── system-connections | |
# │ │ ├── wifi1.nmconnection | |
# │ │ └── wifi2.nmconnection | |
# │ ├── ssh | |
# │ │ ├── sshd_config.d | |
# │ │ │ └── 51-root.conf | |
# │ │ ├── ssh_host_ecdsa_key | |
# │ │ ├── ssh_host_ecdsa_key.pub | |
# │ │ ├── ssh_host_ed25519_key | |
# │ │ ├── ssh_host_ed25519_key.pub | |
# │ │ ├── ssh_host_rsa_key | |
# │ │ └── ssh_host_rsa_key.pub | |
# │ ├── systemd | |
# │ │ └── system | |
# │ │ ├── bluetooth.target.wants | |
# │ │ │ └── bluetooth.service -> /dev/null | |
# │ │ ├── dbus-org.bluez.service -> /dev/null | |
# │ │ ├── dbus-org.fedoraproject.FirewallD1.service -> /dev/null | |
# │ │ ├── graphical.target.wants | |
# │ │ │ └── upower.service -> /dev/null | |
# │ │ ├── multi-user.target.wants | |
# │ │ │ ├── abrtd.service -> /dev/null | |
# │ │ │ ├── atd.service -> /dev/null | |
# │ │ │ ├── auditd.service -> /dev/null | |
# │ │ │ ├── chronyd.service -> /dev/null | |
# │ │ │ ├── crond.service -> /dev/null | |
# │ │ │ ├── cups.path -> /dev/null | |
# │ │ │ ├── firewalld.service -> /dev/null | |
# │ │ │ ├── mdmonitor.service -> /dev/null | |
# │ │ │ ├── smartd.service -> /dev/null | |
# │ │ │ └── sshd.service -> /usr/lib/systemd/system/sshd.service | |
# │ │ ├── sockets.target.wants | |
# │ │ │ └── cups.socket -> /dev/null | |
# │ │ └── sysinit.target.wants | |
# │ │ └── dmraid-activation.service -> /dev/null | |
# │ └── xdg | |
# │ └── autostart | |
# │ ├── clipit-startup.desktop -> /dev/null | |
# │ ├── geoclue-demo-agent.desktop -> /dev/null | |
# │ ├── liveinst-setup.desktop -> /dev/null | |
# │ ├── org.mageia.dnfdragora-updater.desktop -> /dev/null | |
# │ └── xscreensaver-autostart.desktop -> /dev/null | |
# ├── mnt | |
# │ ├── efi | |
# │ └── ext -> /run/initramfs/live | |
# └── usr | |
# └── bin | |
# └── htop | |
# | |
# fstab: | |
# vartmp /var/tmp tmpfs defaults 0 0 | |
# tmpfs /var/log tmpfs defaults 0 0 | |
# tmpfs /var/cache tmpfs defaults 0 0 | |
# LABEL=EFI /mnt/efi vfat defaults 0 0 | |
# | |
# find_replace_null.sh: find "deleted" files in dir and replace with symlinks to | |
# /dev/null, usable after copy from overlayfs to updates | |
# find $1 -perm 0 -print -exec rm {} \; -exec ln -s /dev/null {} \; | |
if [ $# -ne 2 ] ; then | |
echo "ERROR : bad arguments, read script header for manual." | |
echo $0 SRCDIR USBDEV | |
exit 1 | |
fi | |
SRCDIR=$1 | |
USBDEV=$2 | |
LABEL_EFI="EFI" | |
LABEL_EXT="EXT" | |
cleanup() { | |
local RC=$? | |
[ $RC -ne 0 ] && echo "ERROR or ABORT detected ! Doing cleanup and exit (may take some time)." | |
umount $MNT 2>/dev/null | |
rmdir $MNT 2>/dev/null | |
return $RC | |
} | |
trap cleanup EXIT | |
USBDEVP1="${USBDEV}1" | |
USBDEVP2="${USBDEV}2" | |
MNT=$(mktemp -d) | |
echo Temp mount point $MNT | |
echo fdisk $USBDEV | |
echo ' | |
g | |
n | |
+256M | |
t | |
C12A7328-F81F-11D2-BA4B-00A0C93EC93B | |
n | |
t | |
0FC63DAF-8483-4772-8E79-3D69D8477DE4 | |
p | |
w | |
' | \ | |
fdisk $USBDEV | |
echo mkdosfs $USBDEVP1 | |
mkdosfs -v -F32 -n $LABEL_EFI $USBDEVP1 | |
echo Mount $USBDEVP1 to $MNT | |
mount $USBDEVP1 $MNT | |
echo Copy EFI and kernel | |
cp -ar $SRCDIR/EFI $MNT/ | |
cp -ar $SRCDIR/images $MNT/ | |
echo Patch GRUB config | |
mv $MNT/EFI/BOOT/grub.cfg $MNT/EFI/BOOT/grub.cfg.bak | |
echo "$( | |
cat <<EOF | |
set LABEL_EFI="$LABEL_EFI" | |
set LABEL_EXT="$LABEL_EXT" | |
set EXTRA_ARGS="plymouth.enable=0 disablehooks=plymouth audit=0 selinux=0" | |
set KERNEL_ARGS="root=live:LABEL=\$LABEL_EXT rw rd.live.image rd.live.overlay.overlayfs rd.live.overlay=LABEL=\$LABEL_EXT:/overlayfs \$EXTRA_ARGS" | |
EOF | |
) | |
$(cat $MNT/EFI/BOOT/grub.cfg.bak | \ | |
sed 's/set default=.*/set default=0/' | \ | |
sed 's/set timeout=.*/set timeout=1/' | \ | |
sed 's/quiet//' | \ | |
sed 's/rhgb//' | \ | |
sed 's/rd.live.image//'| \ | |
sed 's/search .*/search --no-floppy --set=root -l \$LABEL_EFI/' | \ | |
sed 's/root=live:CDLABEL=[^ ]*/$KERNEL_ARGS rd.live.overlay.readonly=0 rd.live.overlay.reset=0/')" > $MNT/EFI/BOOT/grub.cfg | |
diff $MNT/EFI/BOOT/grub.cfg.bak $MNT/EFI/BOOT/grub.cfg | |
echo Umount $MNT | |
umount $MNT | |
echo mkfs.ext4 $USBDEVP2 | |
mkfs.ext4 -F -L $LABEL_EXT -O ^64bit -j $USBDEVP2 | |
tune2fs -c0 -i0 -ouser_xattr,acl $USBDEVP2 | |
echo Mount $USBDEVP2 to $MNT | |
mount $USBDEVP2 $MNT | |
echo Copy LiveOS | |
cp -ar $SRCDIR/LiveOS $MNT/ | |
echo Make overlay and updates dirs | |
mkdir -m 0755 $MNT/updates $MNT/overlayfs $MNT/ovlwork | |
echo Umount $MNT | |
umount $MNT | |
awesome! saved my life 👍
@soplwang
Glad to hear! Please share your case. What iso did you use?
great! thank you very very much, my .iso was
Fedora-Python-Classroom-Live-x86_64-40-1.14.iso
and I worked on some bootable USB I established through Fedora Media Writer where I setup
Fedora-Workstation-Live-x86_64-39-1.5.iso
without your script I could not accomplish persistent storage.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
awesome! saved my life 👍