clean up deployment script
Some checks failed
Deploy Containers / Prepare (push) Has been cancelled

This commit is contained in:
2025-11-21 02:58:25 -05:00
parent 3e07981021
commit 3d3c4c109d

View File

@@ -5,7 +5,8 @@ import subprocess
def git_diff(): def git_diff():
args = sys.argv args = sys.argv
res = subprocess.run(f"git diff --name-only {args[1]} {args[2]}", capture_output=True, shell=True, text=True) res = subprocess.run(f"git diff --name-only {args[1]} {args[2]}", capture_output=True, shell=True, text=True)
return [x for x in res.stdout.strip().split("\n") if "tasks/" in x or "roles/" in x or "host_vars" in x] # return [x for x in res.stdout.strip().split("\n") if "tasks/" in x or "roles/" in x]
return ["roles/docker/tasks/fuck.yml", "roles/fuck/test/test.yml", "roles/fivem/tasks/main.yml", "tasks/fuck.yml", "tasks/api.yml", "tasks/cup.yml"]
def construct_command(tag = None, host = None): def construct_command(tag = None, host = None):
command = f"ANSIBLE_CONFIG=ansible.cfg /usr/bin/ansible-playbook main.yml --vault-password-file ~/.vault_pass.txt" command = f"ANSIBLE_CONFIG=ansible.cfg /usr/bin/ansible-playbook main.yml --vault-password-file ~/.vault_pass.txt"
@@ -24,81 +25,80 @@ def deploy(tag = None, host = None):
print(f"Deploying {tag}...\n") print(f"Deploying {tag}...\n")
else: else:
print(f"Deploying {host}...\n") print(f"Deploying {host}...\n")
res = subprocess.run(command, shell=True) res = subprocess.run(command, shell=True, stdout=subprocess.DEVNULL)
return res.returncode == 0 return res.returncode == 0
def main(): def main():
tasks_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../tasks") dir_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), '../')
diff = git_diff() diff = git_diff()
host_vars_changed_for = []
# containers that need special treatment
removed_containers = []
vpn_containers = [ vpn_containers = [
"tasks/qbittorrent.yml", "tasks/qbittorrent.yml",
"tasks/jackett.yml" "tasks/jackett.yml"
] ]
managed_roles = [
"roles/fivem",
"roles/gitea-runner",
"roles/traefik"
]
# because these containers rely on gluetun for network, they need to be recreated when gluetun is recreated # special actions
if "tasks/gluetun.yml" in diff: if "tasks/gluetun.yml" in diff:
print("Gluetun detected in diff, queuing dependent containers for recreation") print("[MAIN] Detected Gluetun in diff, recreating dependent containers..")
for container in vpn_containers: for container in vpn_containers:
if container not in diff: if container not in diff:
diff.append(container) diff.append(container)
# when variables update for a host & there are no other modified containers, recreate containers on host # clean up the diff
# for file in diff: new_diff = []
# if "host_vars" in file: for file in diff:
# hostname = file.split("/")[1].split(".")[0] task_name = f"{file.split("/")[0]}/{file.split("/")[1]}"
# print(f"Secret file for '{hostname}' changed, will recreate containers on host after deployment")
# host_vars_changed_for.append(hostname) # i'm not proud of this either
if not os.path.exists(os.path.join(dir_path, file)):
if "roles" in file and not os.path.exists(os.path.join(dir_path, task_name)) and task_name in managed_roles:
print(f"[MAIN] '{task_name}' role removed, marking for cleanup..")
removed_containers.append(task_name)
elif "tasks" in task_name:
print(f"[MAIN] '{task_name}' non-existent, marking for cleanup..")
removed_containers.append(task_name)
elif "roles" in file:
if task_name in managed_roles:
if task_name not in new_diff:
new_diff.append(task_name)
elif "tasks" in file:
new_diff.append(file.split(".")[0])
else:
new_diff.append(file)
deployed = [] deployed = []
failed = [] failed = []
removed = [] for task in new_diff:
for file in diff: deployment = deploy(tag=task)
task_name = ""
# separating these for now because roles will typically
# have a bunch of other things tied to them
if "roles/" not in file and "host_vars/" not in file:
task_name = file.split("/")[1].split(".")[0]
task_file_path = os.path.join(tasks_path, file.split("/")[1])
if not os.path.exists(task_file_path): if not deployment:
print(f"{task_name} doesn't exist, running cleanup") failed.append(task)
res = subprocess.run(f"/usr/bin/docker container stop {task_name}", shell=True)
if res.returncode == 0:
subprocess.run(f"/usr/bin/docker container rm {task_name}", shell=True)
subprocess.run("/usr/bin/docker image prune -f", shell=True)
subprocess.run("/usr/bin/docker container prune -f", shell=True)
print(f"Cleaned up container {task_name}")
removed.append(task_name)
if "host_vars" not in file and task_name and task_name not in removed:
# deploy the task, regardless of its status
if "roles/" not in file:
if task_name not in deployed:
task = deploy(tag=task_name)
else: else:
task_name = file.split("/")[1] deployed.append(task)
if task_name not in deployed: for task in removed_containers:
task = deploy(tag=task_name) print(f"[MAIN] Attempting to remove containers related to '{task}'...")
task_name = task.split("/")[1].split(".")[0]
if not task: containers = subprocess.Popen(f"docker container list | grep {task_name}_", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
failed.append(task_name) for line in containers.stdout:
else: docker_container_id = line.rstrip().decode('utf8').split(" ")[0]
deployed.append(task_name) if docker_container_id and docker_container_id.strip() != "":
print(f"[MAIN] Found Docker container {docker_container_id} related to {task}, removing..")
if len(host_vars_changed_for) > 0:
for host in host_vars_changed_for:
print(f"Redeploying containers on {host} due to host vars update")
task = deploy(host=host)
if task:
deployed.append(host)
else:
failed.append(host)
# clean up containers & dangling images
subprocess.run(f"/usr/bin/docker container stop {docker_container_id}", shell=True, stdout=subprocess.DEVNULL)
subprocess.run(f"/usr/bin/docker container rm {docker_container_id}", shell=True, stdout=subprocess.DEVNULL)
subprocess.run("/usr/bin/docker image prune -f", shell=True, stdout=subprocess.DEVNULL)
subprocess.run("/usr/bin/docker container prune -f", shell=True, stdout=subprocess.DEVNULL)
if len(failed) <= 0 and len(deployed) > 0: if len(failed) <= 0 and len(deployed) > 0:
print("\n---------------------") print("\n---------------------")
@@ -114,7 +114,7 @@ def main():
print("---------------------\n") print("---------------------\n")
sys.exit(1) sys.exit(1)
elif len(deployed) <= 0: elif len(deployed) <= 0:
print("Successfully executed, no tasks required execution") print("[MAIN] Successfully executed, no tasks required execution")
sys.exit(0) sys.exit(0)
if __name__ == "__main__": if __name__ == "__main__":