diff --git a/examples/green/Dockerfile b/examples/green/Dockerfile index 95e5424205a..c29141a67b7 100644 --- a/examples/green/Dockerfile +++ b/examples/green/Dockerfile @@ -42,6 +42,9 @@ RUN ARCH=$(uname -m); \ less \ sudo \ curl \ + btrfsprogs \ + snapper \ + tukit \ sed # Just add the elemental cli diff --git a/pkg/features/embedded/grub-config/etc/cos/grub.cfg b/pkg/features/embedded/grub-config/etc/cos/grub.cfg index fc9f96e13df..251b971948b 100644 --- a/pkg/features/embedded/grub-config/etc/cos/grub.cfg +++ b/pkg/features/embedded/grub-config/etc/cos/grub.cfg @@ -42,40 +42,30 @@ insmod all_video insmod gfxterm insmod loopback insmod squash4 +insmod btrfs set loopdev="loop0" +set btrfs_relative_path="y" menuentry "${display_name}" --id cos { - # label is kept around for backward compatibility - set label=${active_label} - set img=/cOS/active.img - loopback $loopdev /$img - source ($loopdev)/etc/cos/bootargs.cfg - linux ($loopdev)$kernel $kernelcmd ${extra_cmdline} ${extra_active_cmdline} - initrd ($loopdev)$initramfs - loopback -d $loopdev + btrfs-mount-subvol ($root) / ${active_snapshot} + set img=${active_snapshot} + source /etc/cos/bootargs.cfg + linux $kernel $kernelcmd ${extra_cmdline} ${extra_active_cmdline} + initrd $initramfs } menuentry "${display_name} (fallback)" --id fallback { - # label is kept around for backward compatibility - set label=${passive_label} - set img=/cOS/passive.img - loopback $loopdev /$img - source ($loopdev)/etc/cos/bootargs.cfg - linux ($loopdev)$kernel $kernelcmd ${extra_cmdline} ${extra_passive_cmdline} - initrd ($loopdev)$initramfs - loopback -d $loopdev + btrfs-mount-subvol ($root) / ${passive_snapshot} + set img=${passive_snapshot} + source /etc/cos/bootargs.cfg + linux $kernel $kernelcmd ${extra_cmdline} ${extra_passive_cmdline} + initrd $initramfs } menuentry "${display_name} recovery" --id recovery { - # label and recoverylabel are kept around for backward compatibility - if [ -n "${system_label}" ]; then - set label=${system_label} - else - set recoverylabel=${recovery_label} - fi - set img=/cOS/recovery.img search --no-floppy --label --set=root $recovery_label + set img=/cOS/recovery.img loopback $loopdev /$img source ($loopdev)/etc/cos/bootargs.cfg linux ($loopdev)$kernel $kernelcmd ${extra_cmdline} ${extra_recovery_cmdline} diff --git a/pkg/features/embedded/grub-default-bootargs/etc/cos/bootargs.cfg b/pkg/features/embedded/grub-default-bootargs/etc/cos/bootargs.cfg index 97ae35c06d2..816ac343c35 100644 --- a/pkg/features/embedded/grub-default-bootargs/etc/cos/bootargs.cfg +++ b/pkg/features/embedded/grub-default-bootargs/etc/cos/bootargs.cfg @@ -3,6 +3,6 @@ set kernel=/boot/vmlinuz if [ "${img}" == "/cOS/recovery.img" ]; then set kernelcmd="console=tty1 console=ttyS0 root=LABEL=$recovery_label cos-img/filename=$img security=selinux selinux=0 rd.neednet=1 rd.cos.oemlabel=$oem_label rd.cos.mount=LABEL=$oem_label:/oem" else - set kernelcmd="console=tty1 console=ttyS0 root=LABEL=$state_label cos-img/filename=$img panic=5 security=selinux selinux=1 rd.neednet=1 rd.cos.oemlabel=$oem_label rd.cos.mount=LABEL=$oem_label:/oem rd.cos.mount=LABEL=$persistent_label:/usr/local fsck.mode=force fsck.repair=yes" + set kernelcmd="console=tty1 console=ttyS0 root=LABEL=$state_label cos-img/filename=$img panic=5 security=selinux selinux=1 rd.neednet=1 rd.cos.oemlabel=$oem_label rd.cos.mount=LABEL=$oem_label:/oem rd.cos.mount=LABEL=$persistent_label:/usr/local" fi set initramfs=/boot/initrd diff --git a/pkg/features/embedded/immutable-rootfs/usr/lib/dracut/modules.d/30elemental-immutable-rootfs/elemental-generator.sh b/pkg/features/embedded/immutable-rootfs/usr/lib/dracut/modules.d/30elemental-immutable-rootfs/elemental-generator.sh index 89e02159241..f40c062adaa 100755 --- a/pkg/features/embedded/immutable-rootfs/usr/lib/dracut/modules.d/30elemental-immutable-rootfs/elemental-generator.sh +++ b/pkg/features/embedded/immutable-rootfs/usr/lib/dracut/modules.d/30elemental-immutable-rootfs/elemental-generator.sh @@ -148,8 +148,8 @@ mkdir -p "$GENERATOR_DIR/$dev.device.d" echo "RequiresMountsFor=${root_part_mnt}" echo "[Mount]" echo "Where=/sysroot" - echo "What=${root_part_mnt}/${cos_img#/}" - echo "Options=${cos_root_perm},suid,dev,exec,auto,nouser,async" + echo "What=${root}" + echo "Options=${cos_root_perm},subvol=${cos_img},suid,dev,exec,auto,nouser,async" } > "$GENERATOR_DIR"/sysroot.mount if [ ! -e "$GENERATOR_DIR/initrd-root-fs.target.requires/sysroot.mount" ]; then diff --git a/pkg/features/embedded/immutable-rootfs/usr/lib/dracut/modules.d/30elemental-immutable-rootfs/elemental-mount-layout.sh b/pkg/features/embedded/immutable-rootfs/usr/lib/dracut/modules.d/30elemental-immutable-rootfs/elemental-mount-layout.sh index e2109c801b7..a9828d839fc 100755 --- a/pkg/features/embedded/immutable-rootfs/usr/lib/dracut/modules.d/30elemental-immutable-rootfs/elemental-mount-layout.sh +++ b/pkg/features/embedded/immutable-rootfs/usr/lib/dracut/modules.d/30elemental-immutable-rootfs/elemental-mount-layout.sh @@ -260,12 +260,18 @@ readLayoutConfig [ -z "${cos_overlay}" ] && exit 0 +# Hack to get the root device and its mounted subvolume +snapshot=${root##*[} +snapshot=${snapshot%%]} +root=${root%%[*} + # If sysroot is already an overlay do not prepare the rw overlay if [ "${root_fstype}" != "overlay" ]; then if [ -f "${base_part}" ]; then fstab="${base_part} /run/initramfs/cos-state auto ${cos_root_perm} 0 0\n" fi - fstab+="${root} / auto ${cos_root_perm} 0 0\n" + + fstab+="${root} / auto ${cos_root_perm},subvol=${snapshot} 0 0\n" fstab+=$(mountOverlayBase) fi diff --git a/pkg/utils/grub.go b/pkg/utils/grub.go index 30d2808a7ad..b76e2ce2971 100644 --- a/pkg/utils/grub.go +++ b/pkg/utils/grub.go @@ -39,9 +39,13 @@ const ( grubCfgFile = "grub.cfg" grubEFICfgTmpl = ` +insmod btrfs + +set btrfs_relative_path="y" + search --no-floppy --label --set=root %s set prefix=($root)/` + grubConfDir + ` -configfile ($root)/` + grubConfDir + `/%s +configfile ${prefix}/` + grubCfgFile + ` ` ) @@ -254,7 +258,7 @@ func (g Grub) InstallEFI(rootDir, bootDir, efiDir, deviceLabel string) (string, // Add grub.cfg in EFI that chainloads the grub.cfg in recovery // Notice that we set the config to /grub2/grub.cfg which means the above we need to copy the file from // the installation source into that dir - grubCfgContent := []byte(fmt.Sprintf(grubEFICfgTmpl, deviceLabel, grubCfgFile)) + grubCfgContent := []byte(fmt.Sprintf(grubEFICfgTmpl, deviceLabel)) // Fallback err = g.config.Fs.WriteFile(filepath.Join(efiDir, fallbackEFIPath, grubCfgFile), grubCfgContent, cnst.FilePerm) if err != nil {