zulip/scripts/purge-old-deployments

104 lines
3.3 KiB
Python
Executable File

#!/usr/bin/env python3
import argparse
import os
import subprocess
import sys
from typing import Set
ZULIP_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(ZULIP_PATH)
from scripts.lib import clean_unused_caches
from scripts.lib.zulip_tools import (
DEPLOYMENTS_DIR,
get_recent_deployments,
maybe_perform_purging,
su_to_zulip,
)
LOCAL_GIT_CACHE_DIR = "/srv/zulip.git"
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(
description="This script can be used for cleaning old unused deployments.",
epilog="Orphaned/unused caches older than threshold days will be automatically "
"examined and removed.",
)
parser.add_argument(
"--threshold",
dest="threshold_days",
type=int,
default=14,
metavar="<days>",
help="Deployments older than threshold days will be deleted. (defaults to 14)",
)
parser.add_argument(
"--dry-run",
action="store_true",
help="If specified then script will only print the deployments and "
"caches that it will delete/keep back. It will not delete anything.",
)
parser.add_argument(
"--verbose",
action="store_true",
help="If specified then script will print a detailed report of what is going on.",
)
parser.add_argument(
"--no-print-headings",
dest="no_headings",
action="store_true",
help="If specified then script will not print headings for "
"what will be deleted/kept back.",
)
args = parser.parse_args()
args.verbose |= args.dry_run # Always print a detailed report in case of dry run.
return args
def get_deployments_to_be_purged(recent_deployments: Set[str]) -> Set[str]:
all_deployments = {
os.path.join(DEPLOYMENTS_DIR, deployment) for deployment in os.listdir(DEPLOYMENTS_DIR)
}
deployments_to_purge = set()
for deployment in all_deployments:
# Deployments whose name is not in the format of a timestamp are
# always included in the recent_deployments and are not deleted.
if not os.path.isdir(deployment):
# Skip things like uwsgi sockets.
continue
if not os.path.exists(os.path.join(deployment, "zerver")):
# Skip things like "lock" that aren't actually a deployment directory
continue
if deployment not in recent_deployments:
deployments_to_purge.add(deployment)
return deployments_to_purge
def main() -> None:
args = parse_args()
deployments_to_keep = get_recent_deployments(args.threshold_days)
deployments_to_purge = get_deployments_to_be_purged(deployments_to_keep)
maybe_perform_purging(
deployments_to_purge, deployments_to_keep, "deployment", args.dry_run, args.verbose, True
)
if not args.dry_run:
if os.path.exists(LOCAL_GIT_CACHE_DIR):
subprocess.check_call(
["git", "worktree", "prune"], cwd=LOCAL_GIT_CACHE_DIR, preexec_fn=su_to_zulip
)
if not args.no_headings:
print("Deployments cleaned successfully...")
print("Cleaning orphaned/unused caches...")
# Call 'clean_unused_caches.py' script to clean any orphaned/unused caches.
clean_unused_caches.main(args)
print("Done!")
if __name__ == "__main__":
main()