You are not logged in.
So i wrote my own pacman hook and script. The intention was for it to make bootable btrfs snapshots before any update. That also brings up the problem of systemd-boot but I got around that by making the boot partition slightly larger (5GB) then mounting the boot partition to /mnt/backup/boot and then bind mount the correct folders for the live system and snapshots to boot.
Anyway the problem is that sometimes when copying initramfs files, those don't get copied. Only the ucode file gets copied. But this issue isn't a consistent one. Sometimes it works perfectly and other times it dosen't. It's like the files aren't there.
Here is the hook file that is located in /etc/pacman.d/hooks/system-snapshot.hook
[Trigger]
Operation = Upgrade
Type = Package
Target = *
[Action]
Description = Pre-upgrade system snapshot
When = PreTransaction
Exec = /bin/sh -c "/etc/pacman.d/hooks.bin/system-snapshot.sh"And the script file wich is located in /etc/pacman.d/hooks.bin/system-snapshot.sh
#!/bin/sh
TIME=$(date +"%Y-%m-%d_%H-%M")
TIME_SEC=$(date +"%s")
TIME_MIN="3600"
MAX_SNAP="3"
ENCRYPTED="0"
CRYPTROOTUUID=""
UNCRYPTROOTUUID="8a7cb6cd-fe5f-479f-a76f-d1d92babb9e6"
CRYPTSWAPUUID=""
UNCRYPTSWAPUUID="89e057bd-bdf6-4899-9d92-d385eadd14d8"
#Create a new btrfs snapshot
create_btrfs_snapshot() {
VOLUME="$1"
echo ":: System snapshot: Creating new btrfs "$VOLUME" snapshot..."
btrfs subvolume snapshot /mnt/backup-mnt/_active/"$VOLUME" /mnt/backup-mnt/_snapshots/"$VOLUME"_"$TIME"_"$TIME_SEC"
sleep 1
echo ":: System snapshot: Btrfs "$VOLUME" snapshot creation complete."
}
#Delete old btrfs snapshots
delete_old_btrfs_snapshots() {
VOLUME="$1"
echo ":: System snapshot: Deleting old btrfs "$VOLUME" snapshots..."
#Get all snapshot timestamps and add them to an array.
for i in /mnt/backup-mnt/_snapshots/"$VOLUME"_*; do
TIME_SNAPSHOT_DELETE=$(echo "$i" | awk -F '_' '{print $NF}')
DEL_VOL_ARRAY+=($TIME_SNAPSHOT_DELETE)
done
#Check array and delete old snapshots except the newest three.
while [ "${#DEL_VOL_ARRAY[@]}" -gt "$MAX_SNAP" ]; do
TIME_OLDEST_SNAPSHOT_DELETE=$(printf '%s\n' "${DEL_VOL_ARRAY[@]}" | awk '$1 < m || NR == 1 { m = $1 } END { print m }')
btrfs subvolume delete /mnt/backup-mnt/_snapshots/"$VOLUME"_*"$TIME_OLDEST_SNAPSHOT_DELETE"
sleep 1
for i in "${!DEL_VOL_ARRAY[@]}"; do
if [[ "${DEL_VOL_ARRAY[$i]}" = "$TIME_OLDEST_SNAPSHOT_DELETE" ]]; then
unset DEL_VOL_ARRAY[$i]
fi
done
done
unset DEL_VOL_ARRAY
echo ":: System snapshot: Old btrfs "$VOLUME" snapshot deletion complete."
}
#Create a new boot snapshot
create_boot_snapshot() {
echo ":: System snapshot: Creating new boot snapshot..."
#Create a new boot snapshot folder and copy the pre-upgraded boot files to it.
mkdir /mnt/backup-boot/installs/snapshots/arch_${TIME}_${TIME_SEC}
for boot_file in /mnt/backup-boot/installs/active/arch/*; do
echo ":: System snapshot: Copying ${boot_file} to boot snapshot arch_${TIME}_${TIME_SEC}"
cp $boot_file /mnt/backup-boot/installs/snapshots/arch_${TIME}_${TIME_SEC}/
done
#Create a systemd-boot loader entry for the snapshot.
if [[ "$ENCRYPTED" = "0" ]]; then
cat > /mnt/backup-boot/loader/entries/arch-snapshot_"$TIME"_"$TIME_SEC".conf <<- EOC
title Arch Linux (Snapshot ${TIME})
linux /installs/snapshots/arch_${TIME}_${TIME_SEC}/vmlinuz-linux
initrd /installs/snapshots/arch_${TIME}_${TIME_SEC}/intel-ucode.img
initrd /installs/snapshots/arch_${TIME}_${TIME_SEC}/initramfs-linux.img
options root=UUID=${UNCRYPTROOTUUID} rootflags=subvol=_snapshots/root-arch_${TIME}_${TIME_SEC} resume=UUID=${UNCRYPTSWAPUUID} rw
EOC
else
cat > /mnt/backup-boot/loader/entries/arch-snapshot_"$TIME"_"$TIME_SEC".conf <<- EOC
title Arch Linux (Snapshot ${TIME})
linux /installs/snapshots/arch_${TIME}_${TIME_SEC}/vmlinuz-linux
initrd /installs/snapshots/arch_${TIME}_${TIME_SEC}/intel-ucode.img
initrd /installs/snapshots/arch_${TIME}_${TIME_SEC}/initramfs-linux.img
options luks.name=${CRYPTROOTUUID}=crypt_luks0 luks.name=${CRYPTSWAPUUID}=crypt_luks1 root=UUID=${UNCRYPTROOTUUID} rootflags=subvol=_snapshots/root-arch_${TIME}_${TIME_SEC} resume=UUID=$UNCRYPTSWAPUUID rw
EOC
fi
echo ":: System snapshot: Created boot snapshot /mnt/backup-boot/installs/snapshots/arch_${TIME}_${TIME_SEC}"
echo ":: System snapshot: Created systemd-boot entry /mnt/backup-boot/loader/entries/arch-snapshot_${TIME}_${TIME_SEC}.conf"
echo ":: System snapshot: Boot snapshot creation complete."
}
#Delete old boot snapshots
delete_old_boot_snapshots() {
echo ":: System snapshot: Deleting old boot snapshots..."
#Get all boot snapshot timestamps and add them to an array.
for i in /mnt/backup-boot/installs/snapshots/arch_*; do
TIME_BOOT_SNAPSHOT_DELETE=$(echo "$i" | awk -F '_' '{print $NF}')
DEL_BOOT_ARRAY+=($TIME_BOOT_SNAPSHOT_DELETE)
done
#Check array and delete old boot snapshots except the newest three.
while [ "${#DEL_BOOT_ARRAY[@]}" -gt "$MAX_SNAP" ]; do
TIME_OLDEST_BOOT_DELETE=$(printf '%s\n' "${DEL_BOOT_ARRAY[@]}" | awk '$1 < m || NR == 1 { m = $1 } END { print m }')
DELETE_SNAP=$(find /mnt/backup-boot/installs/snapshots/ -maxdepth 1 -name "arch_*${TIME_OLDEST_BOOT_DELETE}")
DELETE_SNAP_ENTRY=$(find /mnt/backup-boot/loader/entries/ -maxdepth 1 -name "arch-snapshot*${TIME_OLDEST_BOOT_DELETE}.conf")
#rm -rf /mnt/backup-boot/installs/snapshots/arch_*"$TIME_OLDEST_BOOT_DELETE"
#rm /mnt/backup-boot/loader/entries/arch-zen*"$TIME_OLDEST_BOOT_DELETE".conf
rm -rf "$DELETE_SNAP"
rm "$DELETE_SNAP_ENTRY"
sleep 1
for i in "${!DEL_BOOT_ARRAY[@]}"; do
if [[ "${DEL_BOOT_ARRAY[$i]}" = "$TIME_OLDEST_BOOT_DELETE" ]]; then
unset DEL_BOOT_ARRAY[$i]
fi
done
if [ ! -z "$DELETE_SNAP" ]; then
echo ":: System snapshot: Deleted boot snapshot ${DELETE_SNAP}"
fi
if [ ! -z "$DELETE_SNAP_ENTRY" ]; then
echo ":: System snapshot: Deleted systemd-boot entry ${DELETE_SNAP_ENTRY}"
fi
done
echo ":: System snapshot: Old boot snapshot deletion complete."
}
#Replace fstab entries for volumes
replace_fstab_entries() {
VOLUME="$1"
#Replace the btrfs subvolume names in the snapshot's /etc/fstab.
echo ":: System snapshot: Changing snapshot fstab for volume ${VOLUME}"
sed -i "s*subvol=_active/${VOLUME}*subvol=_snapshots/${VOLUME}_${TIME}_${TIME_SEC}*g" /mnt/backup-mnt/_snapshots/root-arch_"$TIME"_"$TIME_SEC"/etc/fstab
echo ":: System snapshot: Changing of fstab for volume ${VOLUME} complete"
}
#Replace fstab entries for boot
replace_fstab_boot() {
#Replace the boot and boot bind mount names in /etc/fstab.
echo ":: System snapshot: Changing snapshot fstab for boot."
sed -i "s*mnt/backup-boot/installs/active/arch*mnt/backup-boot/installs/snapshots/arch_${TIME}_${TIME_SEC}*g" /mnt/backup-mnt/_snapshots/root-arch_"$TIME"_"$TIME_SEC"/etc/fstab
echo ":: System snapshot: Changing of fstab for boot complete."
}
echo ":: System snapshot: Beginning system snapshot generation."
if [[ ! -d /mnt/backup-mnt ]]; then
mkdir -p /mnt/backup-mnt
fi
mount --uuid ${UNCRYPTROOTUUID} /mnt/backup-mnt
for ACTIVE_VOLUME in root-arch home-arch; do
#Check the timestamp of the last snapshot generated. If it's withing the threshold, no new snapshots will be generated and the script will exit.
echo ":: System snapshot: Checking time of last btrfs "$ACTIVE_VOLUME" snapshot generated..."
if ls /mnt/backup-mnt/_snapshots/"$ACTIVE_VOLUME"_* &> /dev/null; then
for i in /mnt/backup-mnt/_snapshots/"$ACTIVE_VOLUME"_*; do
TIME_SNAPSHOT_CHECK=$(echo "$i" | awk -F '_' '{print $NF}')
TIME_DIFFRENCE=$(($(date +"%s")-$TIME_SNAPSHOT_CHECK))
TIME_VOL_ARRAY+=($TIME_DIFFRENCE)
done
TIME_OLDEST_SNAPSHOT=$(printf '%s\n' "${TIME_VOL_ARRAY[@]}" | awk '$1 < m || NR == 1 { m = $1 } END { print m }')
if [ "$TIME_OLDEST_SNAPSHOT" -le "$TIME_MIN" ]; then
echo ":: System snapshot: Pre-upgrade btrfs "$ACTIVE_VOLUME" snapshot canceled. Time threshold not met."
else
create_btrfs_snapshot $ACTIVE_VOLUME
delete_old_btrfs_snapshots $ACTIVE_VOLUME
replace_fstab_entries $ACTIVE_VOLUME
if [[ "$ACTIVE_VOLUME" = "root-arch" ]]; then
create_boot_snapshot
delete_old_boot_snapshots
replace_fstab_boot
fi
fi
unset TIME_VOL_ARRAY
else
create_btrfs_snapshot $ACTIVE_VOLUME
replace_fstab_entries $ACTIVE_VOLUME
if [[ "$ACTIVE_VOLUME" = "root-arch" ]]; then
create_boot_snapshot
replace_fstab_boot
fi
fi
done
umount -R /mnt/backup-mnt
echo ":: System snapshot: Complete."Snapshots, boot entries generation and old snapshot deletion works fine. Just the copying of boot files is giving me trouble.
Any help is appreciated.
The Linux philosophy is 'Laugh in the face of danger'. Oops. Wrong One. 'Do it yourself'. Yes, that's it.
Offline
Hi
snap-pac does the same job !
https://github.com/wesbarnett/snap-pac
and for reading only :
btrfs property set /mnt/@snapshots/#/snapshot ro false
I don't love rosbeef
Offline
Yeah well I'm more of a DIY type of guy. I love to mess around and experiment with my system. Thanks for letting me know tho.
Last edited by 7thCore (2021-06-03 18:57:32)
The Linux philosophy is 'Laugh in the face of danger'. Oops. Wrong One. 'Do it yourself'. Yes, that's it.
Offline
Yeah well I'm more of a DIY type of guy. I love to mess around and experiment with my system. Thanks for letting me know tho.
no worries man!
in this case I leave the hand to another, too complex for me ![]()
good luck!
I don't love rosbeef
Offline