Files
lingniu-vehicle-ingest/vehicle-data-platform/deploy/prune-release-history.py
2026-07-16 04:18:15 +08:00

54 lines
1.7 KiB
Python
Executable File

#!/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()