From 76cf7b4e1cd166aad769f0d344d39f37e584793c Mon Sep 17 00:00:00 2001 From: Arvin Schnell Date: Fri, 16 May 2025 10:09:30 +0200 Subject: [PATCH] - added Python program for rollback of any subvolume --- scripts/rollback-home | 104 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100755 scripts/rollback-home diff --git a/scripts/rollback-home b/scripts/rollback-home new file mode 100755 index 00000000..9ffe0a7c --- /dev/null +++ b/scripts/rollback-home @@ -0,0 +1,104 @@ +#!/usr/bin/python3 + +# Read http://snapper.io/2025/05/16/rollback-any.html and understand +# the setup before using this program. + + +import subprocess +import re +import datetime +import argparse + + +subvolume = "/home" + + +def parse_options(): + + parser = argparse.ArgumentParser(description = "rollabck home") + parser.add_argument("number", type = int, help = "rollback to number") + + args = parser.parse_args() + + return args.number + + +def find_next_number(): + + next_number = 1 + + cmd = subprocess.run([ "btrfs", "subvolume", "list", subvolume ], stdout = subprocess.PIPE) + + tmp = cmd.stdout.rstrip().decode("utf-8") + + pattern = f"^@\\{subvolume}\\/\\.snapshots\\/(\\d+)\\/snapshot$" + + for tmp1 in tmp.split('\n'): + tmp2 = tmp1.split(' ') + tmp3 = tmp2[8] + + match = re.search(pattern, tmp3) + + if match: + tmp4 = int(match.group(1)) + 1 + if tmp4 > next_number: + next_number = tmp4 + + print("next number is", next_number) + + return next_number + + +def write_info(number): + + template = """ + + single + {number} + {date} + rollback backup + +""" + + data = { + "number": number, + "date": datetime.datetime.now(datetime.timezone.utc).strftime("%Y-%m-%d %H:%M:%S") + } + + filename = subvolume + "/.snapshots/" + str(number) + "/info.xml" + + with open(filename, "w") as f: + f.write(template.format(**data)) + + +def step_rename(): + + next_number = find_next_number() + + subprocess.run([ "mkdir", subvolume + "/.snapshots/" + str(next_number) ]) + + subprocess.run([ "mv", subvolume + "/.snapshots/0/snapshot", + subvolume + "/.snapshots/" + str(next_number) + "/snapshot" ]) + + subprocess.run([ "btrfs", "property", "set", + subvolume + "/.snapshots/" + str(next_number) + "/snapshot", "ro", "true" ]) + + write_info(next_number) + + +def step_new_zero(number): + + subprocess.run([ "btrfs", "subvolume", "snapshot", + subvolume + "/.snapshots/" + str(number) + "/snapshot", + subvolume + "/.snapshots/0/snapshot" ]) + + +try: + number = parse_options() +except SystemExit: + pass + +print("rollback to", number) + +step_rename() +step_new_zero(number) -- 2.47.3