Created
June 7, 2020 10:39
-
-
Save j0ju/593a499aaae73c3ca112fa32fac389ed to your computer and use it in GitHub Desktop.
current root to nvme with efi and systemd
This file contains hidden or 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/sh | |
set -e | |
TGT=/dev/nvme0n1 | |
WAIT=5 | |
VG=nvme | |
LV_ROOT_SIZE=150G | |
#LV_ROOT_SIZE="$(df -h / | tail -n 1 | awk '{print $2}')" | |
KEY_FILE=/tmp/.nvme.key | |
warn() { echo "W: $*" >&2; } | |
info() { echo "I: $*"; } | |
msg() { echo "I: $*"; } | |
error() { echo "E: $*" >&2; } | |
die() { error "$@"; exit 1; } | |
if [ "$1" = --force ]; then | |
warn "will copy and move root to $TGT in $WAIT seconds" | |
for _ in $(seq 1 $WAIT); do | |
sleep 1 | |
echo -n . | |
done | |
echo | |
else | |
error "not copying root (/dev/mmcblk0) to $TGT" | |
info "use the --force, Luke" | |
echo | |
lsblk | |
echo | |
exit 1 | |
fi | |
if mountpoint /mnt > /dev/null 2>&1; then | |
die "filesystem is mounted at /mnt" | |
fi | |
if [ ! -r "$KEY_FILE" ]; then | |
die "KEY_FILE ($KEY_FILE) does not exist" | |
fi | |
if grep "$TGT" /proc/mounts >&2; then | |
die "$TGT is mounted" | |
fi | |
CLEANUP_TRAPS= | |
cleanup_trap() { | |
local rs=$? | |
local p | |
msg "TRAP: exitcode $rs" | |
for p in $CLEANUP_TRAPS; do | |
msg " TRAP: execute $p" | |
"$p" | |
done | |
exit $rs | |
} | |
trap cleanup_trap EXIT KILL TERM INT QUIT STOP USR1 HUP USR2 | |
msg "partition disk ROOTDEV=$TGT" | |
sgdisk $TGT -Z | |
PART_MD5="$(md5sum /proc/partitions | cut -f1 -d' ')" | |
sgdisk $TGT -Z \ | |
-n 15::+128M -t 15:ef00 \ | |
-n 14::+2G -t 14:8300 \ | |
-n 1:: -t 1:8e00 \ | |
# eo sgdisk | |
# check if the partition table has not been changed | |
if [ "$PART_MD5" = "$(md5sum /proc/partitions | cut -f1 -d' ')" ]; then | |
error "partition disk failed or reloading partition table failed" | |
exit 1 | |
fi | |
msg "evaluate settings" | |
ROOTDEV="$TGT" | |
case "$ROOTDEV" in | |
*[0-9] ) _PD_=p ;; | |
* ) _PD_= ;; | |
esac | |
EFIPART="${ROOTDEV}$_PD_"15 | |
BOOTPART="${ROOTDEV}$_PD_"14 | |
ROOTPART="${ROOTDEV}$_PD_"1 | |
wipefs -af $EFIPART $ROOTPART | |
msg "create crypt" | |
wipefs -af $ROOTPART | |
cryptsetup luksFormat $ROOTPART -d $KEY_FILE -q --type luks2 | |
CRYPT_UUID="$(blkid -o value -s UUID $ROOTPART)" | |
msg "open crypt crypt-$CRYPT_UUID" | |
cleanup_close_crypt() { | |
if [ -b /dev/mapper/crypt-$CRYPT_UUID ]; then | |
cryptsetup close /dev/mapper/crypt-$CRYPT_UUID | |
fi | |
} | |
CLEANUP_TRAPS="cleanup_close_crypt $CLEANUP_TRAPS" | |
cryptsetup luksOpen UUID=$CRYPT_UUID crypt-$CRYPT_UUID -d $KEY_FILE | |
ROOTPART=/dev/mapper/crypt-$CRYPT_UUID | |
msg "create system VG ($VG @ $ROOTPART)" | |
cleanup_deactivate_vg() { | |
vgchange -an $VG | |
} | |
CLEANUP_TRAPS="cleanup_deactivate_vg $CLEANUP_TRAPS" | |
wipefs -af $ROOTPART | |
pvcreate "$ROOTPART" | |
vgcreate $VG "$ROOTPART" | |
msg "create root LV ($VG/root $LV_ROOT_SIZE)" | |
case "$LV_ROOT_SIZE" in | |
*G | *M | *T ) lvcreate -n root -L $LV_ROOT_SIZE -W n $VG ;; | |
*%* ) lvcreate -n root -l $LV_ROOT_SIZE -W n $VG ;; | |
default ) die "unknown size specifier $LV_ROOT_SIZE, exit" ;; | |
esac | |
ROOTPART=/dev/$VG/root | |
# helper for /mnt | |
cleanup_umount_mnt() { | |
if mountpoint /mnt > /dev/null; then | |
mount | grep -Eo " /mnt[^ ]* " | sort -ur | while read mnt; do | |
umount "$mnt" || : | |
done | |
fi | |
} | |
CLEANUP_TRAPS="cleanup_umount_mnt $CLEANUP_TRAPS" | |
# helper for /.btrfs | |
cleanup_umount_dot_btrfs() { | |
if mountpoint /.btrfs > /dev/null; then | |
umount /.btrfs | |
fi | |
} | |
CLEANUP_TRAPS="cleanup_umount_dot_btrfs $CLEANUP_TRAPS" | |
msg "format EFI boot partition ($EFIPART - /boot/efi)" | |
wipefs -af $EFIPART | |
mkfs.vfat "$EFIPART" -F 32 -n EFI | |
msg "copy EFI partition" | |
mount $EFIPART /mnt | |
rsync /boot/efi/ /mnt -a -x | |
umount /mnt | |
msg "format boot partition ($BOOTPART - /boot)" | |
wipefs -af $BOOTPART | |
mkfs.ext4 $BOOTPART | |
msg "copy boot partition" | |
mount $BOOTPART /mnt | |
rsync /boot/ /mnt -a -x | |
umount /mnt | |
msg "format system volume" | |
wipefs -af $ROOTPART | |
mkfs.btrfs -d single -m single $ROOTPART | |
msg "mount system volume" | |
mount -o relatime,compress=zstd $ROOTPART /mnt | |
set -x | |
msg "copy btrfs subvolume structure and data" | |
mount -o relatime,compress=zstd /.btrfs | |
btrfs sub list /.btrfs | awk '{print $NF}' | sort | while read sub; do | |
# only copy data and rootfs/*-current* | |
case "$sub" in | |
rootfs | rootfs/*-current | rootfs/*-current/* ) : ;; # OK | |
rootfs/* ) continue ;; # do NOT copy this | |
# rest is okay | |
esac | |
subpath="/mnt/${sub}" | |
mkdir -p "${subpath%/*}" | |
btrfs sub create "/mnt/$sub" | |
done | |
ROOT_SUB_VOL="$( < /proc/mounts sed -nre '/ \/ / s@^.*subvol=([^, ]+).*$@\1@ p' )" | |
#ROOT_SUB_VOL="$( btrfs sub list /.btrfs | grep -o 'rootfs/.*-current$' | head -n 1 )" | |
echo $ROOT_SUB_VOL | while read sub; do | |
msg "copy current rootfs sub volume $sub" | |
sub="/$sub" | |
rsync -aH /.btrfs/$sub /mnt/${sub%/*} | |
rsync -aHx /dev /mnt/${sub} | |
done | |
btrfs sub list /.btrfs | grep -Eo '[^ ]+$' | grep -v ^rootfs | sort -r | while read sub; do | |
msg "copy sub volume $sub" | |
sub="/$sub" | |
rsync -aH /.btrfs/$sub /mnt/${sub%/*} | |
done | |
umount /mnt | |
msg "assemble / file system" | |
mount -o relatime,compress=zstd,subvol=$ROOT_SUB_VOL $ROOTPART /mnt | |
mount $BOOTPART /mnt/boot | |
mount $EFIPART /mnt/boot/efi | |
mount -o rbind /dev /mnt/dev | |
chroot /mnt mount -t proc proc /proc | |
chroot /mnt mount -t sysfs sysfs /sys | |
mount -o bind /tmp /mnt/tmp | |
mount -o bind /mnt/tmp /mnt/var/tmp | |
mount -o bind /run /mnt/run | |
msg "update crypttab to new UUID" | |
UUID_OLD="$(cat /etc/crypttab | grep -oE "UUID=[^ ]+" | cut -f2 -d=)" | |
sed -i -e "s/$UUID_OLD/$CRYPT_UUID/g" /mnt/etc/crypttab | |
msg "update fstab to new UUID for /" | |
UUID_OLD="$(grep " / " /etc/fstab | grep -oE "UUID=[^ ]+" | cut -f2 -d=)" | |
sed -i -e "s/$UUID_OLD/$(blkid -o value -s UUID $ROOTPART)/g" /mnt/etc/fstab | |
msg "update fstab to new UUID for /boot" | |
UUID_OLD="$(grep " /boot " /etc/fstab | grep -oE "UUID=[^ ]+" | cut -f2 -d=)" | |
sed -i -e "s/$UUID_OLD/$(blkid -o value -s UUID $BOOTPART)/g" /mnt/etc/fstab | |
msg "update fstab to new UUID for /boot/efi" | |
UUID_OLD="$(grep " /boot/efi " /etc/fstab | grep -oE "UUID=[^ ]+" | cut -f2 -d=)" | |
sed -i -e "s/$UUID_OLD/$(blkid -o value -s UUID $EFIPART)/g" /mnt/etc/fstab | |
msg "generate new SSH host keys" | |
for f in /mnt/etc/ssh/ssh_host_*_key; do | |
t="${f#*ssh_host_}" | |
t="${t%_key}" | |
if ssh-keygen -P "" -t "$t" -f "$f".new -C "$(hostname)" -m pem; then | |
mv -f "$f".new "$f" | |
mv -f "$f".new.pub "$f".pub | |
fi | |
done | |
for type in rsa dsa:dss ecdsa; do | |
openssh_type="${type%:*}" | |
dropbear_type="${type#*:}" | |
openssh_key="/mnt/etc/ssh/ssh_host_${openssh_type}_key" | |
dropbear_key="/mnt/etc/dropbear/dropbear_${dropbear_type}_host_key" | |
rm -f "$dropbear_key" | |
if [ -f "$openssh_key" ]; then | |
/usr/lib/dropbear/dropbearconvert openssh dropbear ${openssh_key} ${dropbear_key} 1> /dev/null 2>&1 || \ | |
warn "converting ssh host key for $openssh_type to ${dropbear_key##*/} FAILED" && \ | |
msg "converted ssh host key for $openssh_type to ${dropbear_key##*/}" | |
fi | |
done | |
chroot /mnt grub-install $ROOTDEV | |
chroot /mnt update-initramfs -kall -u | |
chroot /mnt update-grub | |
chroot /mnt etckeeper commit "new root device $ROOTDEV" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment