You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

72 lines
2.2 KiB

  1. #!/usr/bin/env python
  2. import json
  3. import tempfile
  4. import subprocess
  5. import datetime
  6. from pathlib import Path
  7. def get_last_boot():
  8. with subprocess.Popen(
  9. ["journalctl", "--list-boots"], stdout=subprocess.PIPE
  10. ) as proc:
  11. for line in proc.stdout.read().decode().split("\n"):
  12. info, end_time = line.split(chr(8212))
  13. info = list(filter(bool, info.split(" ")))
  14. bootnum = info[0]
  15. if bootnum == "0":
  16. start_date_string = " ".join(info[3:5])
  17. return datetime.datetime.fromisoformat(start_date_string).replace(
  18. tzinfo=datetime.timezone.utc
  19. )
  20. def get_snapshot__after_datetime(start: datetime.datetime):
  21. with subprocess.Popen(
  22. ["snapper", "--utc", "--iso", "--jsonout", "list", "-t", "pre-post"],
  23. stdout=subprocess.PIPE,
  24. ) as proc:
  25. if proc.wait() != 0:
  26. raise PermissionError("Snapper needs root privileges to read snapshots")
  27. data = json.loads(proc.stdout.read().decode())
  28. # ten years
  29. td = 3153600000
  30. ret = None
  31. for snapshot in data["root"]:
  32. snapshot_date = datetime.datetime.fromisoformat(snapshot["date"]).replace(
  33. tzinfo=datetime.timezone.utc
  34. )
  35. d = (snapshot_date - start).total_seconds()
  36. if 0 < d < td:
  37. td = d
  38. ret = snapshot
  39. return ret
  40. def get_snapshot_path(snapshot):
  41. return (
  42. Path(snapshot["subvolume"])
  43. / ".snapshots"
  44. / Path(str(snapshot["number"]))
  45. / "snapshot"
  46. )
  47. def write_pacman_output(path):
  48. out_file = tempfile.NamedTemporaryFile("wt")
  49. proc = subprocess.Popen(["pacman", "-Q", "--dbpath", str(path)], stdout=out_file)
  50. proc.wait()
  51. return out_file
  52. def diff_tempfiles(old, new):
  53. subprocess.Popen(["diff", old.name, new.name, "--color=always", "--minimal"])
  54. if __name__ == "__main__":
  55. snapshot_data = get_snapshot__after_datetime(get_last_boot())
  56. snapshot_root = get_snapshot_path(snapshot_data)
  57. db_root = "var/lib/pacman"
  58. old = write_pacman_output(snapshot_root / db_root)
  59. new = write_pacman_output(Path(snapshot_data["subvolume"]) / db_root)
  60. diff_tempfiles(old, new)