From 2bde7ce22406e0232e513235c4317cb762a24c6e Mon Sep 17 00:00:00 2001 From: Jarno Rankinen <50285623+0ranki@users.noreply.github.com> Date: Sat, 1 Aug 2020 09:52:21 +0300 Subject: [PATCH 1/6] Update README.md Added requirements --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index fbb6230..2bcd3a5 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,7 @@ # snapsh -Btrfs snapshot managing script +Btrfs snapshot managing bash script + +###### Requirements: +- `bash` +- GNU `setopt` - part of GNU `coreutils` +- `btrfs-progs`- Userspace programs for btrfs -- 2.40.1 From 4d4dcb311bf4edf0db0335d063a4c588cad3c80b Mon Sep 17 00:00:00 2001 From: Jarno Rankinen <50285623+0ranki@users.noreply.github.com> Date: Sat, 1 Aug 2020 20:19:47 +0300 Subject: [PATCH 2/6] Update README.md Added configuration and basic snapshotting instructions --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2bcd3a5..a2adbb4 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,13 @@ # snapsh Btrfs snapshot managing bash script -###### Requirements: +### Requirements: - `bash` - GNU `setopt` - part of GNU `coreutils` - `btrfs-progs`- Userspace programs for btrfs + +### Instructions: +- Script needs the toplevel subvolume (id=5) mounted somewhere. Default location is `/root/btrfs-toplevel`, but you can mount it anywhere you like and define it with `TOPLEVEL` variable. (A separate config file will be implemented later). +- Will create a subvolume named snapshots by default to the toplevel. This can also be changed with `SNAPSHOTS_LOCATION`. +- Display usage instructions with `snapsh -h` or `snapsh --help` +- Taking snapshots requires root priviledges. Take a snapshot with `snapsh -s SUBVOLUME` or `snapsh --snapshot SUBVOLUME`, where `SUBVOLUME` is the name of the source subvolume. Example with Fedora default btrfs layout with `root` and `home` subvolumes:
`snapsh -s root`
This will create a snapshot called `root_snapshot_YYYY.MM.DD-hh:mm:ss` to the `snapshots` subvolume (or the one you defined with `SNAPSHOTS_LOCATION`) -- 2.40.1 From 3a1a0c9800a265e1ac18e81f5111b0577659c43a Mon Sep 17 00:00:00 2001 From: Jarno Rankinen <50285623+0ranki@users.noreply.github.com> Date: Sat, 1 Aug 2020 20:43:54 +0300 Subject: [PATCH 3/6] Update README.md Instructions for adding description added --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a2adbb4..cf65405 100644 --- a/README.md +++ b/README.md @@ -10,4 +10,4 @@ Btrfs snapshot managing bash script - Script needs the toplevel subvolume (id=5) mounted somewhere. Default location is `/root/btrfs-toplevel`, but you can mount it anywhere you like and define it with `TOPLEVEL` variable. (A separate config file will be implemented later). - Will create a subvolume named snapshots by default to the toplevel. This can also be changed with `SNAPSHOTS_LOCATION`. - Display usage instructions with `snapsh -h` or `snapsh --help` -- Taking snapshots requires root priviledges. Take a snapshot with `snapsh -s SUBVOLUME` or `snapsh --snapshot SUBVOLUME`, where `SUBVOLUME` is the name of the source subvolume. Example with Fedora default btrfs layout with `root` and `home` subvolumes:
`snapsh -s root`
This will create a snapshot called `root_snapshot_YYYY.MM.DD-hh:mm:ss` to the `snapshots` subvolume (or the one you defined with `SNAPSHOTS_LOCATION`) +- Taking snapshots requires root priviledges. Take a snapshot with `snapsh -s SUBVOLUME` or `snapsh --snapshot SUBVOLUME`, where `SUBVOLUME` is the name of the source subvolume. You can add a description for the snapshot with the `-d | --description` option (must be used before the `-s` option)

Example with Fedora default btrfs layout with `root` and `home` subvolumes:
`snapsh -d "This is a snapshot" -s root`
This will create a snapshot called `root_snapshot_YYYY.MM.DD-hh:mm:ss` to the `snapshots` subvolume (or the one you defined with `SNAPSHOTS_LOCATION`), with a description "This is a snapshot" -- 2.40.1 From 8db86b51ec9245477d7c0d58223c2f62ca01563e Mon Sep 17 00:00:00 2001 From: Jarno Rankinen <50285623+0ranki@users.noreply.github.com> Date: Sun, 2 Aug 2020 20:32:41 +0300 Subject: [PATCH 4/6] Update README.md Added list option description --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index cf65405..0c00b14 100644 --- a/README.md +++ b/README.md @@ -11,3 +11,4 @@ Btrfs snapshot managing bash script - Will create a subvolume named snapshots by default to the toplevel. This can also be changed with `SNAPSHOTS_LOCATION`. - Display usage instructions with `snapsh -h` or `snapsh --help` - Taking snapshots requires root priviledges. Take a snapshot with `snapsh -s SUBVOLUME` or `snapsh --snapshot SUBVOLUME`, where `SUBVOLUME` is the name of the source subvolume. You can add a description for the snapshot with the `-d | --description` option (must be used before the `-s` option)

Example with Fedora default btrfs layout with `root` and `home` subvolumes:
`snapsh -d "This is a snapshot" -s root`
This will create a snapshot called `root_snapshot_YYYY.MM.DD-hh:mm:ss` to the `snapshots` subvolume (or the one you defined with `SNAPSHOTS_LOCATION`), with a description "This is a snapshot" +- Snapshots can be listed with `snapsh -l` or `snapsh --list` -- 2.40.1 From be893f3ee5242cfe7361af77a5023771a880f3ca Mon Sep 17 00:00:00 2001 From: Jarno Rankinen Date: Sun, 2 Aug 2020 20:42:59 +0300 Subject: [PATCH 5/6] Updated helptext with list option --- snapsh | 1 + 1 file changed, 1 insertion(+) diff --git a/snapsh b/snapsh index 0d5739e..e634f43 100755 --- a/snapsh +++ b/snapsh @@ -38,6 +38,7 @@ Options: snapshots listing. Must be used before -s, e.g. snapsh -d \"A snapshot\" -s root -s SUBVOL, --snapshot SUBVOL Take a snapshot of subvolume named SUBVOL. + -l, --list List snapshots Exit codes: 2 - Invalid options -- 2.40.1 From 974b2225dced6e5b7b494740f5ea743c4787fcbf Mon Sep 17 00:00:00 2001 From: Jarno Rankinen Date: Sun, 2 Aug 2020 21:38:27 +0300 Subject: [PATCH 6/6] Snapshot removal implemented Snapshot removing implemented (-r, --remove) Updated helptext Variable expansion fixes --- snapsh | 58 ++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 48 insertions(+), 10 deletions(-) diff --git a/snapsh b/snapsh index e634f43..e685614 100755 --- a/snapsh +++ b/snapsh @@ -25,6 +25,7 @@ BTRFS_EXECUTABLE=$(which btrfs) TIMESTAMP=$(date +%Y.%m.%d-%H:%M:%S) SUBVOLUME="root" DESCRIPTION="" +REMOVE_TARGET="" @@ -39,10 +40,8 @@ Options: snapsh -d \"A snapshot\" -s root -s SUBVOL, --snapshot SUBVOL Take a snapshot of subvolume named SUBVOL. -l, --list List snapshots - -Exit codes: - 2 - Invalid options - 3 - Target subvolume does not exist\n" + -r NUMBER, --remove NUMBER Remove snapshot NUMBER. See snapshot numbers with + snapsh -l\n" } @@ -61,7 +60,7 @@ snapshot() { ${BTRFS_EXECUTABLE} subvolume create ${SNAPSHOTS_LOCATION} unset ${REPLY} else - EXIT_CODE=3 + EXIT_CODE=1 fi else printf "Creating snapshot of subvolume ${SUBVOLUME} as ${SUBVOLUME}_snapshot_${TIMESTAMP}\n" @@ -95,7 +94,7 @@ snapshot() { list() { root_check - NUM=0 + NUM=1 printf "%6s %s %s %26s %s %s %6s %s %s\n" "Number" "|" "Time:" "|" "Source" "|" "Type" "|" "Description" for snapshot in ${SNAPSHOTS_LOCATION}/*/; do . ${snapshot}/.snapsh @@ -107,11 +106,43 @@ list() { +remove() { + root_check + SNAPSHOTS=(${SNAPSHOTS_LOCATION}/*/) + let INDEX=${REMOVE_TARGET}-1 + TARGET=${SNAPSHOTS[${INDEX}]} + . ${TARGET}/.snapsh + + if [[ "${INDEX}" -gt "${#SNAPSHOTS[@]}" ]]; then + printf "Snapshot number ${REMOVE_TARGET} does not exist.\n" + list + exit 1 + elif [[ "${REMOVE_TARGET}" -lt 1 ]]; then + printf "Number must be a positive integer.\n" + list + exit 1 + fi + + printf "Delete snapshot ${REMOVE_TARGET}: ${DATE}, subvolume ${SOURCE_SUBVOLUME}, ${DESCRIPTION} (y/n)? " + read -n 1 + if [[ "${REPLY}" == "y" ]]; then + printf "\n" + ${BTRFS_EXECUTABLE} property set ${TARGET} ro false + ${BTRFS_EXECUTABLE} subvolume delete ${TARGET} + exit 0 + else + printf "\nAborted by user.\n" + exit 1 + fi +} + + + # Check for root permissions root_check() { if [[ "$UID" -ne 0 ]]; then printf "This option needs root permission.\n" - exit 3 + exit 1 fi } @@ -120,18 +151,18 @@ root_check() { # If no options are given, display help if [[ "$#" -eq 0 ]]; then help - exit 2 + exit 0 fi # Options parsing: -OPTIONS=$(getopt -a -n snapsh -o hs:d:l --long help,snapshot:,description:,list -- "$@") +OPTIONS=$(getopt -a -n snapsh -o hs:d:lr: --long help,snapshot:,description:,list,remove: -- "$@") # Invalid options (getopt returns nonzero) if [[ "$?" -ne 0 ]]; then printf "Error Parsing options\n" help - exit 2 + exit 1 fi eval set -- "$OPTIONS" @@ -160,6 +191,13 @@ while true; do shift ;; + -r | --remove) + REMOVE_TARGET="$2" + remove + shift 2 + ;; + + esac done -- 2.40.1