Bernardo Magri преди 1 година
родител
ревизия
b3726dc3ec
променени са 1 файла, в които са добавени 70 реда и са изтрити 20 реда
  1. 70 20
      snap-slack.py

+ 70 - 20
snap-slack.py

@@ -1,17 +1,25 @@
+#!/usr/bin/env python3
+
 import os
 import subprocess
 import toml
-from datetime import datetime, timedelta
-import shutil
+import argparse
+from datetime import datetime
+
+# Path to the configuration file
+CONFIG_PATH = "/etc/snap-slack/config.toml"
 
 # Read configuration from a TOML file
-def read_config(file_path):
+def read_config(file_path=CONFIG_PATH):
+    if not os.path.exists(file_path):
+        raise FileNotFoundError(f"Configuration file not found: {file_path}")
+    
     with open(file_path, 'r') as f:
         config = toml.load(f)
     return config
 
 # Create a new snapshot with the current date and time
-def create_snapshot(config):
+def create(config):
     date_str = datetime.now().strftime("%Y%m%d-%H%M%S")
     snapshot_name = f"{config['snapshot']['snapshot_prefix']}{date_str}"
     snapshot_path = os.path.join(config['snapshot']['snapshot_dir'], snapshot_name)
@@ -31,11 +39,16 @@ def create_snapshot(config):
 
 # Add an entry for the snapshot in elilo.conf
 def add_elilo_entry(config, snapshot):
+    # Get the extra boot options from the config, if any
+    extra_boot_options = config['elilo'].get('extra_boot_options', '')
+
+    # Construct the boot entry with optional extra boot options
     entry = f"""
 image=vmlinuz
         label={snapshot}
         root={config['elilo']['root_partition']}
-        append="rootflags=subvol={config['snapshot']['snapshot_dir']}/{snapshot} ro"
+        append="rootflags=subvol={config['snapshot']['snapshot_dir']}/{snapshot} ro {extra_boot_options}"
+        read-only
         initrd=initrd.gz
 """
 
@@ -84,24 +97,33 @@ def remove_old_snapshots(config):
             remove_elilo_entry(config, snapshot)
             print(f"Removed snapshot: {snapshot}")
 
-# Function to wrap slackpkg upgrade
-def slackpkg_upgrade(config):
-    print("Preparing to run slackpkg upgrade...")
-    create_snapshot(config)
-    print("Running slackpkg upgrade...")
-    subprocess.run(["/usr/sbin/slackpkg", "upgrade-all"])
+# Adopt a snapshot as the new root subvolume
+def adopt(config, snapshot):
+    current_root_path = os.path.join(config['snapshot']['btrfs_mount_point'], config['snapshot']['root_subvolume'])
+    snapshot_path = os.path.join(config['snapshot']['snapshot_dir'], snapshot)
 
-# Function to wrap sbopkg -i
-def sbopkg_install(config, package):
-    print(f"Preparing to install package using sbopkg: {package}")
-    create_snapshot(config)
-    print(f"Running sbopkg -i {package}...")
-    subprocess.run(["/usr/sbin/sbopkg", "-i", package])
+    if not os.path.exists(snapshot_path):
+        raise Exception(f"Snapshot '{snapshot}' not found.")
 
-def main():
-    # Load configuration from config.toml
-    config = read_config("config.toml")
+    # Step 1: Rename the current root subvolume to something else (e.g., @old_root)
+    old_root_path = current_root_path + "_old"
+    print(f"Renaming current root subvolume to {old_root_path}")
+    cmd_rename_root = ["btrfs", "subvolume", "snapshot", current_root_path, old_root_path]
+    subprocess.run(cmd_rename_root, check=True)
+
+    # Step 2: Rename the selected snapshot to become the new root subvolume
+    print(f"Renaming snapshot '{snapshot}' to become the new root subvolume.")
+    cmd_set_new_root = ["btrfs", "subvolume", "snapshot", snapshot_path, current_root_path]
+    subprocess.run(cmd_set_new_root, check=True)
+
+    # Step 3: Update the elilo bootloader configuration to point to the new root subvolume
+    print(f"Updating elilo.conf to use the new root subvolume '{snapshot}'.")
+    add_elilo_entry(config, snapshot)
 
+    print(f"Snapshot '{snapshot}' has been adopted as the new root subvolume.")
+
+# Main logic for managing snapshots
+def update(config):
     # Step 1: Get list of current snapshots and add them to elilo.conf if needed
     snapshots = list_snapshots(config)
     for snapshot in snapshots:
@@ -110,5 +132,33 @@ def main():
     # Step 2: Remove snapshots older than retention period
     remove_old_snapshots(config)
 
+# Parse command-line arguments
+def parse_arguments():
+    parser = argparse.ArgumentParser(description='Manage BTRFS snapshots and elilo bootloader entries.')
+    parser.add_argument('action', choices=['create', 'update', 'adopt'],
+                        help='Specify the action to perform: create, manage, or adopt.')
+    parser.add_argument('--snapshot', help='The snapshot to adopt as the new root subvolume.')
+    return parser.parse_args()
+
+def main():
+    # Load configuration from /etc/manage_snapshots/config.toml
+    config = read_config()
+
+    # Parse command-line arguments
+    args = parse_arguments()
+
+    # Execute based on action
+    if args.action == 'create':
+        create(config)
+    elif args.action == 'update':
+        update(config)
+    elif args.action == 'adopt':
+        if not args.snapshot:
+            print("Error: You must specify the snapshot to adopt using --snapshot.")
+        else:
+            adopt(config, args.snapshot)
+    else:
+        print("Invalid action")
+
 if __name__ == "__main__":
     main()