snap-slack.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. import os
  2. import subprocess
  3. import toml
  4. from datetime import datetime, timedelta
  5. import shutil
  6. # Read configuration from a TOML file
  7. def read_config(file_path):
  8. with open(file_path, 'r') as f:
  9. config = toml.load(f)
  10. return config
  11. # Create a new snapshot with the current date and time
  12. def create_snapshot(config):
  13. date_str = datetime.now().strftime("%Y%m%d-%H%M%S")
  14. snapshot_name = f"{config['snapshot']['snapshot_prefix']}{date_str}"
  15. snapshot_path = os.path.join(config['snapshot']['snapshot_dir'], snapshot_name)
  16. # Run the Btrfs snapshot command
  17. cmd = ["btrfs", "subvolume", "snapshot",
  18. os.path.join(config['snapshot']['btrfs_mount_point'], config['snapshot']['root_subvolume']),
  19. snapshot_path]
  20. result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  21. if result.returncode == 0:
  22. print(f"Created snapshot: {snapshot_name}")
  23. add_elilo_entry(config, snapshot_name)
  24. return snapshot_name
  25. else:
  26. raise Exception(f"Failed to create snapshot: {result.stderr.decode()}")
  27. # Add an entry for the snapshot in elilo.conf
  28. def add_elilo_entry(config, snapshot):
  29. entry = f"""
  30. image=vmlinuz
  31. label={snapshot}
  32. root={config['elilo']['root_partition']}
  33. append="rootflags=subvol={config['snapshot']['snapshot_dir']}/{snapshot} ro"
  34. initrd=initrd.gz
  35. """
  36. # Append to elilo.conf if the entry doesn't already exist
  37. elilo_conf = config['elilo']['elilo_conf']
  38. with open(elilo_conf, 'r+') as f:
  39. content = f.read()
  40. if snapshot not in content:
  41. print(f"Adding entry for snapshot: {snapshot}")
  42. f.write(entry)
  43. # Remove an entry for a deleted snapshot from elilo.conf
  44. def remove_elilo_entry(config, snapshot):
  45. elilo_conf = config['elilo']['elilo_conf']
  46. with open(elilo_conf, 'r') as f:
  47. lines = f.readlines()
  48. with open(elilo_conf, 'w') as f:
  49. for line in lines:
  50. if snapshot not in line:
  51. f.write(line)
  52. print(f"Removed entry for snapshot: {snapshot}")
  53. # List all current snapshots
  54. def list_snapshots(config):
  55. snapshots = []
  56. for entry in os.listdir(config['snapshot']['snapshot_dir']):
  57. entry_path = os.path.join(config['snapshot']['snapshot_dir'], entry)
  58. if os.path.isdir(entry_path) and entry.startswith(config['snapshot']['snapshot_prefix']):
  59. snapshots.append(entry)
  60. return snapshots
  61. # Remove snapshots older than the retention period
  62. def remove_old_snapshots(config):
  63. retention_days = config['snapshot']['retention_days']
  64. now = datetime.now()
  65. for snapshot in list_snapshots(config):
  66. snapshot_path = os.path.join(config['snapshot']['snapshot_dir'], snapshot)
  67. created_time = datetime.fromtimestamp(os.path.getctime(snapshot_path))
  68. if (now - created_time).days > retention_days:
  69. # Remove snapshot
  70. cmd = ["btrfs", "subvolume", "delete", snapshot_path]
  71. subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  72. remove_elilo_entry(config, snapshot)
  73. print(f"Removed snapshot: {snapshot}")
  74. # Function to wrap slackpkg upgrade
  75. def slackpkg_upgrade(config):
  76. print("Preparing to run slackpkg upgrade...")
  77. create_snapshot(config)
  78. print("Running slackpkg upgrade...")
  79. subprocess.run(["/usr/sbin/slackpkg", "upgrade-all"])
  80. # Function to wrap sbopkg -i
  81. def sbopkg_install(config, package):
  82. print(f"Preparing to install package using sbopkg: {package}")
  83. create_snapshot(config)
  84. print(f"Running sbopkg -i {package}...")
  85. subprocess.run(["/usr/sbin/sbopkg", "-i", package])
  86. def main():
  87. # Load configuration from config.toml
  88. config = read_config("config.toml")
  89. # Step 1: Get list of current snapshots and add them to elilo.conf if needed
  90. snapshots = list_snapshots(config)
  91. for snapshot in snapshots:
  92. add_elilo_entry(config, snapshot)
  93. # Step 2: Remove snapshots older than retention period
  94. remove_old_snapshots(config)
  95. if __name__ == "__main__":
  96. main()