# Offline model of PBS's prune selection (pbs-datastore prune.rs compute_prune_info / mark_selections), # run over ep0's snapshot list. Never touches ep0. ep0's clock is UTC (timedatectl), and PBS keys # weekly buckets by local time "%G/%V" (ISO year/week). import sys, datetime snaps = {} for line in open(sys.argv[1]): line=line.strip() if line.startswith('ns/') and '/ct/' in line: ns = line.split('/')[1]; t = line.rsplit('/',1)[1] snaps.setdefault(ns, []).append(t) def sel_last(t): return t def sel_week(t): d = datetime.datetime.strptime(t, '%Y-%m-%dT%H:%M:%SZ'); y,w,_ = d.isocalendar(); return f"{y}/{w:02d}" def compute(lst, opts): lst = sorted(lst, reverse=True); mark = {} for keep, sel in opts: already = {sel(t) for t in lst if mark.get(t)=='keep'}; inc=set() for t in lst: if t in mark: continue s = sel(t) if s in already: continue if s not in inc: if len(inc) >= keep: break inc.add(s); mark[t]='keep' else: mark[t]='remove' return {t: mark.get(t,'remove') for t in lst} jobs = {'demo-hp':'prune-demo-hp','demo-felhom':'prune-demo-felhom'} print("box | job | snapshots today | keep-last 2 keeps / removes | keep-weekly 2 keeps / removes") for ns in sorted(snaps): a = compute(snaps[ns], [(2, sel_last)]); b = compute(snaps[ns], [(2, sel_week)]) f = lambda m,k: ', '.join(f"{t[:10]} (w{sel_week(t)[5:]})" for t,v in m.items() if v==k) or 'none' print(f"{ns} | {jobs.get(ns,'NO JOB')} | {len(snaps[ns])} | {f(a,'keep')} / {f(a,'remove')} | {f(b,'keep')} / {f(b,'remove')}")