| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- import os
- import subprocess
- import toml
- from datetime import datetime, timedelta
- import shutil
- # Read configuration from a TOML file
- def read_config(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):
- 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)
- # Run the Btrfs snapshot command
- cmd = ["btrfs", "subvolume", "snapshot",
- os.path.join(config['snapshot']['btrfs_mount_point'], config['snapshot']['root_subvolume']),
- snapshot_path]
- result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- if result.returncode == 0:
- print(f"Created snapshot: {snapshot_name}")
- add_elilo_entry(config, snapshot_name)
- return snapshot_name
- else:
- raise Exception(f"Failed to create snapshot: {result.stderr.decode()}")
- # Add an entry for the snapshot in elilo.conf
- def add_elilo_entry(config, snapshot):
- entry = f"""
- image=vmlinuz
- label={snapshot}
- root={config['elilo']['root_partition']}
- append="rootflags=subvol={config['snapshot']['snapshot_dir']}/{snapshot} ro"
- initrd=initrd.gz
- """
- # Append to elilo.conf if the entry doesn't already exist
- elilo_conf = config['elilo']['elilo_conf']
- with open(elilo_conf, 'r+') as f:
- content = f.read()
- if snapshot not in content:
- print(f"Adding entry for snapshot: {snapshot}")
- f.write(entry)
- # Remove an entry for a deleted snapshot from elilo.conf
- def remove_elilo_entry(config, snapshot):
- elilo_conf = config['elilo']['elilo_conf']
- with open(elilo_conf, 'r') as f:
- lines = f.readlines()
- with open(elilo_conf, 'w') as f:
- for line in lines:
- if snapshot not in line:
- f.write(line)
- print(f"Removed entry for snapshot: {snapshot}")
- # List all current snapshots
- def list_snapshots(config):
- snapshots = []
- for entry in os.listdir(config['snapshot']['snapshot_dir']):
- entry_path = os.path.join(config['snapshot']['snapshot_dir'], entry)
- if os.path.isdir(entry_path) and entry.startswith(config['snapshot']['snapshot_prefix']):
- snapshots.append(entry)
- return snapshots
- # Remove snapshots older than the retention period
- def remove_old_snapshots(config):
- retention_days = config['snapshot']['retention_days']
- now = datetime.now()
- for snapshot in list_snapshots(config):
- snapshot_path = os.path.join(config['snapshot']['snapshot_dir'], snapshot)
- created_time = datetime.fromtimestamp(os.path.getctime(snapshot_path))
- if (now - created_time).days > retention_days:
- # Remove snapshot
- cmd = ["btrfs", "subvolume", "delete", snapshot_path]
- subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- 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"])
- # 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])
- def main():
- # Load configuration from config.toml
- config = read_config("config.toml")
- # Step 1: Get list of current snapshots and add them to elilo.conf if needed
- snapshots = list_snapshots(config)
- for snapshot in snapshots:
- add_elilo_entry(config, snapshot)
- # Step 2: Remove snapshots older than retention period
- remove_old_snapshots(config)
- if __name__ == "__main__":
- main()
|