From b3448ba6de9c89296364c3c44b9ac3904d5cb99f Mon Sep 17 00:00:00 2001 From: Daniil Anfimov Date: Wed, 10 Jun 2026 15:16:25 +0300 Subject: [PATCH] Actualize dev deployment Resolves: https://github.com/AlmaLinux/build-system/issues/531 --- inventories/one_vm/group_vars/all.yml | 7 ++ playbooks/albs_on_one_vm.yml | 8 +- requirements.yml | 1 + roles/dev_deploy/defaults/main/common.yml | 7 ++ roles/dev_deploy/defaults/main/configs.yml | 8 +- roles/dev_deploy/tasks/misc.yml | 74 ++++++++++++++++- roles/dev_deploy/tasks/services.yml | 29 +++---- .../albs-gitea-listener-config.yaml.j2 | 4 +- roles/dev_deploy/templates/albs.conf.j2 | 80 ------------------- roles/dev_deploy/templates/build_node.yml.j2 | 2 +- roles/dev_deploy/templates/sign_node.yml.j2 | 4 +- roles/dev_deploy/templates/vars.env.j2 | 4 +- 12 files changed, 113 insertions(+), 115 deletions(-) delete mode 100644 roles/dev_deploy/templates/albs.conf.j2 diff --git a/inventories/one_vm/group_vars/all.yml b/inventories/one_vm/group_vars/all.yml index cca0af7..43fcc26 100644 --- a/inventories/one_vm/group_vars/all.yml +++ b/inventories/one_vm/group_vars/all.yml @@ -59,4 +59,11 @@ excluded_containers: - "test_db" - "web_server_tests" +# Containers that must NOT be started before bootstrap_permissions runs, +# so a human cannot race the bootstrap by signing in via OAuth and +# grabbing id=1 ahead of the system user. They are started later from +# misc.yml after the system user is created. +pre_bootstrap_excluded_containers: + - "nginx" + ... diff --git a/playbooks/albs_on_one_vm.yml b/playbooks/albs_on_one_vm.yml index e2d47c7..03d6979 100644 --- a/playbooks/albs_on_one_vm.yml +++ b/playbooks/albs_on_one_vm.yml @@ -1,7 +1,13 @@ --- - name: Deploy the ALBS hosts: all + connection: "{{ 'local' if use_local_connection else 'ssh' }}" roles: + - role: geerlingguy.docker + become: true + vars: + docker_install_compose_plugin: true + docker_users: + - "{{ ansible_user_id }}" - dev_deploy - connection: "{{ 'local' if use_local_connection else 'ssh' }}" ... diff --git a/requirements.yml b/requirements.yml index 4f98472..e13d5b4 100644 --- a/requirements.yml +++ b/requirements.yml @@ -2,6 +2,7 @@ roles: - name: ezamriy.fail2ban version: v0.1.0 + - name: geerlingguy.docker collections: - name: community.docker diff --git a/roles/dev_deploy/defaults/main/common.yml b/roles/dev_deploy/defaults/main/common.yml index 65c593a..84a4f61 100644 --- a/roles/dev_deploy/defaults/main/common.yml +++ b/roles/dev_deploy/defaults/main/common.yml @@ -33,5 +33,12 @@ created_directories: packages: - "gnupg" + - "python3-pip" + - "git" postgres_password: "{{ postgres_password | urlencode }}" + +# When true, bootstrap_repositories.py is invoked with -S to skip syncing +# repos from their remotes (useful for limited disk space; metadata-only +# on-demand sync still happens on first package request). +bootstrap_repositories_no_sync: false diff --git a/roles/dev_deploy/defaults/main/configs.yml b/roles/dev_deploy/defaults/main/configs.yml index 5b7cf94..193642a 100644 --- a/roles/dev_deploy/defaults/main/configs.yml +++ b/roles/dev_deploy/defaults/main/configs.yml @@ -4,10 +4,10 @@ generated_configs: dname: alts_config.yaml dest: "{{ sources_root }}/alts/configs" mode: "0644" - - sname: albs.conf.j2 - dname: albs.conf - dest: "{{ sources_root }}/albs-web-server/nginx_configs" - mode: "0644" + # nginx config (albs.conf) is intentionally NOT templated here — it lives + # in the albs-web-server repo at nginx_configs/albs.conf and is mounted + # directly into the nginx container. It has no per-deployment values, so + # there is no reason to duplicate it as a Jinja template here. - sname: alembic.ini.j2 dname: alembic.ini dest: "{{ sources_root }}/albs-web-server/alws" diff --git a/roles/dev_deploy/tasks/misc.yml b/roles/dev_deploy/tasks/misc.yml index ae5286c..2ef00fa 100644 --- a/roles/dev_deploy/tasks/misc.yml +++ b/roles/dev_deploy/tasks/misc.yml @@ -53,11 +53,11 @@ - name: Bootstrap repositories community.docker.docker_container_exec: container: "{{ container_name_prefix }}_web_server_1" - command: python3 scripts/bootstrap_repositories.py -c reference_data/platforms.yaml + command: "python3 scripts/bootstrap_repositories.py {{ '-S ' if bootstrap_repositories_no_sync else '' }}-c reference_data/platforms.yaml" register: result until: result is succeeded - retries: 10 - delay: 15 + retries: 2 + delay: 5 when: is_clean_installation.stat.exists == False - name: Activate user @@ -66,6 +66,71 @@ command: bash -c 'python3 scripts/manage_users.py -e base_user@almalinux.org -t AlmaLinux_team --verify --superuser || true' when: is_clean_installation.stat.exists == False +# The JWT initially generated in common.yml uses a guessed user_id and is +# only there so the first config render isn't empty. Now that the base +# user actually exists in the DB, regenerate the JWT via the web_server +# helper so it carries the real id and a fresh expiry, then re-render +# the configs and recreate the consumer containers. +- name: Regenerate ALBS JWT for the real base_user + tags: + - jwt_tokens + - albs_jwt_token + community.docker.docker_container_exec: + container: "{{ container_name_prefix }}_web_server_1" + command: >- + bash -c 'python3 scripts/generate_token.py + -e base_user@almalinux.org -s "{{ albs_jwt_secret }}" + | grep -E "^eyJ" | tail -n 1' + register: regenerated_albs_jwt + +- name: Update albs_jwt fact with regenerated token + tags: + - jwt_tokens + - albs_jwt_token + set_fact: + albs_jwt: "{{ regenerated_albs_jwt.stdout | trim }}" + when: + - regenerated_albs_jwt is defined + - regenerated_albs_jwt.stdout | default('') | trim | length > 0 + +- name: Re-render service configs with regenerated JWT + tags: + - jwt_tokens + - albs_jwt_token + - configs + template: + dest: "{{ item.dest }}/{{ item.dname }}" + src: "{{ item.sname }}" + mode: "{{ item.mode }}" + force: yes + with_items: "{{ generated_configs }}" + when: + - regenerated_albs_jwt is defined + - regenerated_albs_jwt.stdout | default('') | length > 0 + +- name: Recreate consumer containers to pick up regenerated JWT + tags: + - jwt_tokens + - albs_jwt_token + - services + shell: "{{ docker_compose }} -p {{ container_name_prefix }} --compatibility up -d --force-recreate {{ item }}" + args: + chdir: "{{ sources_root }}/albs-web-server" + loop: "{{ services.stdout_lines }}" + when: + - regenerated_albs_jwt is defined + - regenerated_albs_jwt.stdout | default('') | length > 0 + - item not in excluded_containers + - item not in (pre_bootstrap_excluded_containers | default([])) + - services is defined + +- name: Start containers deferred until after bootstrap + shell: "{{ docker_compose }} -p {{ container_name_prefix }} --compatibility up -d --build --force-recreate {{ item }}" + args: + chdir: "{{ sources_root }}/albs-web-server" + loop: "{{ pre_bootstrap_excluded_containers | default([]) }}" + when: pre_bootstrap_excluded_containers | default([]) + - name: Checking if GPG key exists on web_server tags: add_pgp_to_web_server ansible.builtin.uri: @@ -76,6 +141,9 @@ Authorization: "Bearer {{ albs_jwt }}" return_content: true register: gpg_request_output + until: gpg_request_output.status == 200 + retries: 30 + delay: 5 - name: Adding GPG key to the web_server tags: add_pgp_to_web_server diff --git a/roles/dev_deploy/tasks/services.yml b/roles/dev_deploy/tasks/services.yml index 6d6d9d9..a380976 100644 --- a/roles/dev_deploy/tasks/services.yml +++ b/roles/dev_deploy/tasks/services.yml @@ -1,26 +1,12 @@ --- -- name: Check if docker-compose command exists - shell: "command -v docker-compose || echo not found" - register: docker_compose_command +- name: Verify docker compose plugin (v2) is available + shell: "docker compose version" changed_when: False -- name: Find docker-compose - shell: "find / -name 'docker-compose' -executable -type f -print -quit 2>/dev/null | head -n 1" - register: docker_compose_find - when: docker_compose_command.stdout == "not found" - ignore_errors: true - changed_when: False - -- name: Set docker_compose variable to found path - set_fact: - docker_compose: "{{ docker_compose_find.stdout_lines[0] }}" - when: docker_compose_command.stdout == "not found" - -- name: Set docker_compose variable to command output +- name: Set docker_compose variable set_fact: - docker_compose: "{{ docker_compose_command.stdout }}" - when: docker_compose_command.stdout != "not found" + docker_compose: "docker compose" - name: Create and start services block: @@ -34,11 +20,13 @@ shell: "{{ docker_compose }} -p {{ container_name_prefix }} --compatibility up -d --build --force-recreate {{ item }}" args: chdir: "{{ sources_root }}/albs-web-server" - when: item not in excluded_containers + when: + - item not in excluded_containers + - item not in (pre_bootstrap_excluded_containers | default([])) loop: "{{ services.stdout_lines }}" when: - docker_compose != "not found" - - excluded_containers + - excluded_containers or (pre_bootstrap_excluded_containers | default([])) - name: Create and start services shell: "{{ docker_compose }} -p {{ container_name_prefix }} --compatibility up -d --build --force-recreate" @@ -48,6 +36,7 @@ when: - docker_compose != "not found" - not excluded_containers + - not (pre_bootstrap_excluded_containers | default([])) - debug: var: output diff --git a/roles/dev_deploy/templates/albs-gitea-listener-config.yaml.j2 b/roles/dev_deploy/templates/albs-gitea-listener-config.yaml.j2 index 93a5567..42cd4d3 100644 --- a/roles/dev_deploy/templates/albs-gitea-listener-config.yaml.j2 +++ b/roles/dev_deploy/templates/albs-gitea-listener-config.yaml.j2 @@ -1,5 +1,5 @@ --- -mqtt_queue_host: "{{ container_name_prefix }}_mosquitto_1" +mqtt_queue_host: "mosquitto" mqtt_queue_port: 1883 mqtt_queue_topic_unmodified: gitea-webhooks-unmodified mqtt_queue_topic_modified: gitea-webhooks-modified @@ -9,4 +9,4 @@ mqtt_queue_username: "\"\"" mqtt_queue_password: "\"\"" mqtt_queue_clean_session: False albs_jwt_token: "{{ albs_jwt }}" -albs_address: "http://{{ container_name_prefix }}_web_server_1:8000" +albs_address: "http://web_server:8000" diff --git a/roles/dev_deploy/templates/albs.conf.j2 b/roles/dev_deploy/templates/albs.conf.j2 deleted file mode 100644 index 9f29b51..0000000 --- a/roles/dev_deploy/templates/albs.conf.j2 +++ /dev/null @@ -1,80 +0,0 @@ -upstream backend { - server web_server:8000; -} - -upstream frontend { - server frontend:8080; -} - -upstream pulp { - server pulp:80; -} - -{% if 'sign_file' not in excluded_containers %} -upstream signfile { - server sign_file:8000; -} -{% endif %} - -map $http_upgrade $connection_upgrade { - default upgrade; - '' close; -} - -server { - listen 80; - client_max_body_size 100M; - location / { - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection $connection_upgrade; - proxy_set_header Host $host; - proxy_pass $scheme://frontend; - } - - location /api/v1/ { - proxy_read_timeout 900s; - proxy_set_header Host $http_host; - proxy_set_header Connection $http_connection; - proxy_set_header Upgrade $http_upgrade; - proxy_pass $scheme://backend; - } - - location /api_3/ { - proxy_read_timeout 900s; - proxy_set_header Host $http_host; - proxy_set_header Connection $http_connection; - proxy_set_header Upgrade $http_upgrade; - proxy_pass $scheme://backend; - } - - location /coprs/ { - proxy_read_timeout 900s; - proxy_set_header Host $http_host; - proxy_set_header Connection $http_connection; - proxy_set_header Upgrade $http_upgrade; - proxy_pass $scheme://backend; - } - - location /docs { - proxy_pass $scheme://backend; - } - - location /openapi.json { - proxy_pass $scheme://backend; - } - - location /pulp/ { - # header for decompressing build/test logs - if ($request_uri ~* (\.log$)) { - add_header Content-Encoding gzip; - } - proxy_pass http://pulp; - } - -{% if 'sign_file' not in excluded_containers %} - location /sign-file/ { - proxy_set_header Host $http_host; - proxy_pass http://signfile/; - } -{% endif %} -} diff --git a/roles/dev_deploy/templates/build_node.yml.j2 b/roles/dev_deploy/templates/build_node.yml.j2 index 20e28ea..f8778e6 100644 --- a/roles/dev_deploy/templates/build_node.yml.j2 +++ b/roles/dev_deploy/templates/build_node.yml.j2 @@ -1,6 +1,6 @@ --- development_mode: true -master_url: "http://{{ container_name_prefix }}_web_server_1:8000/api/v1/" +master_url: "http://web_server:8000/api/v1/" jwt_token: "{{ albs_jwt }}" pulp_host: "http://pulp" pulp_user: "{{ pulp_user }}" diff --git a/roles/dev_deploy/templates/sign_node.yml.j2 b/roles/dev_deploy/templates/sign_node.yml.j2 index b37f538..c8d967a 100644 --- a/roles/dev_deploy/templates/sign_node.yml.j2 +++ b/roles/dev_deploy/templates/sign_node.yml.j2 @@ -6,8 +6,8 @@ pulp_user: "{{ pulp_user }}" pulp_password: "{{ pulp_password }}" development_mode: true dev_pgp_key_password: "{{ gpg_default_password }}" -master_url: "http://{{ container_name_prefix }}_web_server_1:8000/api/v1/" -ws_master_url: "ws://{{ container_name_prefix }}_web_server_1:8000/api/v1/" +master_url: "http://web_server:8000/api/v1/" +ws_master_url: "ws://web_server:8000/api/v1/" {% if immudb_username is defined %} immudb_username: {{ immudb_username }} {% endif %} diff --git a/roles/dev_deploy/templates/vars.env.j2 b/roles/dev_deploy/templates/vars.env.j2 index 231817d..250b7e8 100644 --- a/roles/dev_deploy/templates/vars.env.j2 +++ b/roles/dev_deploy/templates/vars.env.j2 @@ -7,7 +7,7 @@ GITHUB_INTEGRATION_ENABLED="{{ github_integration_enabled | default(False) }}" GITHUB_APP_ID="{{ github_app_id | default(None) }}" PATH_TO_GITHUB_APP_PEM="{{ path_to_github_app_pem | default(None) }}" GITHUB_INSTALLATION_ID="{{ github_installation_id | default(None) }}" -ALTS_HOST="http://{{ container_name_prefix }}_alts-scheduler_1:8000" +ALTS_HOST="http://alts-scheduler:8000" ALTS_TOKEN="{{ alts_jwt }}" DATABASE_URL="{{ albs_db_url }}" SYNC_DATABASE_URL="{{ albs_db_sync_url }}" @@ -19,7 +19,7 @@ FASTAPI_SQLA__ASYNC__SQLALCHEMY_URL="{{ albs_db_url }}" FASTAPI_SQLA__ASYNC__SQLALCHEMY_ECHO_POOL=True FASTAPI_SQLA__PULP_ASYNC__SQLALCHEMY_URL="{{ async_pulp_database_url }}" FASTAPI_SQLA__PULP_ASYNC__SQLALCHEMY_ECHO_POOL=True -REDIS_URL="redis://{{ container_name_prefix }}_redis_1:6379" +REDIS_URL="redis://redis:6379" PULP_HOST="http://pulp" PULP_INTERNAL_HOST="http://pulp" PULP_USER="{{ pulp_user }}"