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.

75 lines
2.4 KiB

#!/usr/bin/env python
import json
import tempfile
import subprocess
import datetime
from pathlib import Path
def get_last_boot():
with subprocess.Popen(
["journalctl", "--utc", "--list-boots"], stdout=subprocess.PIPE
) as proc:
for line in proc.stdout.read().decode().split("\n"):
info, end_time = line.split(chr(8212))
info = list(filter(bool, info.split(" ")))
bootnum = info[0]
if bootnum == "0":
start_date_string = " ".join(info[3:5])
return datetime.datetime.fromisoformat(start_date_string).replace(
tzinfo=datetime.timezone.utc
)
def get_snapshot_after_datetime(start: datetime.datetime):
with subprocess.Popen(
["snapper", "--utc", "--iso", "--jsonout", "list", "-t", "pre-post"],
stdout=subprocess.PIPE,
) as proc:
if proc.wait() != 0:
raise PermissionError("Snapper needs root privileges to read snapshots")
data = json.loads(proc.stdout.read().decode())
# ten years
td = 3153600000
ret = None
for snapshot in data["root"]:
snapshot_date = datetime.datetime.fromisoformat(snapshot["date"]).replace(
tzinfo=datetime.timezone.utc
)
d = (snapshot_date - start).total_seconds()
if 0 < d < td:
td = d
ret = snapshot
if ret is None:
print(f"No update since last boot on {start.astimezone()}")
exit(0)
return ret
def get_snapshot_path(snapshot):
return (
Path(snapshot["subvolume"])
/ ".snapshots"
/ Path(str(snapshot["number"]))
/ "snapshot"
)
def write_pacman_output(path):
out_file = tempfile.NamedTemporaryFile("wt")
proc = subprocess.Popen(["pacman", "-Q", "--dbpath", str(path)], stdout=out_file)
proc.wait()
return out_file
def diff_tempfiles(old, new):
subprocess.Popen(["diff", old.name, new.name, "--color=always", "--minimal"])
if __name__ == "__main__":
snapshot_data = get_snapshot_after_datetime(get_last_boot())
snapshot_root = get_snapshot_path(snapshot_data)
db_root = "var/lib/pacman"
old = write_pacman_output(snapshot_root / db_root)
new = write_pacman_output(Path(snapshot_data["subvolume"]) / db_root)
diff_tempfiles(old, new)