Venom1991 / refind-btrfs

Generate rEFInd manual boot stanzas from Btrfs snapshots
GNU General Public License v3.0
144 stars 8 forks source link

Allow for subentry to existing Menuentry #22

Open jocelynthode opened 2 years ago

jocelynthode commented 2 years ago

Hi,

First I'd like to thank you for your tool, it's really useful and saved me from rolling out my own scripts.

At the moment I have my main entry in refind as well as the one generated from the snapshots and their submenuentry.

Ideally I'd like to only have one menuentry and have the snapshots only as submenuentry of this original entry.

I'd be open to create a PR to add this. Could you help me get started with this idea and where to start in the code please?

Venom1991 commented 2 years ago

Hi,

the implementation of this feature is non-trivial and would require quite a bit of work, unfortunately.

The generated boot stanza would have to be merged into the source boot stanza by converting it to a collection of sub-menus (flattening it, in other words) - that's the easy part. The hard part is replacing the source boot stanza at just the right position in the rEFInd configuration file with the resultant boot stanza. I suppose ANTLR does return the positions of tokens as it performs the lexical analysis of the source file expressed as a kind of offset (line and character, for example). Maybe something could be done with that.
Either way, that's a bit tricky because a simple overwrite would not behave correctly in case there is possibly important text located after the source boot stanza's location. Perhaps it'd be easier to disable (by adding a "disabled" option to its definition) the source boot stanza and then simply append the generated boot stanza at the end of the file.

Also, this behavior would have to be configurable - that is, the user should be able to choose whether the generated boot stanzas are to be separated or merged.

If you have the time and will, you could start in this source directory. It contains all the source boot stanza parsing, boot stanza generation and persistence code.

When developing locally, make sure to create a virtual environment, install the dependencies and enable system site packages in your pyvenv.cfg:

include-system-site-packages = true

because libbtrfsutil is not available on PyPI.

jocelynthode commented 2 years ago

Thanks for the extensive response. This indeed looks like more work than I had planned. I'll have to take a bit of time to see if it's feasible and then see if I have the time for this.

Another option could be to force the user to separate the source boot stanza in a specific file so that refind-btrfs could work on this file without fearing breaking anything else. This would of course only be required when the user activates this specific option.

Venom1991 commented 2 years ago

How would you force the user to do so, that is perform the config file separation which you've mentioned? I don't see how that scenario can even be validated because I cannot discern whether the configured rEFInd config file is the one actually used by rEFInd itself or simply a utility config file to be used solely by refind-btrfs.

UltraBlackLinux commented 1 year ago

just did some experimenting and came up with this:

menuentry "Arch" {
    icon     /EFI/refind/themes/refind-theme-regular/icons/512-192/os_arch.png
    volume   "4f58220f-2b24-374a-96c3-7d9c60290781"
    options  "root=PARTUUID=4f58220f-2b24-374a-96c3-7d9c60290781 rw add_efi_memmap rootflags=subvol=@ initrd=@\boot\amd-ucode.img rd.udev.log_priority=3 vt.global_cursor_default=0 systemd.unified_cgroup_hierarchy=1 loglevel=3 sysrq_always_enabled=1 iommu=soft"

    submenuentry "Zen" {
        loader   /@/boot/vmlinuz-linux-zen
        initrd   /@/boot/initramfs-linux-zen.img    
    }
    submenuentry "Zen - Fallback Initramfs" {
        loader   /@/boot/vmlinuz-linux-zen
        initrd   /@/boot/initramfs-linux-fallback.img
    }
    submenuentry "Zen - Boot to terminal" {
        loader   /@/boot/vmlinuz-linux-zen
        initrd   /@/boot/initramfs-linux-zen.img    
        add_options "systemd.unit=multi-user.target"
    }

    submenuentry "LTS" {
        loader   /@/boot/vmlinuz-linux-lts
        initrd   /@/boot/initramfs-linux-lts.img    
    }
    submenuentry "LTS - Fallback Initramfs" {
        loader   /@/boot/vmlinuz-linux-lts
        initrd   /@/boot/initramfs-linux-lts-fallback.img
    }
    submenuentry "LTS - Boot to terminal" {
        loader   /@/boot/vmlinuz-linux-lts
        initrd   /@/boot/initramfs-linux-lts.img    
        add_options "systemd.unit=multi-user.target"
    }

    submenuentry "Linux" {
        loader   /@/boot/vmlinuz-linux
        initrd   /@/boot/initramfs-linux.img    
    }
    submenuentry "Linux - Fallback Initramfs" {
        loader   /@/boot/vmlinuz-linux
        initrd  /@/boot/initramfs-linux-fallback.img
    }
    submenuentry "Linux - Boot to terminal" {
        loader   /@/boot/vmlinuz-linux
        initrd   /@/boot/initramfs-linux.img    
        add_options "systemd.unit=multi-user.target"
    }
}

Works like a charm, but is a lot of boilerplate. I would really prefer one of these per snapshot over having one entry per kernel per snapshot. Sadly I can't use this myself as it will result in refind-btrfs not creating bootable snapshots for this at all

Venom1991 commented 1 year ago

@UltraBlackLinux It might work if you set this option to "true".

UltraBlackLinux commented 1 year ago

@UltraBlackLinux It might work if you set this option to "true".

sadly already enabled for me. I think this is due to the weird configuration; I assume it wants options in the same context

Venom1991 commented 1 year ago

sadly already enabled for me. I think this is due to the weird configuration; I assume it wants options in the same context

Quote from that option's explanation: "If set to "true", only those sub-menus which do not override the main stanza's "loader" and "options" fields and which do not delete (i.e., set it to nothing) its "initrd" field are taken into consideration."

I can't really remember why I've added those constraints in the first place. It's been some time since I've implemented them but there has to be a reason.

UltraBlackLinux commented 1 year ago

sadly, it still does not work. It does not get submenus just because I created a menu with kernel selection submenus