From 257cafad84fe78b5dfb170500dde859c04da0d39 Mon Sep 17 00:00:00 2001 From: "martin.fencl" Date: Tue, 1 Sep 2026 09:16:39 +0200 Subject: [PATCH] feat: enhance Glance deployment with improved configuration and error handling --- docker-compose/docker-compose-glance.yml | 19 ++-- files/glance/glance.yml | 9 +- update_glance.yml | 107 +++++++++++++++++------ 3 files changed, 95 insertions(+), 40 deletions(-) diff --git a/docker-compose/docker-compose-glance.yml b/docker-compose/docker-compose-glance.yml index 25a595f..a0efa99 100644 --- a/docker-compose/docker-compose-glance.yml +++ b/docker-compose/docker-compose-glance.yml @@ -1,22 +1,25 @@ # docker-compose-glance.yml +name: glance + services: glance: container_name: glance image: glanceapp/glance:latest restart: unless-stopped volumes: - # Relative to project_src (~/.ansible-compose), so no username is hardcoded. - # The playbook creates this directory and uploads glance.yml into it. + # Relative to project_src (~/.ansible-compose/glance), so no username is + # hardcoded. The playbook creates this directory and uploads glance.yml. # The image entrypoint is /app/glance --config /app/config/glance.yml, # so the file must be named exactly glance.yml. - - ./glance/config:/app/config + - ./config:/app/config + - /etc/localtime:/etc/localtime:ro environment: # Used by the calendar widget and by relative timestamps - TZ=Europe/Prague - # Optional: raises the GitHub API limit for the releases widget. - # Referenced from glance.yml as ${GITHUB_TOKEN}; inject it as a - # Semaphore secret instead of committing it here. - # - GITHUB_TOKEN=${GITHUB_TOKEN} + env_file: + # Deployed by the playbook from the persistent env file on the VM. + # Provides GITHUB_TOKEN, referenced from glance.yml as ${GITHUB_TOKEN}. + - .env ports: - - '9445:8080' + - '9445:8080' \ No newline at end of file diff --git a/files/glance/glance.yml b/files/glance/glance.yml index 4675936..a9db2d6 100644 --- a/files/glance/glance.yml +++ b/files/glance/glance.yml @@ -1,4 +1,5 @@ # glance.yml - source of truth lives in git, deployed by update_glance.yml +# GITHUB_TOKEN comes from the persistent env file on the VM, never from git. pages: - name: Home @@ -77,12 +78,12 @@ pages: - type: releases cache: 1d - # Without authentication the GitHub API allows up to 60 requests per hour. - # Uncomment and pass GITHUB_TOKEN in as an environment variable to raise it. - # token: ${GITHUB_TOKEN} + # Without a token the GitHub API allows up to 60 requests per hour. + # A read-only token with no scopes raises this to 5000. + token: ${GITHUB_TOKEN} repositories: - trezor/trezor-firmware - glanceapp/glance - go-gitea/gitea - immich-app/immich - - syncthing/syncthing + - syncthing/syncthing \ No newline at end of file diff --git a/update_glance.yml b/update_glance.yml index 2774fb9..d4705d0 100644 --- a/update_glance.yml +++ b/update_glance.yml @@ -11,22 +11,50 @@ # Glance settings glance_project: glance + glance_port: 9445 glance_compose_filename: "docker-compose-glance.yml" glance_service: glance - glance_port: 9445 - # Config delivery (git -> controller -> target). - # Must match the ./glance/config volume in the compose file. - glance_config_local: "{{ playbook_dir }}/files/glance/glance.yml" + # Own project directory, so .env does not collide with other stacks + glance_remote_dir: "{{ compose_remote_base }}/glance" glance_config_remote_dir: "{{ compose_remote_base }}/glance/config" + # Config delivery (git -> controller -> target) + glance_config_local: "{{ playbook_dir }}/files/glance/glance.yml" + + # Persistent env file on the VM (NOT in git) + glance_env_persistent: "{{ compose_remote_base }}/env/glance.env" + tasks: - - name: Ensure remote compose directory exists + - name: Ensure remote base directory exists ansible.builtin.file: path: "{{ compose_remote_base }}" state: directory mode: "0755" + - name: Ensure remote env directory exists + ansible.builtin.file: + path: "{{ compose_remote_base }}/env" + state: directory + + - name: Check for persistent Glance env file + ansible.builtin.stat: + path: "{{ glance_env_persistent }}" + register: glance_env_stat + + - name: Abort when Glance env is missing + ansible.builtin.fail: + msg: >- + Missing persistent env file: {{ glance_env_persistent }}. + Create it on the VM with a GITHUB_TOKEN variable. + when: not glance_env_stat.stat.exists + + - name: Ensure Glance project directory exists + ansible.builtin.file: + path: "{{ glance_remote_dir }}" + state: directory + mode: "0755" + - name: Ensure Glance config directory exists ansible.builtin.file: path: "{{ glance_config_remote_dir }}" @@ -36,7 +64,7 @@ - name: Upload Glance compose file to remote host ansible.builtin.copy: src: "{{ compose_local_dir }}/{{ glance_compose_filename }}" - dest: "{{ compose_remote_base }}/{{ glance_compose_filename }}" + dest: "{{ glance_remote_dir }}/{{ glance_compose_filename }}" mode: "0644" - name: Upload Glance configuration @@ -45,10 +73,17 @@ dest: "{{ glance_config_remote_dir }}/glance.yml" mode: "0644" + - name: Deploy Glance .env into compose directory + ansible.builtin.copy: + src: "{{ glance_env_persistent }}" + dest: "{{ glance_remote_dir }}/.env" + remote_src: true + mode: "0600" + - name: Pull latest Glance image community.docker.docker_compose_v2: project_name: "{{ glance_project }}" - project_src: "{{ compose_remote_base }}" + project_src: "{{ glance_remote_dir }}" files: - "{{ glance_compose_filename }}" pull: always @@ -56,7 +91,7 @@ - name: Recreate Glance service community.docker.docker_compose_v2: project_name: "{{ glance_project }}" - project_src: "{{ compose_remote_base }}" + project_src: "{{ glance_remote_dir }}" files: - "{{ glance_compose_filename }}" services: @@ -64,25 +99,41 @@ state: present recreate: always - - name: Wait for Glance port - ansible.builtin.wait_for: - host: 127.0.0.1 - port: "{{ glance_port }}" - timeout: 60 + - name: Verify Glance is serving + block: + - name: Wait for Glance port + ansible.builtin.wait_for: + host: 127.0.0.1 + port: "{{ glance_port }}" + timeout: 60 - - name: Check Glance HTTP endpoint - ansible.builtin.uri: - url: "http://127.0.0.1:{{ glance_port }}/" - status_code: 200 - register: glance_http - retries: 30 - delay: 3 - until: glance_http.status == 200 - changed_when: false + - name: Check Glance HTTP endpoint (retry until ready) + ansible.builtin.uri: + url: "http://127.0.0.1:{{ glance_port }}/" + status_code: 200 + register: glance_http + retries: 30 + delay: 3 + until: glance_http.status == 200 + changed_when: false - - name: Show Glance container logs on failed startup - ansible.builtin.command: - cmd: "docker logs --tail 50 glance" - register: glance_logs - changed_when: false - when: glance_http is failed \ No newline at end of file + rescue: + - name: Collect Glance container logs + ansible.builtin.command: + cmd: "docker logs --tail 50 glance" + register: glance_logs + changed_when: false + failed_when: false + + - name: Show Glance container logs + ansible.builtin.debug: + msg: "{{ glance_logs.stderr_lines | default([]) + glance_logs.stdout_lines | default([]) }}" + + - name: Fail after showing logs + ansible.builtin.fail: + msg: "Glance did not become healthy on port {{ glance_port }}. See container logs above." + + - name: Clean up legacy compose file from shared base directory + ansible.builtin.file: + path: "{{ compose_remote_base }}/{{ glance_compose_filename }}" + state: absent \ No newline at end of file