From aac9704e8b01d6d6b2e28b75db629d51919b013e Mon Sep 17 00:00:00 2001 From: Kevin Veen-Birkenbach Date: Sat, 6 Sep 2025 10:32:33 +0200 Subject: [PATCH] Refactor: remove legacy update-docker role and references Details: - Removed update-docker role (README, meta, vars, tasks, script) - Cleaned references from group_vars, update-compose, and docs - Adjusted web-app-matrix role (removed @todo pointing to update-docker) - Updated administrator guide (update-docker no longer mentioned) Ref: https://chatgpt.com/share/68bbeff1-27a0-800f-bef3-03ab597595fd --- docs/guides/administrator/README.md | 2 +- group_vars/all/07_services.yml | 4 +- roles/update-compose/tasks/01_core.yml | 7 - roles/update-docker/README.md | 27 --- roles/update-docker/meta/main.yml | 27 --- roles/update-docker/tasks/01_core.yml | 20 -- roles/update-docker/tasks/main.yml | 4 - roles/update-docker/templates/script.py.j2 | 207 --------------------- roles/update-docker/vars/main.yml | 2 - roles/web-app-matrix/tasks/01_docker.yml | 1 - 10 files changed, 2 insertions(+), 299 deletions(-) delete mode 100644 roles/update-docker/README.md delete mode 100644 roles/update-docker/meta/main.yml delete mode 100644 roles/update-docker/tasks/01_core.yml delete mode 100644 roles/update-docker/tasks/main.yml delete mode 100644 roles/update-docker/templates/script.py.j2 delete mode 100644 roles/update-docker/vars/main.yml diff --git a/docs/guides/administrator/README.md b/docs/guides/administrator/README.md index 2e80e5ad..042a5439 100644 --- a/docs/guides/administrator/README.md +++ b/docs/guides/administrator/README.md @@ -15,7 +15,7 @@ Follow these guides to install and configure Infinito.Nexus: - **Networking & VPN** - Configure `WireGuard`, `OpenVPN`, and `Nginx Reverse Proxy`. ## Managing & Updating Infinito.Nexus 🔄 -- Regularly update services using `update-docker`, `update-pacman`, or `update-apt`. +- Regularly update services using `update-pacman`, or `update-apt`. - Monitor system health with `sys-ctl-hlth-btrfs`, `sys-ctl-hlth-webserver`, and `sys-ctl-hlth-docker-container`. - Automate system maintenance with `sys-lock`, `sys-ctl-cln-bkps`, and `sys-ctl-rpr-docker-hard`. diff --git a/group_vars/all/07_services.yml b/group_vars/all/07_services.yml index deff8163..27dada9a 100644 --- a/group_vars/all/07_services.yml +++ b/group_vars/all/07_services.yml @@ -12,7 +12,6 @@ SYS_SERVICE_BACKUP_RMT_2_LOC: "{{ 'svc-bkp-rmt-2-loc' | get_se SYS_SERVICE_BACKUP_DOCKER_2_LOC: "{{ 'sys-ctl-bkp-docker-2-loc' | get_service_name(SOFTWARE_NAME) }}" SYS_SERVICE_REPAIR_DOCKER_SOFT: "{{ 'sys-ctl-rpr-docker-soft' | get_service_name(SOFTWARE_NAME) }}" SYS_SERVICE_REPAIR_DOCKER_HARD: "{{ 'sys-ctl-rpr-docker-hard' | get_service_name(SOFTWARE_NAME) }}" -SYS_SERVICE_UPDATE_DOCKER: "{{ 'update-docker' | get_service_name(SOFTWARE_NAME) }}" ## On Failure SYS_SERVICE_ON_FAILURE_COMPOSE: "{{ ('sys-ctl-alm-compose@') | get_service_name(SOFTWARE_NAME, False) }}%n.service" @@ -46,8 +45,7 @@ SYS_SERVICE_GROUP_MANIPULATION: > SYS_SERVICE_GROUP_CLEANUP + SYS_SERVICE_GROUP_REPAIR + SYS_SERVICE_GROUP_OPTIMIZATION + - SYS_SERVICE_GROUP_MAINTANANCE + - [ SYS_SERVICE_UPDATE_DOCKER ] + SYS_SERVICE_GROUP_MAINTANANCE ) | sort }} diff --git a/roles/update-compose/tasks/01_core.yml b/roles/update-compose/tasks/01_core.yml index 31ec0993..7d3ad150 100644 --- a/roles/update-compose/tasks/01_core.yml +++ b/roles/update-compose/tasks/01_core.yml @@ -14,13 +14,6 @@ name: update-apt when: ansible_distribution == "Debian" -- name: "Update Docker Images" - include_role: - name: update-docker - when: - - docker_compose_directory_stat.stat.exists - - run_once_update_docker is not defined - - name: "Check if yay is installed" command: which yay register: yay_installed diff --git a/roles/update-docker/README.md b/roles/update-docker/README.md deleted file mode 100644 index a1285cea..00000000 --- a/roles/update-docker/README.md +++ /dev/null @@ -1,27 +0,0 @@ -# Update Docker - -## Description - -This role updates Docker Compose instances by checking for changes in Docker image digests and applying updates if necessary. It utilizes a Python script to handle git pulls and Docker image pulls, and rebuilds containers when changes are detected. - -## Overview - -The role performs the following: -- Deploys a Python script to check for Docker image updates. -- Configures a systemd service to run the update script. -- Restarts the Docker update service upon configuration changes. -- Supports additional procedures for specific Docker applications (e.g., Discourse, Mastodon, Nextcloud). - -## Purpose - -The role is designed to ensure that Docker images remain current by automatically detecting changes and rebuilding containers as needed. This helps maintain a secure and efficient container environment. - -## Features - -- **Docker Image Monitoring:** Checks for changes in image digests. -- **Automated Updates:** Pulls new images and rebuilds containers when necessary. -- **Service Management:** Configures and restarts a systemd service to handle updates. -- **Application-Specific Procedures:** Includes hooks for updating specific Docker applications. - -## Credits 📝 -It was created with the help of ChatGPT. The conversation is available [here](https://chat.openai.com/share/165418b8-25fa-433b-baca-caded941e22a) \ No newline at end of file diff --git a/roles/update-docker/meta/main.yml b/roles/update-docker/meta/main.yml deleted file mode 100644 index c5b330a4..00000000 --- a/roles/update-docker/meta/main.yml +++ /dev/null @@ -1,27 +0,0 @@ -galaxy_info: - author: "Kevin Veen-Birkenbach" - description: "Updates Docker Compose instances by detecting changes in Docker image digests and rebuilding containers when necessary. This role automates Docker image pulls and container rebuilds." - license: "Infinito.Nexus NonCommercial License" - license_url: "https://s.infinito.nexus/license" - company: | - Kevin Veen-Birkenbach - Consulting & Coaching Solutions - https://www.veen.world - min_ansible_version: "2.9" - platforms: - - name: Archlinux - versions: - - rolling - - name: Ubuntu - versions: - - all - galaxy_tags: - - docker - - update - - compose - - images - - systemd - - maintenance - repository: "https://s.infinito.nexus/code" - issue_tracker_url: "https://s.infinito.nexus/issues" - documentation: "https://docs.infinito.nexus" diff --git a/roles/update-docker/tasks/01_core.yml b/roles/update-docker/tasks/01_core.yml deleted file mode 100644 index 55bde37c..00000000 --- a/roles/update-docker/tasks/01_core.yml +++ /dev/null @@ -1,20 +0,0 @@ -- name: Include dependency 'sys-lock' - include_role: - name: sys-lock - when: run_once_sys_lock is not defined - -- name: "start {{ 'sys-ctl-bkp-docker-2-loc-everything' | get_service_name(SOFTWARE_NAME) }}" - systemd: - name: "{{ 'sys-ctl-bkp-docker-2-loc-everything' | get_service_name(SOFTWARE_NAME) }}" - state: started - when: - - MODE_BACKUP | bool - -- include_role: - name: sys-service - vars: - system_service_restarted: true - system_service_timer_enabled: false - system_service_tpl_on_failure: "{{ SYS_SERVICE_ON_FAILURE_COMPOSE }}" - system_service_tpl_exec_start: "{{ system_service_script_exec }} {{ PATH_DOCKER_COMPOSE_INSTANCES }}" - system_service_tpl_exec_start_pre: "/usr/bin/python {{ PATH_SYSTEM_LOCK_SCRIPT }} {{ SYS_SERVICE_GROUP_MANIPULATION | join(' ') }} --ignore {{ SYS_SERVICE_GROUP_CLEANUP | join(' ') }} {{ 'update-docker' | get_service_name(SOFTWARE_NAME) }} --timeout '{{ SYS_TIMEOUT_DOCKER_UPDATE }}'" \ No newline at end of file diff --git a/roles/update-docker/tasks/main.yml b/roles/update-docker/tasks/main.yml deleted file mode 100644 index 9113e12e..00000000 --- a/roles/update-docker/tasks/main.yml +++ /dev/null @@ -1,4 +0,0 @@ -- block: - - include_tasks: 01_core.yml - - include_tasks: utils/run_once.yml - when: run_once_update_docker is not defined \ No newline at end of file diff --git a/roles/update-docker/templates/script.py.j2 b/roles/update-docker/templates/script.py.j2 deleted file mode 100644 index b27ce528..00000000 --- a/roles/update-docker/templates/script.py.j2 +++ /dev/null @@ -1,207 +0,0 @@ -import os -import subprocess -import sys -import time - -def run_command(command): - """ - Executes the specified shell command, streaming and collecting its output in real-time. - If the command exits with a non-zero status, a subprocess.CalledProcessError is raised, - including the exit code, the executed command, and the full output (as bytes) for debugging purposes. - """ - process = None - try: - process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - output = [] - - for line in iter(process.stdout.readline, b''): - decoded_line = line.decode() - output.append(decoded_line) - sys.stdout.write(decoded_line) - - return_code = process.wait() - if return_code: - full_output = ''.join(output) - raise subprocess.CalledProcessError(return_code, command, output=full_output.encode()) - finally: - if process and process.stdout: - process.stdout.close() - -def git_pull(): - """ - Checks whether the Git repository in the specified directory is up to date and performs a git pull if necessary. - - Raises: - Exception: If retrieving the local or remote git revision fails because the command returns a non-zero exit code. - """ - print("Checking if the git repository is up to date.") - - # Run 'git rev-parse @' and check its exit code explicitly. - local_proc = subprocess.run("git rev-parse @", shell=True, capture_output=True) - if local_proc.returncode != 0: - error_msg = local_proc.stderr.decode().strip() or "Unknown error while retrieving local revision." - raise Exception(f"Failed to retrieve local git revision: {error_msg}") - local = local_proc.stdout.decode().strip() - - # Run 'git rev-parse @{u}' and check its exit code explicitly. - remote_proc = subprocess.run("git rev-parse @{u}", shell=True, capture_output=True) - if remote_proc.returncode != 0: - error_msg = remote_proc.stderr.decode().strip() or "Unknown error while retrieving remote revision." - raise Exception(f"Failed to retrieve remote git revision: {error_msg}") - remote = remote_proc.stdout.decode().strip() - - if local != remote: - print("Repository is not up to date. Performing git pull.") - run_command("git pull") - return True - - print("Repository is already up to date.") - return False - -{% raw %} -def get_image_digests(directory): - """ - Retrieves the image digests for all images in the specified Docker Compose project. - """ - compose_project = os.path.basename(directory) - try: - images_output = subprocess.check_output( - f'docker images --format "{{{{.Repository}}}}:{{{{.Tag}}}}@{{{{.Digest}}}}" | grep {compose_project}', - shell=True - ).decode().strip() - return dict(line.split('@') for line in images_output.splitlines() if line) - except subprocess.CalledProcessError as e: - if e.returncode == 1: # grep no match found - return {} - else: - raise # Other errors are still raised -{% endraw %} - -def is_any_service_up(): - """ - Checks if any Docker services are currently running. - """ - process = subprocess.Popen("docker-compose ps -q", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - output, _ = process.communicate() - service_ids = output.decode().strip().splitlines() - return bool(service_ids) - -def pull_docker_images(): - """ - Pulls the latest Docker images for the project. - """ - print("Pulling docker images.") - try: - run_command("docker-compose pull") - except subprocess.CalledProcessError as e: - if "pull access denied" in e.output.decode() or "must be built from source" in e.output.decode(): - print("Need to build the image from source.") - return True - else: - print("Failed to pull images with unexpected error.") - raise - return False - -def update_docker(directory): - """ - Checks for updates to Docker images and rebuilds containers if necessary. - """ - print(f"Checking for updates to Docker images in {directory}.") - before_digests = get_image_digests(directory) - need_to_build = pull_docker_images() - after_digests = get_image_digests(directory) - if before_digests != after_digests: - print("Changes detected in image digests. Rebuilding containers.") - need_to_build = True - - if need_to_build: - # This propably just rebuilds the Dockerfile image if there is a change in the other docker compose containers - run_command("docker-compose build --pull") - start_docker(directory) - else: - print("Docker images are up to date. No rebuild necessary.") - -def update_discourse(directory): - """ - Updates Discourse by running the rebuild command on the launcher script. - """ - docker_repository_directory = os.path.join(directory, "services", "{{ applications | get_app_conf('web-app-discourse','repository') }}") - print(f"Using path {docker_repository_directory } to pull discourse repository.") - os.chdir(docker_repository_directory ) - if git_pull(): - print("Start Discourse update procedure.") - update_procedure("docker stop {{ applications | get_app_conf('web-app-discourse','docker.services.discourse.name') }}") - update_procedure("docker rm {{ applications | get_app_conf('web-app-discourse','docker.services.discourse.name') }}") - try: - update_procedure("docker network connect {{ applications | get_app_conf('web-app-discourse','docker.network') }} {{ applications | get_app_conf('svc-db-postgres', 'docker.network') }}") - except subprocess.CalledProcessError as e: - error_message = e.output.decode() - if "already exists" in error_message or "is already connected" in error_message: - print("Network connection already exists. Skipping...") - else: - raise - update_procedure("./launcher rebuild {{ applications | get_app_conf('web-app-discourse','docker.services.discourse.name') }}") - else: - print("Discourse update skipped. No changes in git repository.") - -def update_procedure(command): - """ - Attempts to execute a command up to a maximum number of retries. - """ - max_attempts = 3 - for attempt in range(max_attempts): - try: - run_command(command) - break # If the command succeeds, exit the loop - except subprocess.CalledProcessError as e: - if attempt < max_attempts - 1: # Check if it's not the last attempt - print(f"Attempt {attempt + 1} failed, retrying in 60 seconds...") - time.sleep(60) # Wait for 60 seconds before retrying - else: - print("All attempts to update have failed.") - raise # Re-raise the last exception after all attempts fail - -def start_docker(directory): - """ - Starts or restarts Docker services in the specified directory. - """ - if is_any_service_up(): - print(f"Restarting containers in {directory}.") - run_command("docker-compose up -d --force-recreate") - else: - print(f"Skipped starting. No service is up in {directory}.") - -if __name__ == "__main__": - if len(sys.argv) < 2: - print("Please provide the path to the parent directory as a parameter.") - sys.exit(1) - - parent_directory = sys.argv[1] - for dir_entry in os.scandir(parent_directory): - if dir_entry.is_dir(): - dir_path = dir_entry.path - print(f"Checking for updates in: {dir_path}") - os.chdir(dir_path) - - # Pull git repository if it exist - # @deprecated: This function should be removed in the future, as soon as all docker applications use the correct folder path - if os.path.isdir(os.path.join(dir_path, ".git")): - print("DEPRECATED: Docker .git repositories should be saved under /opt/docker/{instance}/services/{repository_name} ") - git_pull() - - if os.path.basename(dir_path) == "matrix": - # No autoupdate for matrix is possible atm, - # due to the reason that the role has to be executed every time. - # The update has to be executed in the role - # @todo implement in future - pass - else: - # Pull and update docker images - update_docker(dir_path) - - # The following instances need additional update and upgrade procedures - if os.path.basename(dir_path) == "discourse": - update_discourse(dir_path) - - # @todo implement dedicated procedure for bluesky - # @todo implement dedicated procedure for taiga diff --git a/roles/update-docker/vars/main.yml b/roles/update-docker/vars/main.yml deleted file mode 100644 index a630b7bb..00000000 --- a/roles/update-docker/vars/main.yml +++ /dev/null @@ -1,2 +0,0 @@ -application_id: update-docker -system_service_id: "{{ application_id }}" diff --git a/roles/web-app-matrix/tasks/01_docker.yml b/roles/web-app-matrix/tasks/01_docker.yml index 2e3f3b91..b3e69f74 100644 --- a/roles/web-app-matrix/tasks/01_docker.yml +++ b/roles/web-app-matrix/tasks/01_docker.yml @@ -67,7 +67,6 @@ notify: docker compose up # Pull image when update is wished. -# @todo This should be moved to update-docker - name: docker compose pull command: cmd: docker-compose -p "{{ MATRIX_PROJECT }}" pull