diff --git a/41_snapshots-btrfs b/41_snapshots-btrfs index 123f095..52ae310 100644 --- a/41_snapshots-btrfs +++ b/41_snapshots-btrfs @@ -42,13 +42,6 @@ grub_btrfs_config="${sysconfdir}/default/grub-btrfs/config" [[ -f "$grub_btrfs_config" ]] && . "$grub_btrfs_config" [[ -f "${sysconfdir}/default/grub" ]] && . "${sysconfdir}/default/grub" -## Exit the script, if: -[[ "${GRUB_BTRFS_DISABLE,,}" == "true" ]] && exit 0 # Disable Grub-btrfs is set to true (default=false) -if ! type btrfs >/dev/null 2>&1; then exit 0; fi # btrfs-progs isn't installed -[[ -f "${GRUB_BTRFS_MKCONFIG_LIB:-/usr/share/grub/grub-mkconfig_lib}" ]] && . "${GRUB_BTRFS_MKCONFIG_LIB:-/usr/share/grub/grub-mkconfig_lib}" || exit 0 # grub-mkconfig_lib couldn't be found -# Root filesystem isn't btrfs -[[ "$(${grub_probe} --target="fs" / 2>/dev/null)" != "btrfs" ]] && exit 0 - ## Error Handling print_error() { @@ -58,6 +51,12 @@ print_error() exit 0 } +## Exit the script, if: +[[ "${GRUB_BTRFS_DISABLE,,}" == "true" ]] && print_error "GRUB_BTRFS_DISABLE is set to true (default=false)" +if ! type btrfs >/dev/null 2>&1; then print_error "btrfs-progs isn't installed"; fi +[[ -f "${GRUB_BTRFS_MKCONFIG_LIB:-/usr/share/grub/grub-mkconfig_lib}" ]] && . "${GRUB_BTRFS_MKCONFIG_LIB:-/usr/share/grub/grub-mkconfig_lib}" || print_error "grub-mkconfig_lib couldn't be found" +[[ "$(${grub_probe} --target="fs" / 2>/dev/null)" != "btrfs" ]] && print_error "Root filesystem isn't btrfs" + printf "Detecting snapshots ...\n" >&2 ; ## Submenu name diff --git a/Makefile b/Makefile index 04b1575..93be560 100644 --- a/Makefile +++ b/Makefile @@ -8,37 +8,64 @@ OPENRC ?= false SHARE_DIR = $(DESTDIR)$(PREFIX)/share LIB_DIR = $(DESTDIR)$(PREFIX)/lib BIN_DIR = $(DESTDIR)$(PREFIX)/bin +MAN_DIR = $(SHARE_DIR)/man -.PHONY: install uninstall help +TEMP_DIR = ./temp + +.PHONY: install uninstall clean help install: @if test "$(shell id -u)" != 0; then \ echo "You are not root, run this target as root please."; \ exit 1; \ fi + @echo " Installing " + @echo + @echo " :::::::: ::::::::: ::: ::: ::::::::: ::::::::: ::::::::::: ::::::::: :::::::::: :::::::: " + @echo " :+: :+: :+: :+: :+: :+: :+: :+: :+: :+: :+: :+: :+: :+: :+: :+: " + @echo " +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ " + @echo " :#: +#++:++#: +#+ +:+ +#++:++#+ +#++:++#++:++ +#++:++#+ +#+ +#++:++#: :#::+::# +#++:++#++ " + @echo " +#+ +#+# +#+ +#+ +#+ +#+ +#+ +#+ +#+ +#+ +#+ +#+ +#+ +#+ +#+ " + @echo " #+# #+# #+# #+# #+# #+# #+# #+# #+# #+# #+# #+# #+# #+# #+# #+# " + @echo " ######## ### ### ######## ######### ######### ### ### ### ### ######## " + @echo + @echo " For further information visit https://github.com/Antynea/grub-btrfs or read the man page: 'man grub-btrfs'" + @echo + @mkdir "${TEMP_DIR}" + @chmod 777 ${TEMP_DIR} + @cp manpages/grub-btrfs.8.man ${TEMP_DIR}/grub-btrfs.8 + @bzip2 ${TEMP_DIR}/grub-btrfs.8 + @install -Dm644 -t "${MAN_DIR}/man8" "${TEMP_DIR}/grub-btrfs.8.bz2" + @cp manpages/grub-btrfsd.8.man ${TEMP_DIR}/grub-btrfsd.8 + @bzip2 ${TEMP_DIR}/grub-btrfsd.8 + @install -Dm644 -t "${MAN_DIR}/man8" "${TEMP_DIR}/grub-btrfsd.8.bz2"; @install -Dm755 -t "$(DESTDIR)/etc/grub.d/" 41_snapshots-btrfs @install -Dm644 -t "$(DESTDIR)/etc/default/grub-btrfs/" config + @install -Dm744 -t "$(BIN_DIR)/" grub-btrfsd; @# Systemd init system @if test "$(SYSTEMD)" = true; then \ - install -Dm644 -t "$(LIB_DIR)/systemd/system/" grub-btrfs.path; \ - install -Dm644 -t "$(LIB_DIR)/systemd/system/" grub-btrfs.service; \ + echo "Installing systemd .service file"; \ + install -Dm644 -t "$(LIB_DIR)/systemd/system/" grub-btrfsd.service; \ fi @# OpenRC init system @if test "$(OPENRC)" = true; then \ - install -Dm744 -t "$(BIN_DIR)/" grub-btrfs-openrc; \ + echo "Installing openRC init.d & conf.d file"; \ install -Dm744 grub-btrfsd.initd "$(DESTDIR)/etc/init.d/grub-btrfsd"; \ install -Dm644 grub-btrfsd.confd "$(DESTDIR)/etc/conf.d/grub-btrfsd"; \ fi @# Arch Linux like distros only : @if test "$(INITCPIO)" = true; then \ + echo "Installing initcpio hook"; \ install -Dm644 "initramfs/Arch Linux/overlay_snap_ro-install" "$(LIB_DIR)/initcpio/install/grub-btrfs-overlayfs"; \ install -Dm644 "initramfs/Arch Linux/overlay_snap_ro-hook" "$(LIB_DIR)/initcpio/hooks/grub-btrfs-overlayfs"; \ fi @install -Dm644 -t "$(SHARE_DIR)/licenses/$(PKGNAME)/" LICENSE @install -Dm644 -t "$(SHARE_DIR)/doc/$(PKGNAME)/" README.md @install -Dm644 "initramfs/readme.md" "$(SHARE_DIR)/doc/$(PKGNAME)/initramfs-overlayfs.md" + @rm -rf "${TEMP_DIR}" uninstall: + @echo "Uninstalling grub-btrfs" @if test "$(shell id -u)" != 0; then \ echo "You are not root, run this target as root please."; \ exit 1; \ @@ -47,12 +74,14 @@ uninstall: rm -f "$${grub_dirname:-/boot/grub}/grub-btrfs.cfg" @rm -f "$(DESTDIR)/etc/default/grub-btrfs/config" @rm -f "$(DESTDIR)/etc/grub.d/41_snapshots-btrfs" - @rm -f "$(LIB_DIR)/systemd/system/grub-btrfs.path" - @rm -f "$(LIB_DIR)/systemd/system/grub-btrfs.service" - @rm -f "$(BIN_DIR)/grub-btrfs-openrc;" + @rm -f "$(LIB_DIR)/systemd/system/grub-btrfsd.service" + @rm -f "$(BIN_DIR)/grub-btrfsd;" @rm -f "$(DESTDIR)/etc/init.d/grub-btrfsd;" + @rm -f "$(DESTDIR)/etc/conf.d/grub-btrfsd;" @rm -f "$(LIB_DIR)/initcpio/install/grub-btrfs-overlayfs" @rm -f "$(LIB_DIR)/initcpio/hooks/grub-btrfs-overlayfs" + @rm -f "$(MAN_DIR)/man8/grub-btrfs.8.bz2" + @rm -f "$(MAN_DIR)/man8/grub-btrfsd.8.bz2" @# Arch Linux UNlike distros only : @if test "$(INITCPIO)" != true && test -d "$(LIB_DIR)/initcpio"; then \ rmdir --ignore-fail-on-non-empty "$(LIB_DIR)/initcpio/install" || :; \ @@ -66,9 +95,14 @@ uninstall: @rmdir --ignore-fail-on-non-empty "$(SHARE_DIR)/licenses/$(PKGNAME)/" || : @rmdir --ignore-fail-on-non-empty "$(DESTDIR)/etc/default/grub-btrfs" || : +clean: + @echo "Deleting ./temp" + @rm -rf "${TEMP_DIR}" + help: @echo @echo "Usage: $(MAKE) [ = ... ] [ ]" + @echo "Example: $(MAKE) OPENRC=true SYSTEMD=false install" @echo @echo " actions: install" @echo " uninstall" diff --git a/README.md b/README.md index 9550a5d..bb9db1a 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,11 @@ [![GitHub release](https://img.shields.io/github/release/Antynea/grub-btrfs.svg)](https://github.com/Antynea/grub-btrfs/releases) ![](https://img.shields.io/github/license/Antynea/grub-btrfs.svg) -## grub-btrfs +## 💻 grub-btrfs -This is a version 4.xx of grub-btrfs ##### BTC donation address: `1Lbvz244WA8xbpHek9W2Y12cakM6rDe5Rt` - - - -### Description: +### 🔎 Description: Improves grub by adding "btrfs snapshots" to the grub menu. You can boot your system on a "snapshot" from the grub menu. @@ -22,16 +21,16 @@ This project includes its own solution. Refer to the [documentation](https://github.com/Antynea/grub-btrfs/blob/master/initramfs/readme.md). - - - -### What features does grub-btrfs v4.xx have? +### ✨ What features does grub-btrfs have? * Automatically list snapshots existing on root partition (btrfs). * Automatically detect if `/boot` is in separate partition. * Automatically detect kernel, initramfs and intel/amd microcode in `/boot` directory on snapshots. * Automatically create corresponding "menuentry" in `grub.cfg` * Automatically detect the type/tags and descriptions/comments of snapper/timeshift snapshots. -* Automatically generate `grub.cfg` if you use the provided systemd service. +* Automatically generate `grub.cfg` if you use the provided systemd/ openRC service. - - - -### Installation: +### 🛠️ Installation: #### Arch Linux The package is available in the community repository [grub-btrfs](https://archlinux.org/packages/community/any/grub-btrfs/) ``` @@ -44,10 +43,12 @@ If you have not activated the GURU yet, do so by running: ``` emerge -av app-eselect/eselect-repository eselect repository enable guru -emerge --sync +emaint sync -r guru ``` +If you are using Systemd on Gentoo, make sure the USE-Flag `systemd` is set. (Either globally in make.conf or in package.use for the package app-backup/grub-btrfs) +Without systemd USE-Flag the OpenRC-daemon of grub-btrfs will be installed. -Now merge grub-btrfs via +Emerge grub-btrfs via `emerge app-backup/grub-btrfs` #### Kali Linux @@ -64,7 +65,8 @@ Booting into read-only snapshots is fully supported when choosing "btrfs" as fil * [btrfs-progs](https://archlinux.org/packages/core/x86_64/btrfs-progs/) * [grub](https://archlinux.org/packages/core/x86_64/grub/) * [bash >4](https://archlinux.org/packages/core/x86_64/bash/) - * [gawk ](https://archlinux.org/packages/core/x86_64/gawk/) + * [gawk](https://archlinux.org/packages/core/x86_64/gawk/) + * (optional for the daemon)[inotify-tools](https://archlinux.org/packages/community/x86_64/inotify-tools/) #### NOTE: All distros Generate your grub menu after installation for the changes to take effect. @@ -73,93 +75,258 @@ On **Arch Linux** or **Gentoo** use `grub-mkconfig -o /boot/grub/grub.cfg`. On **Fedora** use `grub2-mkconfig -o /boot/grub2/grub.cfg` On **Debian-like** distribution `update-grub` is an alias to `grub-mkconfig ...` - - - -### Customization: +### ⚙️ Customization: You have the possibility to modify many parameters in `/etc/default/grub-btrfs/config`. -See [config file](https://github.com/Antynea/grub-btrfs/blob/master/config) for more information. +For further information see [config file](https://github.com/Antynea/grub-btrfs/blob/master/config) or `man grub-btrfs` -- - - -### Automatically update grub upon snapshot: -To automatically regenerate `grub-btrfs.cfg` when a modification appears in the `/.snapshots` mount point, run -```bash -systemctl enable grub-btrfs.path -systemctl start grub-btrfs.path # In case the mount point is available already -``` -Monitoring starts automatically when the mount point becomes available. - -#### Snapshots not in `/.snapshots` -To modify `grub-btrfs.path` run -```bash -systemctl edit --full grub-btrfs.path -systemctl reenable grub-btrfs.path -``` -To find out the name of the `.mount` unit use `systemctl list-units -t mount`. - -**Timeshift** -1. Run `systemctl edit --full grub-btrfs.path` -1. Replace the whole block by: -``` -[Unit] -Description=Monitors for new snapshots -DefaultDependencies=no -Requires=run-timeshift-backup.mount -After=run-timeshift-backup.mount -BindsTo=run-timeshift-backup.mount - -[Path] -PathModified=/run/timeshift/backup/timeshift-btrfs/snapshots - -[Install] -WantedBy=run-timeshift-backup.mount -``` -1. Run `systemctl reenable grub-btrfs.path` to reload the changes you made - -1. Run `systemctl start grub-btrfs.path` to start monitoring.
Otherwise, the unit will automatically start monitoring when the mount point will be available. - -Note: -You can view your change to `systemctl cat grub-btrfs.path`. -To revert change use `systemctl revert grub-btrfs.path`. - ----- -### Automatically update grub upon restart/boot: -[Look at this comment](https://github.com/Antynea/grub-btrfs/issues/138#issuecomment-766918328) -Currently not implemented - -## -#### OpenRC -1. If you would like grub-btrfs menu to automatically update when a snapshot is created or deleted: -* Use `rc-config add grub-btrfsd default`, to start the grub-btrfsd daemon the next time the system boots. - * To start `grub-btrfsd` right now, run `rc-service grub-btrfsd start` - * `grub-btrfsd` automatically watches the snapshot directory of timeshift (/run/timeshift/backup/timeshift-btrfs/snapshots) - and updates the grub-menu when a change occurs. -* Currently untested for snapper - -2. If you would like grub-btrfs menu to automatically update on system restart/ shutdown: -Just add the following script as `/etc/local.d/grub-btrfs-update.stop` - ```bash - #!/bin/bash - - description="Update the grub btrfs snapshots menu" - name="grub-btrfs-update" - - depend() - { - use localmount - } - - bash -c 'if [ -s "${GRUB_BTRFS_GRUB_DIRNAME:-/boot/grub}/grub-btrfs.cfg" ]; then /etc/grub.d/41_snapshots-btrfs; else {GRUB_BTRFS_MKCONFIG:-grub-mkconfig} -o {GRUB_BTRFS_GRUB_DIRNAME:-/boot/grub}/grub.cfg; fi' - ``` - - Make your script executeable with `chmod a+x /etc/local.d/grub-btrfs-update.stop`. - -* The extension ".stop" at the end of the filename indicates to locald that this script should be run at shutdown. - If you want to run the menu update on startup instead, rename the file to `grub-btrfs-update.start` -* Works for snapper and timeshift - -##### Warning: +#### Warning: by default, `grub-mkconfig` command is used. Might be `grub2-mkconfig` on some systems (Fedora ...). Edit `GRUB_BTRFS_MKCONFIG` variable in `/etc/default/grub-btrfs/config` file to reflect this. +#### grub-btrfsd daemon + +Grub-btrfs comes with a daemon script that automatically updates the grub menu when it sees a snapshot being created or deleted in a directory it is given via command line. + +The daemon can be configured by passing different command line arguments to it. This can be change by either running +```bash +sudo systemctl edit --full grub-btrfsd +``` +(when using systemd) or by editing `/etc/conf.d/grub-btrfsd` (when using openRC). In either case the daemon must be restarted for the changes to take effect with +```bash +sudo systemctl restart grub-btrfsd # for systemd +``` +or +``` +sudo rc-service grub-btrfsd restart # for openRC +``` + +It is also possible to start the daemon without systemd or openRC. If you want to do this, the daemon should be stopped with +```bash +sudo systemctl stop grub-btrfsd # for systemd +``` +or +```bash +sudo rc-service grub-btrfsd stop # for openRC +``` +Then the daemon can be manually run and played around with with the command `grub-btrfsd`. +For additional information on daemon script and its arguments, run `grub-btrfsd -h` and see `man grub-btrfsd` + +- - - +### 🪀 Automatically update grub upon snapshot +Grub-btrfs comes with its own daemon, that watches the snapshot directory for you and updates the grub menu automatically every time a snapshot is created or deleted. +By default this daemon watches the directory `/.snapshots` for changes (new snapshots or deletion of snapshots) and triggers the grub menu creation if a snapshot is found. +Therefore, if Snapper is used with its default directory, the daemon can just be started and nothing needs to be configured. For configuration like Timeshift, or Snapper with a different directory, see further below. + +To start it now, run +```bash +sudo systemctl start grub-btrfsd # for systemd +``` +or +```bash +sudo rc-service grub-btrfsd start # for openRC +``` + +To activate it during system startup, run +```bash +sudo systemctl enable grub-btrfsd # for systemd +``` +or +```bash +sudo rc-config add grub-btrfsd default # for openRC +``` + +#### 💼 Snapshots not in `/.snapshots` +NOTE: This works also for Timeshift versions < 22.06, the path to watch would be `/run/timeshift/backup/timeshift-btrfs/snapshots`. + +##### Systemd +By default the daemon is watching the directory `/.snapshots`. If the daemon should watch a different directory, it can be edited with +```bash +sudo systemctl edit --full grub-btrfsd # for systemd +``` +What should be edited is the `/.snapshots`-part in the line that says `ExecStart=/usr/bin/grub-btrfsd --syslog /.snapshots`. +So this is what the file should look afterwards: +``` bash +[Unit] +Description=Regenerate grub-btrfs.cfg + +[Service] +Type=simple +LogLevelMax=notice +# Set the possible paths for `grub-mkconfig` +Environment="PATH=/sbin:/bin:/usr/sbin:/usr/bin" +# Load environment variables from the configuration +EnvironmentFile=/etc/default/grub-btrfs/config +# Start the daemon, usage of it is: +# grub-btrfsd [-h, --help] [-t, --timeshift-auto] [-l, --log-file LOG_FILE] SNAPSHOTS_DIR +# SNAPSHOTS_DIR Snapshot directory to watch, without effect when --timeshift-auto +# Optional arguments: +# -t, --timeshift-auto Automatically detect Timeshifts snapshot directory +# -l, --log-file Specify a logfile to write to +# -v, --verbose Let the log of the daemon be more verbose +# -s, --syslog Write to syslog +ExecStart=/usr/bin/grub-btrfsd --syslog /path/to/your/snapshot/directory + +[Install] +WantedBy=multi-user.target +``` + +When done, the service should be restarted with +``` bash +sudo systemctl restart grub-btrfsd # for systemd +``` + +##### OpenRC +Arguments are passed to grub-btrfsd via the file `/etc/conf.d/grub-btrfsd`. +The variable `snapshots` defines, where the daemon will watch for snapshots. + +After editing, the file should looks like this: +``` bash +# Copyright 2022 Pascal Jaeger +# Distributed under the terms of the GNU General Public License v3 + +## Where to locate the root snapshots +#snapshots="/.snapshots" # Snapper in the root directory +#snapshots="/run/timeshift/backup/timeshift-btrfs/snapshots" # Timeshift < v22.06 +snapshots="/path/to/your/snapshot/directory" + +## Optional arguments to run with the daemon +# Possible options are: +# -t, --timeshift-auto Automatically detect Timeshifts snapshot directory for timeshift >= 22.06 +# -l, --log-file Specify a logfile to write to +# -v, --verbose Let the log of the daemon be more verbose +# -s, --syslog Write to syslog +# Uncomment the line to activate the option +optional_args+="--syslog " # write to syslog by default +#optional_args+="--timeshift-auto " +#optional_args+="--log-file /var/log/grub-btrfsd.log " +#optional_args+="--verbose " +``` + +After that, the daemon should be restarted with +``` bash +sudo rc-service grub-btrfsd restart # for openRC +``` + +#### 🌟 Timeshift >= version 22.06 +Newer Timeshift versions create a new directory named after their process ID in `/run/timeshift` every time they are started. The PID is going to be different every time. +Therefore the daemon can not simply watch a directory, it watches `/run/timeshift` first, if a directory is created it gets Timeshifts current PID, then watches a directory in that newly created directory from Timeshift. +Anyhow, to activate this mode of the daemon, `--timeshift-auto` must be passed to the daemon as a command line argument. + +##### Systemd +To pass `--timeshift-auto` to grub-btrfsd, the servicefile of grub-btrfsd can be edited with +```bash +sudo systemctl edit --full grub-btrfsd # for systemd +``` + +The line that says +```bash +ExecStart=/usr/bin/grub-btrfsd /.snapshots --syslog + +``` + +should be edited into +``` bash +ExecStart=/usr/bin/grub-btrfsd --syslog --timeshift-auto +``` + +So the file looks like this, afterwards: +``` bash +[Unit] +Description=Regenerate grub-btrfs.cfg + +[Service] +Type=simple +LogLevelMax=notice +# Set the possible paths for `grub-mkconfig` +Environment="PATH=/sbin:/bin:/usr/sbin:/usr/bin" +# Load environment variables from the configuration +EnvironmentFile=/etc/default/grub-btrfs/config +# Start the daemon, usage of it is: +# grub-btrfsd [-h, --help] [-t, --timeshift-auto] [-l, --log-file LOG_FILE] SNAPSHOTS_DIR +# SNAPSHOTS_DIR Snapshot directory to watch, without effect when --timeshift-auto +# Optional arguments: +# -t, --timeshift-auto Automatically detect Timeshifts snapshot directory +# -l, --log-file Specify a logfile to write to +# -v, --verbose Let the log of the daemon be more verbose +# -s, --syslog Write to syslog +ExecStart=/usr/bin/grub-btrfsd --syslog --timeshift-auto + +[Install] +WantedBy=multi-user.target +``` + +When done, the service must be restarted with +``` bash +sudo systemctl restart grub-btrfsd # for systemd +``` + +Note: +You can view your change with `systemctl cat grub-btrfsd`. +To revert change use `systemctl revert grub-btrfsd`. + +##### OpenRC +Arguments are passed to grub-btrfsd via the file `/etc/conf.d/grub-btrfsd`. +The variable `optional_args` defines, which optional arguments get passed to the daemon. +Uncomment `#optional_args+="--timeshift-auto "` to pass the command line option `--timeshift-auto` to it. + +After the change, the file should look like this: +(Note that there is no need to comment out the `snapshots` variable. It is ignored when `--timeshift-auto` is active.) +``` bash +# Copyright 2022 Pascal Jaeger +# Distributed under the terms of the GNU General Public License v3 + +## Where to locate the root snapshots +snapshots="/.snapshots" # Snapper in the root directory +#snapshots="/run/timeshift/backup/timeshift-btrfs/snapshots" # Timeshift < v22.06 + +## Optional arguments to run with the daemon +# Possible options are: +# -t, --timeshift-auto Automatically detect Timeshifts snapshot directory for timeshift >= 22.06 +# -l, --log-file Specify a logfile to write to +# -v, --verbose Let the log of the daemon be more verbose +# -s, --syslog Write to syslog +# Uncomment the line to activate the option +optional_args+="--syslog " # write to syslog by default +optional_args+="--timeshift-auto " +#optional_args+="--log-file /var/log/grub-btrfsd.log " +#optional_args+="--verbose " +``` + + +After that, the daemon should be restarted with +``` bash +sudo rc-service grub-btrfsd restart # for openRC +``` + +---- +### ❇️ Automatically update grub upon restart/boot: +#### Systemd +[Look at this comment](https://github.com/Antynea/grub-btrfs/issues/138#issuecomment-766918328) +Currently not implemented + +#### OpenRC +If you would like the grub-btrfs menu to automatically update on system restart/ shutdown, just add the following script as `/etc/local.d/grub-btrfs-update.stop`: +```bash +#!/usr/bin/env bash + +description="Update the grub btrfs snapshots menu" +name="grub-btrfs-update" + +depend() +{ + use localmount +} + +bash -c 'if [ -s "${GRUB_BTRFS_GRUB_DIRNAME:-/boot/grub}/grub-btrfs.cfg" ]; then /etc/grub.d/41_snapshots-btrfs; else {GRUB_BTRFS_MKCONFIG:-grub-mkconfig} -o {GRUB_BTRFS_GRUB_DIRNAME:-/boot/grub}/grub.cfg; fi' +``` + +Make your script executable with `chmod a+x /etc/local.d/grub-btrfs-update.stop`. + +* The extension `.stop` at the end of the filename indicates to locald that this script should be run at shutdown. + If you want to run the menu update on startup instead, rename the file to `grub-btrfs-update.start` +* Works for snapper and timeshift + - - - ### Special thanks for assistance and contributions * [Maxim Baz](https://github.com/maximbaz) diff --git a/grub-btrfs-openrc b/grub-btrfs-openrc deleted file mode 100755 index 988be81..0000000 --- a/grub-btrfs-openrc +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh -echo $$ > /run/grub-btrfsd.pid -snapshots="${1:-/run/timeshift/backup/timeshift-btrfs/snapshots}" - -while true; do sleep 1 && inotifywait -e create -e delete "$snapshots" && sleep 5 && if [ -s "${GRUB_BTRFS_GRUB_DIRNAME:-/boot/grub}/grub-btrfs.cfg" ]; then /etc/grub.d/41_snapshots-btrfs; else ${GRUB_BTRFS_MKCONFIG:-grub-mkconfig} -o ${GRUB_BTRFS_GRUB_DIRNAME:-/boot/grub}/grub.cfg; fi ; done - - diff --git a/grub-btrfs.path b/grub-btrfs.path deleted file mode 100644 index b624a95..0000000 --- a/grub-btrfs.path +++ /dev/null @@ -1,12 +0,0 @@ -[Unit] -Description=Monitors for new snapshots -DefaultDependencies=no -Requires=\x2esnapshots.mount -After=\x2esnapshots.mount -BindsTo=\x2esnapshots.mount - -[Path] -PathModified=/.snapshots - -[Install] -WantedBy=\x2esnapshots.mount diff --git a/grub-btrfs.service b/grub-btrfs.service deleted file mode 100644 index 90d0ef9..0000000 --- a/grub-btrfs.service +++ /dev/null @@ -1,11 +0,0 @@ -[Unit] -Description=Regenerate grub-btrfs.cfg - -[Service] -Type=oneshot -# Set the possible paths for `grub-mkconfig` -Environment="PATH=/sbin:/bin:/usr/sbin:/usr/bin" -# Load environment variables from the configuration -EnvironmentFile=/etc/default/grub-btrfs/config -# Regenerate just '/boot/grub/grub-btrfs.cfg' if it exists and is not empty, else regenerate the whole grub menu -ExecStart=bash -c 'if [ -s "${GRUB_BTRFS_GRUB_DIRNAME:-/boot/grub}/grub-btrfs.cfg" ]; then /etc/grub.d/41_snapshots-btrfs; else ${GRUB_BTRFS_MKCONFIG:-grub-mkconfig} -o ${GRUB_BTRFS_GRUB_DIRNAME:-/boot/grub}/grub.cfg; fi' diff --git a/grub-btrfsd b/grub-btrfsd new file mode 100755 index 0000000..5988059 --- /dev/null +++ b/grub-btrfsd @@ -0,0 +1,223 @@ +#!/bin/sh +# Copyright 2022 Pascal Jaeger +# Distributed under the terms of the GNU General Public License v3 +# Update GRUB when new BTRFS snapshots are created. + +# init +timeshift_pid=-1 +watchtime=0 +logfile=0 +snapshots=-1 +timeshift_auto=false +verbose=false +syslog=false + +# helper functions +GREEN=$'\033[0;32m' +RED=$'\033[0;31m' +CYAN=$'\033[;36m' +RESET=$'\033[0m' + +print_help() { + echo "${CYAN}[?] Usage:" + echo "${0##*/} [-h, --help] [-t, --timeshift-auto] [-l, --log-file LOG_FILE] [-v, --verbose] [-s, --syslog] SNAPSHOTS_DIR" + echo + echo "SNAPSHOTS_DIR Snapshot directory to watch, without effect when --timeshift-auto" + echo + echo "Optional arguments:" + echo "-t, --timeshift-auto Automatically detect Timeshifts snapshot directory" + echo "-l, --log-file Specify a logfile to write to" + echo "-v, --verbose Let the log of the daemon be more verbose" + echo "-s, --syslog Write to syslog" + echo "-h, --help Display this message${RESET}" +} + +log() { + echo "${2}"$1"${RESET}" + if [ ${syslog} = true ]; then + logger -p user.notice -t ${0##*/}"["$$"]" "$1" + fi + if [ ${#logfile} -gt 1 ]; then + echo "$(date) ${1}" >> ${logfile} + fi +} + +vlog() { + if [ ${verbose} = true ]; then + echo "${2}"$1"${RESET}" + if [ ${syslog} = true ]; then + logger -p user.notice -t ${0##*/} "$1" + fi + if [ ${#logfile} -gt 1 ]; then + echo "$(date) ${1}" >> ${logfile} + fi + fi +} + +err() { + echo "${2}"${1}"${RESET}" >&2 + if [ ${syslog} = true ]; then + logger -p user.error -t ${0##*/} "$1" + fi + if [ ${#logfile} -gt 1 ]; then + echo "$(date) error: ${1}" >> ${logfile} + fi +} + +# parse arguments +while getopts :l:tvsh-: opt; do + case "$opt" in + -) + case "${OPTARG}" in + log-file) + logfile="${!OPTIND}"; OPTIND=$(( $OPTIND + 1 )) + ;; + timeshift-auto) + timeshift_auto=true + ;; + verbose) + verbose=true + ;; + syslog) + syslog=true + ;; + *) + if [ "$OPTERR" = 1 ] && [ "${optspec:0:1}" != ":" ]; then + err "[!] Unknown option --${OPTARG}" "${RED}" >&2 + echo + fi + print_help + exit 1 + ;; + esac;; + l) + logfile="${OPTARG}" + ;; + t) + timeshift_auto=true + ;; + v) + verbose=true + ;; + s) + syslog=true + ;; + h) + print_help + exit 0 + ;; + *) + if [ "$OPTERR" = 1 ] || [ "${optspec:0:1}" = ":" ]; then + err "[!] Non-option argument: '-${OPTARG}'" "${RED}" >&2 + echo + fi + print_help + exit 1 + ;; + esac +done +shift $(( OPTIND - 1 )) + +snapshots="${1}" + +if [ ${#logfile} -gt 1 ]; then + touch "${logfile}" + echo "GRUB-BTRFSD log $(date)" >> "${logfile}" +fi + +log "grub-btrfsd starting up..." "${GREEN}" + +if [ ${verbose} = true ]; then + inotify_qiet_flag="" +else + inotify_qiet_flag=" -q -q " +fi + +vlog "Arguments:" +vlog "Snapshot directory: $snapshots" +vlog "Timestift autodetection: $timeshift_auto" +vlog "Logfile: $logfile" + +if ! [ -d "$snapshots" ] && ! [ ${timeshift_auto} = true ]; then + err "[!] No directory found at ${snapshots}" "${RED}" >&2 + err "[!] Please specify a valid snapshot directory" "${RED}" >&2 + exit 1 +fi + +if [ ${timeshift_auto} = true ]; then + watchtime=15 + [ -d /run/timeshift ] || mkdir /run/timeshift +else + watchtime=0 +fi + +create_grub_menu() { + # create the grub submenu of the whole grub menu, depending on wether the submenu already exists + # and gives feedback if it worked + if [ -s "${GRUB_BTRFS_GRUB_DIRNAME:-/boot/grub}/grub-btrfs.cfg" ]; then + if /etc/grub.d/41_snapshots-btrfs; then + log "Grub submenu recreated" "${GREEN}" + else + err "[!] Error during grub submenu creation (grub-btrfs error)" "${RED}" + fi + else + if ${GRUB_BTRFS_MKCONFIG:-grub-mkconfig} -o ${GRUB_BTRFS_GRUB_DIRNAME:-/boot/grub}/grub.cfg; then + log "Grub menu recreated" "${GREEN}" + else + err "[!] Error during grub menu creation (grub/ grub-btrfs error)" "${RED}" + fi + fi +} + +# start the actual daemon +vlog "Snapshot dir watchtimeout: $watchtime" +vlog "Entering infinite while" "${GREEN}" +while true; do + runs=false + if [ ${timeshift_auto} = true ] && ! [ "${timeshift_pid}" -gt 0 ] ; then + # watch the timeshift folder for a folder that is created when timeshift starts up + sleep 1 # for safety so the outer while is not going crazy + if [ "${timeshift_pid}" -eq -2 ]; then + log "detected timeshift shutdown" + fi + timeshift_pid=$(ps ax | awk '{sub(/.*\//, "", $5)} $5 ~ /timeshift/ {print $1}') + if [ "${#timeshift_pid}" -gt 0 ]; then + snapshots="/run/timeshift/${timeshift_pid}/backup/timeshift-btrfs/snapshots" + log "detected running Timeshift at daemon startup, PID is: $timeshift_pid" + vlog "new snapshots directory is $snapshots" + else + log "Watching /run/timeshift for timeshift to start" + inotifywait ${inotify_qiet_flag} -e create -e delete /run/timeshift && { + sleep 1 + timeshift_pid=$(ps ax | awk '{sub(/.*\//, "", $5)} $5 ~ /timeshift/ {print $1}') + snapshots="/run/timeshift/${timeshift_pid}/backup/timeshift-btrfs/snapshots" + log "detected Timeshift startup, PID is: $timeshift_pid" "${CYAN}" + vlog "new snapshots directory is $snapshots" "${CYAN}" + (create_grub_menu) # create the grub menu once immidiatly in a forking process. Snapshots from commandline using timeshift --create need this + } + fi + runs=false + else + while [ -d "$snapshots" ]; do + # watch the actual snapshots folder for a new snapshot or a deletion of a snapshot + if [ ${runs} = false ] && [ ${verbose} = false ]; then + log "Watching $snapshots for new snapshots..." "${CYAN}" + else + vlog "Watching $snapshots for new snapshots..." "${CYAN}" + fi + runs=true + inotifywait ${inotify_qiet_flag} -e create -e delete -e unmount -t "$watchtime" "$snapshots" && { + log "Detected snapshot creation/ deletion, recreating Grub menu" "${CYAN}" + sleep 5 + create_grub_menu + } + sleep 1 + done + timeshift_pid=-2 + fi + if ! [ ${timeshift_auto} = true ] && ! [ -d "${snapshots}" ] ; then # in case someone deletes the snapshots folder (in snapper mode) to prevent the while loop from going wild + break + fi +done + +exit 0 # tradition is tradition diff --git a/grub-btrfsd.confd b/grub-btrfsd.confd index 9033c82..7d12ca1 100644 --- a/grub-btrfsd.confd +++ b/grub-btrfsd.confd @@ -1,3 +1,18 @@ -# Where to locate the root snapshots -#snapshots="/.snapshots" # Snapper in the root directory -snapshots="/run/timeshift/backup/timeshift-btrfs/snapshots" # Timeshift +# Copyright 2022 Pascal Jaeger +# Distributed under the terms of the GNU General Public License v3 + +## Where to locate the root snapshots +snapshots="/.snapshots" # Snapper in the root directory +#snapshots="/run/timeshift/backup/timeshift-btrfs/snapshots" # Timeshift < v22.06 + +## Optional arguments to run with the daemon +# Possible options are: +# -t, --timeshift-auto Automatically detect Timeshifts snapshot directory for timeshift >= 22.06 +# -l, --log-file Specify a logfile to write to +# -v, --verbose Let the log of the daemon be more verbose +# -s, --syslog Write to syslog +# Uncomment the line to activate the option +optional_args+="--syslog " # write to syslog by default +#optional_args+="--timeshift-auto " +#optional_args+="--log-file /var/log/grub-btrfsd.log " +#optional_args+="--verbose " diff --git a/grub-btrfsd.initd b/grub-btrfsd.initd index 3782782..2ffb8b1 100755 --- a/grub-btrfsd.initd +++ b/grub-btrfsd.initd @@ -1,15 +1,13 @@ #!/sbin/openrc-run -# Copyright 1999-2021 Gentoo Foundation -# Distributed under the terms of the GNU General Public License v2 +# Copyright 2021 Pascal Jaeger +# Distributed under the terms of the GNU General Public License v3 name="grub-btrfs daemon" -command="/usr/bin/grub-btrfs-openrc" -command_args="${snapshots}" +command="/usr/bin/grub-btrfsd" +command_args="$optional_args ${snapshots}" pidfile="/run/{RC_SVCNAME}.pid" command_background=true depend() { use localmount } - - diff --git a/grub-btrfsd.service b/grub-btrfsd.service new file mode 100644 index 0000000..35a9ad9 --- /dev/null +++ b/grub-btrfsd.service @@ -0,0 +1,22 @@ +[Unit] +Description=Regenerate grub-btrfs.cfg + +[Service] +Type=simple +LogLevelMax=notice +# Set the possible paths for `grub-mkconfig` +Environment="PATH=/sbin:/bin:/usr/sbin:/usr/bin" +# Load environment variables from the configuration +EnvironmentFile=/etc/default/grub-btrfs/config +# Start the daemon, usage of it is: +# grub-btrfsd [-h, --help] [-t, --timeshift-auto] [-l, --log-file LOG_FILE] SNAPSHOTS_DIR +# SNAPSHOTS_DIR Snapshot directory to watch, without effect when --timeshift-auto +# Optional arguments: +# -t, --timeshift-auto Automatically detect Timeshifts snapshot directory +# -l, --log-file Specify a logfile to write to +# -v, --verbose Let the log of the daemon be more verbose +# -s, --syslog Write to syslog +ExecStart=/usr/bin/grub-btrfsd --syslog /.snapshots + +[Install] +WantedBy=multi-user.target diff --git a/manpages/grub-btrfs.8.man b/manpages/grub-btrfs.8.man new file mode 100644 index 0000000..86b4db4 --- /dev/null +++ b/manpages/grub-btrfs.8.man @@ -0,0 +1,240 @@ +.TH "grub-btrfs" "8" + +.SH "NAME" +.PP +grub-btrfs - Automatically add btrfs-Snapshots as a Grub submenu + +.SH "SYNOPSIS" +.PP +/etc/grub.d/41\d\s-2snapshots\s+2\u-btrfs + +.SH "DESCRIPTION" +.PP +Improves grub by adding “btrfs snapshots” to the grub menu. + +.PP +You can boot your system on a “snapshot” from the grub menu. +Supports manual snapshots, snapper and timeshift. +Features of grub-btrfs: +.IP \(em 4 +Automatically list snapshots existing on root partition (btrfs). +.IP \(em 4 +Automatically detect if /boot is in separate partition. +.IP \(em 4 +Automatically detect kernel, initramfs and intel/amd microcode in /boot directory on snapshots. +.IP \(em 4 +Automatically create corresponding “menuentry” in grub.cfg +.IP \(em 4 +Automatically detect the type/tags and descriptions/comments of snapper/timeshift snapshots. +.IP \(em 4 +Automatically generate grub.cfg if you use the provided systemd service. + +.SH "CONFIGURATION" +.PP +grub-btrfs is configured via the file \fC/etc/default/grub\-btrfs/config\fP. +Possible options are: + +.SS "GENERAL" +.SS "\fCGRUB_BTRFS_DISABLE\fP" +.PP +Disable grub-btrfs if true. +.IP \(em 4 +Default: “false” +.IP \(em 4 +Example: \fCGRUB_BTRFS_DISABLE="true"\fP + +.SS "\fCGRUB_BTRFS_TITLE_FORMAT\fP" +.PP +The snapshot entries submenu in Grub are added according to this line. It is possible to change to order of the fields. +.IP \(em 4 +Default: (“date” “snapshot” “type” “description”) +.PP +-Example: \fCGRUB_BTRFS_TITLE_FORMAT=("date" "snapshot" "type" "description")\fP + +.SS "\fCGRUB_BTRFS_LIMIT\fP" +.PP +Maximum number of snapshots in the GRUB snapshots sub menu. +.IP \(em 4 +Default: “50” +.PP +-Example: \fCGRUB_BTRFS_LIMIT="50"\fP + +.SS "\fCGRUB_BTRFS_SUBVOLUME_SORT\fP" +.PP +Sort the found subvolumes by “ogeneration” or “generation” or “path” or “rootid”. +.IP \(em 4 +See Sorting section in +.BR btrfs-subvolume (8) +.PP +“-rootid” means list snapshot by new ones first. +.IP \(em 4 +Default: “-rootid” +.PP +-Example: \fCGRUB_BTRFS_SUBVOLUME_SORT="+ogen,\-gen,path,rootid"\fP + +.SS "\fCGRUB_BTRFS_SHOW_SNAPSHOTS_FOUND\fP" +.PP +Show snapshots found during run “grub-mkconfig” +.IP \(em 4 +Default: “true” +.PP +-Example: \fCGRUB_BTRFS_SHOW_SNAPSHOTS_FOUND="false"\fP + +.SS "\fCGRUB_BTRFS_ROOTFLAGS\fP" +.PP +Comma seperated mount options to be used when booting a snapshot. +They can be defined here as well as in the “/” line inside the respective snapshots’ +“/etc/fstab” files. Mount options found in both places are combined, and this variable +takes priority over `fstab` entries. +NB: Do NOT include “subvol=...” or “subvolid=...” here. +.IP \(em 4 +Default: “” +.PP +-Example: \fCGRUB_BTRFS_ROOTFLAGS="space_cache,commit=10,norecovery"\fP + +.SS "\fCGRUB_BTRFS_OVERRIDE_BOOT_PARTITION_DETECTION\fP" +.PP +By default “grub-btrfs” automatically detects your boot partition, +either located at the system root or on a separate partition or in a subvolume, +Change to “true” if your boot partition is not detected as separate. +.IP \(em 4 +Default: “false” +.PP +-Example: \fCGRUB_BTRFS_OVERRIDE_BOOT_PARTITION_DETECTION="true"\fP + +.SS "CUSTOM KERNELS" +.SS "\fCGRUB_BTRFS_NKERNEL\fP / \fCGRUB_BTRFS_NINIT\fP / \fCGRUB_BTRFS_CUSTOM_MICROCODE\fP" +.PP +By default, “grub-btrfs” automatically detects most existing kernels, initramfs and microcode. +Customs kernel, initramfs and microcodes that are not detected can be added in these variables. +.IP \(em 4 +Default: (“”) +.PP +-Example: \fCGRUB_BTRFS_NKERNEL=("kernel\-5.19.4\-custom" "vmlinux\-5.19.4\-custom")\fP + \fCGRUB_BTRFS_NINIT=("initramfs\-5.19.4\-custom.img" "initrd\-5.19.4\-custom.img" "otherinit\-5.19.4\-custom.gz")\fP + \fCGRUB_BTRFS_CUSTOM_MICROCODE=("custom\-ucode.img" "custom\-uc.img "custom_ucode.cpio")\fP + +.SS "SNAPSHOT FILTERING" +.SS "\fCGRUB_BTRFS_IGNORE_SPECIFIC_PATH\fP" +.PP +Ignore specific path during run “grub-mkconfig”. +Only exact paths are ignored. +e.g : if `specific path` = @, only `@` snapshot will be ignored. +.IP \(em 4 +Default: (“@”) +.PP +-Example: \fCGRUB_BTRFS_IGNORE_SPECIFIC_PATH=("@home")\fP + +.SS "\fCGRUB_BTRFS_IGNORE_PREFIX_PATH\fP" +.PP +Ignore prefix path during run “grub-mkconfig”. +Any path starting with the specified string will be ignored. +e.g : if `prefix path` = @, all snapshots beginning with “@/...” will be ignored. +.IP \(em 4 +Default: (“var/lib/docker” “@var/lib/docker” “@/var/lib/docker”) +.PP +-Example: \fCGRUB_BTRFS_IGNORE_PREFIX_PATH=("var/lib/docker" "@var/lib/docker" "@/var/lib/docker")\fP + +.SS "\fCGRUB_BTRFS_IGNORE_SNAPSHOT_TYPE\fP" +.PP +Ignore specific type/tag of snapshot during run “grub-mkconfig”. +For snapper: +Type = single, pre, post. +For Timeshift: +Tag = boot, ondemand, hourly, daily, weekly, monthly. +.IP \(em 4 +Default: (“”) +.PP +-Example: \fCGRUB_BTRFS_IGNORE_SNAPSHOT_TYPE=("ondemand")\fP + +.SS "\fCGRUB_BTRFS_IGNORE_SNAPSHOT_DESCRIPTION\fP" +.PP +Ignore specific description of snapshot during run “grub-mkconfig”. +.IP \(em 4 +Default: (“”) +.PP +-Example: \fCGRUB_BTRFS_IGNORE_SNAPSHOT_DESCRIPTION=("timeline")\fP + +.SS "DISTRIBUTION DEPENDENT SETTINGS" +.SS "\fCGRUB_BTRFS_BOOT_DIRNAME\fP" +.PP +Location of kernels/initramfs/microcode. +Used by “grub-btrfs” to detect the boot partition and the location of kernels, initramfs and microcodes. +.IP \(em 4 +Default: “/boot” +.PP +-Example: \fCGRUB_BTRFS_BOOT_DIRNAME="/"\fP + +.SS "\fCGRUB_BTRFS_GRUB_DIRNAME\fP" +.PP +Location of the folder containing the “grub.cfg” file. +Used by grub-btrfs to save the file “grub-btrfs.cfg”. +Might be grub2 on some systems. +For example, on Fedora with EFI : “/boot/efi/EFI/fedora” +.IP \(em 4 +Default: “/boot/grub” +.PP +-Example: \fCGRUB_BTRFS_GRUB_DIRNAME="/boot/grub2"\fP + +.SS "\fCGRUB_BTRFS_MKCONFIG\fP" +.PP +Name/path of the command to generate the grub menu, used by “grub-btrfs.service” +Might be ’grub2-mkconfig’ on some systems (e.g. Fedora) +Default paths are /sbin:/bin:/usr/sbin:/usr/bin, if your path is missing, report it on the upstream project. +You can use the name of the command only or full the path. +.IP \(em 4 +Default: grub-mkconfig +.PP +-Example: \fCGRUB_BTRFS_MKCONFIG=/sbin/grub2\-mkconfig\fP + +.SS "\fCGRUB_BTRFS_SCRIPT_CHECK\fP" +.PP +Name of grub-script-check command, used by “grub-btrfs” +Might be ’grub2-script-check’ on some systems (e.g. Fedora) +.IP \(em 4 +Default: grub-script-check +.IP \(em 4 +Example: \fCGRUB_BTRFS_SCRIPT_CHECK=grub2\-script\-check\fP + +.SS "\fCGRUB_BTRFS_MKCONFIG_LIB\fP" +.PP +Path of grub-mkconfig\d\s-2lib\s+2\u file, used by “grub-btrfs” +Might be ’/usr/share/grub2/grub-mkconfig\d\s-2lib\s+2\u’ on some systems (e.g. Opensuse) +.IP \(em 4 +Default: /usr/share/grub/grub-mkconfig\d\s-2lib\s+2\u +.IP \(em 4 +Example: \fCGRUB_BTRFS_MKCONFIG_LIB=/usr/share/grub2/grub\-mkconfig_lib\fP + +.SS "SECURITY" +.SS "\fCGRUB_BTRFS_PROTECTION_AUTHORIZED_USERS\fP" +.PP +Password protection management for submenu, snapshots +Refer to the Grub documentation \fIhttps://www.gnu.org/software/grub/manual/grub/grub.html#Authentication-and-authorisation\fP +and this comment \fIhttps://github.com/Antynea/grub-btrfs/issues/95#issuecomment-682295660\fP +Add authorized usernames separate by comma (userfoo,userbar). +When Grub’s password protection is enabled, the superuser is authorized by default, it is not necessary to add it +.IP \(em 4 +Default: “- Example: \fCGRUB_BTRFS_PROTECTION_AUTHORIZED_USERS="userfoo,userbar"\fP + +.SS "\fCGRUB_BTRFS_DISABLE_PROTECTION_SUBMENU\fP" +.PP +Disable authentication support for submenu of Grub-btrfs only (--unrestricted) +does not work if GRUB\d\s-2BTRFS\s+2\u\d\s-2PROTECTION\s+2\u\d\s-2AUTHORIZED\s+2\u\d\s-2USERS\s+2\u is not empty +.IP \(em 4 +Default: “false” +.IP \(em 4 +Example: \fCGRUB_BTRFS_DISABLE_PROTECTION_SUBMENU="true"\fP + +.SH "FILES" +.PP +/etc/default/grub-btrfs/config + +.SH "SEE ALSO" +.IR btrfs (8) +.IR btrfs-subvolume (8) +.IR grub-btrfsd (8) +.IR grub-mkconfig (8) + +.SH "COPYRIGHT" +.PP +Copyright (c) 2022 Pascal Jäger diff --git a/manpages/grub-btrfs.8.org b/manpages/grub-btrfs.8.org new file mode 100644 index 0000000..5e6a225 --- /dev/null +++ b/manpages/grub-btrfs.8.org @@ -0,0 +1,180 @@ +#+title: grub-btrfs +#+author: Pascal Jaeger +#+man_class_option: :sectionid 8 + +* NAME + grub-btrfs - Automatically add btrfs-Snapshots as a Grub submenu + +* SYNOPSIS +/etc/grub.d/41_snapshots-btrfs + +* DESCRIPTION +Improves grub by adding "btrfs snapshots" to the grub menu. + +You can boot your system on a "snapshot" from the grub menu. +Supports manual snapshots, snapper and timeshift. +Features of grub-btrfs: +- Automatically list snapshots existing on root partition (btrfs). +- Automatically detect if /boot is in separate partition. +- Automatically detect kernel, initramfs and intel/amd microcode in /boot directory on snapshots. +- Automatically create corresponding "menuentry" in grub.cfg +- Automatically detect the type/tags and descriptions/comments of snapper/timeshift snapshots. +- Automatically generate grub.cfg if you use the provided systemd service. + +* CONFIGURATION +grub-btrfs is configured via the file ~/etc/default/grub-btrfs/config~. +Possible options are: + +** GENERAL + +*** ~GRUB_BTRFS_DISABLE~ +Disable grub-btrfs if true. +- Default: "false" +- Example: ~GRUB_BTRFS_DISABLE="true"~ + +*** ~GRUB_BTRFS_TITLE_FORMAT~ +The snapshot entries submenu in Grub are added according to this line. It is possible to change to order of the fields. +- Default: ("date" "snapshot" "type" "description") +-Example: ~GRUB_BTRFS_TITLE_FORMAT=("date" "snapshot" "type" "description")~ + +*** ~GRUB_BTRFS_LIMIT~ +Maximum number of snapshots in the GRUB snapshots sub menu. +- Default: "50" +-Example: ~GRUB_BTRFS_LIMIT="50"~ + +*** ~GRUB_BTRFS_SUBVOLUME_SORT~ +Sort the found subvolumes by "ogeneration" or "generation" or "path" or "rootid". +- See Sorting section in +#+BEGIN_MAN +.BR btrfs-subvolume (8) +#+END_MAN +"-rootid" means list snapshot by new ones first. +- Default: "-rootid" +-Example: ~GRUB_BTRFS_SUBVOLUME_SORT="+ogen,-gen,path,rootid"~ + +*** ~GRUB_BTRFS_SHOW_SNAPSHOTS_FOUND~ +Show snapshots found during run "grub-mkconfig" +- Default: "true" +-Example: ~GRUB_BTRFS_SHOW_SNAPSHOTS_FOUND="false"~ + +*** ~GRUB_BTRFS_ROOTFLAGS~ +Comma seperated mount options to be used when booting a snapshot. +They can be defined here as well as in the "/" line inside the respective snapshots' +"/etc/fstab" files. Mount options found in both places are combined, and this variable +takes priority over `fstab` entries. +NB: Do NOT include "subvol=..." or "subvolid=..." here. +- Default: "" +-Example: ~GRUB_BTRFS_ROOTFLAGS="space_cache,commit=10,norecovery"~ + +*** ~GRUB_BTRFS_OVERRIDE_BOOT_PARTITION_DETECTION~ +By default "grub-btrfs" automatically detects your boot partition, +either located at the system root or on a separate partition or in a subvolume, +Change to "true" if your boot partition is not detected as separate. +- Default: "false" +-Example: ~GRUB_BTRFS_OVERRIDE_BOOT_PARTITION_DETECTION="true"~ + +** CUSTOM KERNELS + +*** ~GRUB_BTRFS_NKERNEL~ / ~GRUB_BTRFS_NINIT~ / ~GRUB_BTRFS_CUSTOM_MICROCODE~ +By default, "grub-btrfs" automatically detects most existing kernels, initramfs and microcode. +Customs kernel, initramfs and microcodes that are not detected can be added in these variables. +- Default: ("") +-Example: ~GRUB_BTRFS_NKERNEL=("kernel-5.19.4-custom" "vmlinux-5.19.4-custom")~ + ~GRUB_BTRFS_NINIT=("initramfs-5.19.4-custom.img" "initrd-5.19.4-custom.img" "otherinit-5.19.4-custom.gz")~ + ~GRUB_BTRFS_CUSTOM_MICROCODE=("custom-ucode.img" "custom-uc.img "custom_ucode.cpio")~ + +** SNAPSHOT FILTERING + +*** ~GRUB_BTRFS_IGNORE_SPECIFIC_PATH~ +Ignore specific path during run "grub-mkconfig". +Only exact paths are ignored. +e.g : if `specific path` = @, only `@` snapshot will be ignored. +- Default: ("@") +-Example: ~GRUB_BTRFS_IGNORE_SPECIFIC_PATH=("@home")~ + +*** ~GRUB_BTRFS_IGNORE_PREFIX_PATH~ +Ignore prefix path during run "grub-mkconfig". +Any path starting with the specified string will be ignored. +e.g : if `prefix path` = @, all snapshots beginning with "@/..." will be ignored. +- Default: ("var/lib/docker" "@var/lib/docker" "@/var/lib/docker") +-Example: ~GRUB_BTRFS_IGNORE_PREFIX_PATH=("var/lib/docker" "@var/lib/docker" "@/var/lib/docker")~ + +*** ~GRUB_BTRFS_IGNORE_SNAPSHOT_TYPE~ +Ignore specific type/tag of snapshot during run "grub-mkconfig". +For snapper: +Type = single, pre, post. +For Timeshift: +Tag = boot, ondemand, hourly, daily, weekly, monthly. +- Default: ("") +-Example: ~GRUB_BTRFS_IGNORE_SNAPSHOT_TYPE=("ondemand")~ + +*** ~GRUB_BTRFS_IGNORE_SNAPSHOT_DESCRIPTION~ +Ignore specific description of snapshot during run "grub-mkconfig". +- Default: ("") +-Example: ~GRUB_BTRFS_IGNORE_SNAPSHOT_DESCRIPTION=("timeline")~ + +** DISTRIBUTION DEPENDENT SETTINGS + +*** ~GRUB_BTRFS_BOOT_DIRNAME~ +Location of kernels/initramfs/microcode. +Used by "grub-btrfs" to detect the boot partition and the location of kernels, initramfs and microcodes. +- Default: "/boot" +-Example: ~GRUB_BTRFS_BOOT_DIRNAME="/"~ + +*** ~GRUB_BTRFS_GRUB_DIRNAME~ +Location of the folder containing the "grub.cfg" file. +Used by grub-btrfs to save the file "grub-btrfs.cfg". +Might be grub2 on some systems. +For example, on Fedora with EFI : "/boot/efi/EFI/fedora" +- Default: "/boot/grub" +-Example: ~GRUB_BTRFS_GRUB_DIRNAME="/boot/grub2"~ + +*** ~GRUB_BTRFS_MKCONFIG~ +Name/path of the command to generate the grub menu, used by "grub-btrfs.service" +Might be 'grub2-mkconfig' on some systems (e.g. Fedora) +Default paths are /sbin:/bin:/usr/sbin:/usr/bin, if your path is missing, report it on the upstream project. +You can use the name of the command only or full the path. +- Default: grub-mkconfig +-Example: ~GRUB_BTRFS_MKCONFIG=/sbin/grub2-mkconfig~ + +*** ~GRUB_BTRFS_SCRIPT_CHECK~ +Name of grub-script-check command, used by "grub-btrfs" +Might be 'grub2-script-check' on some systems (e.g. Fedora) +- Default: grub-script-check +- Example: ~GRUB_BTRFS_SCRIPT_CHECK=grub2-script-check~ + +*** ~GRUB_BTRFS_MKCONFIG_LIB~ +Path of grub-mkconfig_lib file, used by "grub-btrfs" +Might be '/usr/share/grub2/grub-mkconfig_lib' on some systems (e.g. Opensuse) +- Default: /usr/share/grub/grub-mkconfig_lib +- Example: ~GRUB_BTRFS_MKCONFIG_LIB=/usr/share/grub2/grub-mkconfig_lib~ + +** SECURITY + +*** ~GRUB_BTRFS_PROTECTION_AUTHORIZED_USERS~ +Password protection management for submenu, snapshots +Refer to the Grub documentation https://www.gnu.org/software/grub/manual/grub/grub.html#Authentication-and-authorisation +and this comment https://github.com/Antynea/grub-btrfs/issues/95#issuecomment-682295660 +Add authorized usernames separate by comma (userfoo,userbar). +When Grub's password protection is enabled, the superuser is authorized by default, it is not necessary to add it +- Default: "- Example: ~GRUB_BTRFS_PROTECTION_AUTHORIZED_USERS="userfoo,userbar"~ + +*** ~GRUB_BTRFS_DISABLE_PROTECTION_SUBMENU~ +Disable authentication support for submenu of Grub-btrfs only (--unrestricted) +does not work if GRUB_BTRFS_PROTECTION_AUTHORIZED_USERS is not empty +- Default: "false" +- Example: ~GRUB_BTRFS_DISABLE_PROTECTION_SUBMENU="true"~ + +* FILES +/etc/default/grub-btrfs/config + +* SEE ALSO +#+BEGIN_MAN +.IR btrfs (8) +.IR btrfs-subvolume (8) +.IR grub-btrfsd (8) +.IR grub-mkconfig (8) +#+END_MAN + +* COPYRIGHT +Copyright (c) 2022 Pascal Jäger diff --git a/manpages/grub-btrfsd.8.man b/manpages/grub-btrfsd.8.man new file mode 100644 index 0000000..9158d62 --- /dev/null +++ b/manpages/grub-btrfsd.8.man @@ -0,0 +1,71 @@ +.TH "grub-btrfsd" "8" + +.SH "NAME" +.PP +grub-btrfsd - An OpenRC daemon to automatically update the grub menu with +.BR grub-btrfs (8) +.PP +when a new btrfs snapshot is created. + +.SH "SYNOPSIS" +.PP +\fCgrub\-btrfsd [\-h, \-\-help] [\-t, \-\-timeshift\-auto] [\-l, \-\-log\-file LOG_FILE] [\-v, \-\-verbose] [\-s, \-\-syslog] SNAPSHOTS_DIR\fP + +.SH "DESCRIPTION" +.PP +Grub-btrfs-openrc is a shell script which is meant to be run as a daemon. +Grub-btrfsd watches a directory where snapshots are created or deleted via inotifywait and runs grub-mkconfig (if grub-mkconfig never ran before since grub-btrfs was installed) or \fC/etc/grub.d/41_snapshots\-btrfs\fP (when grub-mkconfig ran before with grub-btrfs installed) when something in that directory changes. + +.SH "OPTIONS" +.SS "\fCSNAPSHOTS_DIR\fP" +.PP +This argument specifies the path where grub-btrfsd looks for newly created snapshots and snapshot deletions. It is usually defined by the program used to make snapshots. +E.g. for Snapper this would be \fC/.snapshots\fP + +.SS "\fC\-t / \-\-timeshift\-auto\fP" +.PP +This is a flag to activate the auto detection of the path where Timeshift stores snapshots. Newer versions (>=22.06) of Timeshift mount their snapshots to \fC/run/timeshift/$PID/backup/timeshift\-btrfs\fP. Where \fC$PID\fP is the process ID of the currently running Timeshift session. The PID is changing every time Timeshift is opened. grub-btrfsd can automatically take care of the detection of the correct PID and directory if this flag is set. In this case the argument \fCSNAPSHOTS_DIR\fP has no effect. + +.SS "\fC\-l / \-\-log\-file\fP" +.PP +This arguments specifies a file where grub-btrfsd should write log messages. + +.SS "\fC\-h / \-\-help\fP" +.PP +Displays a short help message. + +.SS "\fC\-v / \-\-verbose\fP" +.PP +Let the log of the daemon be more verbose + +.SS "\fC\-s / \-\-syslog\fP" +.PP +Write to syslog + +.SH "CONFIGURATION" +.PP +The daemon is usually configured via the file \fC/etc/conf.d/grub\-btrfsd\fP on openrc-init systems and \fCsudo systemctl edit \-\-full grub\-btrfsd\fP on systemd systems. In this file the arguments (See OPTIONS), that OpenRC passes to the daemon when it is started, can be configured. + +.SS "NOTES" +.PP +A common configuration for Snapper would be to set \fCSNAPSHOTS_DIR\fP to \fC/.snapshots\fP and not to set \fC\-\-timeshift\-auto\fP. +For Timeshift \fC\-\-timeshift\-auto\fP is set to true and \fCSNAPSHOTS_DIR\fP can be left as is. + +.SH "FILES" +.PP +\fC/etc/conf.d/grub\-btrfsd\fP +\fC/usr/lib/systemd/system/grub\-btrfsd.service\fP + +.SH "SEE ALSO" +.IR btrfs (8) +.IR btrfs-subvolume (8) +.IR grub-btrfsd (8) +.IR grub-mkconfig (8) +.IR inotifywait (1) +.IR openrc (8) +.IR rc-service (8) +.IR timeshift (1) + +.SH "COPYRIGHT" +.PP +Copyright (c) 2022 Pascal Jäger diff --git a/manpages/grub-btrfsd.8.org b/manpages/grub-btrfsd.8.org new file mode 100644 index 0000000..c6521fa --- /dev/null +++ b/manpages/grub-btrfsd.8.org @@ -0,0 +1,63 @@ +#+title: grub-btrfsd +#+author: Pascal Jaeger +#+man_class_option: :sectionid 8 + +* NAME +grub-btrfsd - An OpenRC daemon to automatically update the grub menu with +#+BEGIN_MAN +.BR grub-btrfs (8) +#+END_MAN +when a new btrfs snapshot is created. + +* SYNOPSIS +~grub-btrfsd [-h, --help] [-t, --timeshift-auto] [-l, --log-file LOG_FILE] [-v, --verbose] [-s, --syslog] SNAPSHOTS_DIR~ + +* DESCRIPTION +Grub-btrfs-openrc is a shell script which is meant to be run as a daemon. +Grub-btrfsd watches a directory where snapshots are created or deleted via inotifywait and runs grub-mkconfig (if grub-mkconfig never ran before since grub-btrfs was installed) or ~/etc/grub.d/41_snapshots-btrfs~ (when grub-mkconfig ran before with grub-btrfs installed) when something in that directory changes. + +* OPTIONS +** ~SNAPSHOTS_DIR~ +This argument specifies the path where grub-btrfsd looks for newly created snapshots and snapshot deletions. It is usually defined by the program used to make snapshots. +E.g. for Snapper this would be ~/.snapshots~ + +** ~-t / --timeshift-auto~ +This is a flag to activate the auto detection of the path where Timeshift stores snapshots. Newer versions (>=22.06) of Timeshift mount their snapshots to ~/run/timeshift/$PID/backup/timeshift-btrfs~. Where ~$PID~ is the process ID of the currently running Timeshift session. The PID is changing every time Timeshift is opened. grub-btrfsd can automatically take care of the detection of the correct PID and directory if this flag is set. In this case the argument ~SNAPSHOTS_DIR~ has no effect. + +** ~-l / --log-file~ +This arguments specifies a file where grub-btrfsd should write log messages. + +** ~-h / --help~ +Displays a short help message. + +** ~-v / --verbose~ +Let the log of the daemon be more verbose + +** ~-s / --syslog~ +Write to syslog + +* CONFIGURATION +The daemon is usually configured via the file ~/etc/conf.d/grub-btrfsd~ on openrc-init systems and ~sudo systemctl edit --full grub-btrfsd~ on systemd systems. In this file the arguments (See OPTIONS), that OpenRC passes to the daemon when it is started, can be configured. + +** NOTES +A common configuration for Snapper would be to set ~SNAPSHOTS_DIR~ to ~/.snapshots~ and not to set ~--timeshift-auto~. +For Timeshift ~--timeshift-auto~ is set to true and ~SNAPSHOTS_DIR~ can be left as is. + +* FILES +~/etc/conf.d/grub-btrfsd~ +~/usr/lib/systemd/system/grub-btrfsd.service~ + +* SEE ALSO +#+BEGIN_MAN +.IR btrfs (8) +.IR btrfs-subvolume (8) +.IR grub-btrfsd (8) +.IR grub-mkconfig (8) +.IR inotifywait (1) +.IR openrc (8) +.IR rc-service (8) +.IR timeshift (1) +#+END_MAN + +* COPYRIGHT +Copyright (c) 2022 Pascal Jäger