ops(web): bound immutable release history

This commit is contained in:
lingniu
2026-07-16 04:18:15 +08:00
parent 8e8f3f9f5c
commit 326d03cd6d
10 changed files with 392 additions and 3 deletions

View File

@@ -0,0 +1,53 @@
#!/usr/bin/env python3
from __future__ import print_function
import argparse
import os
import shutil
from pathlib import Path
def main():
parser = argparse.ArgumentParser(description='Keep a bounded number of immutable platform releases.')
parser.add_argument('root')
parser.add_argument('limit', type=int)
parser.add_argument('protected', nargs='*')
args = parser.parse_args()
root = Path(args.root).resolve()
releases = (root / 'releases').resolve()
if root == Path('/') or releases.parent != root or not releases.is_dir():
raise SystemExit('unsafe or missing release root: {}'.format(releases))
if args.limit < 2:
raise SystemExit('release history limit must be at least 2')
protected = set()
for value in args.protected:
path = Path(value).resolve()
if path.parent != releases or not path.is_dir():
raise SystemExit('protected release is outside the release root: {}'.format(path))
protected.add(path)
candidates = [path.resolve() for path in releases.iterdir() if path.is_dir() and not path.is_symlink()]
candidates.sort(key=lambda path: path.stat().st_mtime, reverse=True)
keep = set(protected)
for path in candidates:
if len(keep) >= args.limit:
break
keep.add(path)
removed = 0
for path in candidates:
if path in keep:
continue
if path.parent != releases:
raise SystemExit('refusing to remove a nested or escaped path: {}'.format(path))
shutil.rmtree(str(path))
removed += 1
print('release_prune=ok before={} kept={} removed={}'.format(len(candidates), len(keep), removed))
if __name__ == '__main__':
main()