From 8bfec84235c41e51c0ed0068da00cb9e31bfcbaa Mon Sep 17 00:00:00 2001 From: Gloria Ciavarrini Date: Fri, 19 Jun 2026 10:40:07 +0200 Subject: [PATCH 1/3] feat(dcm_deploy): replace managers and gateway with control-plane Single control-plane container on :8080, provider URLs updated, postgres init from control-plane repo, alignment and Molecule tests adjusted. Assisted-By: Claude (Anthropic) Signed-off-by: Gloria Ciavarrini --- molecule/default/verify.yml | 32 ++++++---------- molecule/rootless/verify.yml | 11 +----- roles/dcm_deploy/defaults/main.yml | 19 +++------- .../dcm_deploy/tasks/deploy_quadlet_files.yml | 10 +---- roles/dcm_deploy/tasks/generate_configs.yml | 38 ++++--------------- .../dcm_deploy/tasks/initialize_database.yml | 5 +-- roles/dcm_deploy/tasks/prerequisites.yml | 5 +-- roles/dcm_deploy/tasks/start_services.yml | 32 +++------------- .../dcm_deploy/tasks/validate_deployment.yml | 21 ++-------- ...-acm-cluster-service-provider.container.j2 | 6 +-- .../dcm-catalog-manager.container.j2 | 26 ------------- ...iner.j2 => dcm-control-plane.container.j2} | 12 +++--- .../templates/dcm-gateway.container.j2 | 20 ---------- ...8s-container-service-provider.container.j2 | 6 +-- ...dcm-kubevirt-service-provider.container.j2 | 6 +-- .../dcm-placement-manager.container.j2 | 27 ------------- .../templates/dcm-policy-manager.container.j2 | 26 ------------- ...ee-tier-demo-service-provider.container.j2 | 6 +-- .../dcm_deploy/templates/dcm-ui.container.j2 | 6 +-- verify_compose_alignment.yml | 31 +++++++-------- 20 files changed, 76 insertions(+), 269 deletions(-) delete mode 100644 roles/dcm_deploy/templates/dcm-catalog-manager.container.j2 rename roles/dcm_deploy/templates/{dcm-service-provider-manager.container.j2 => dcm-control-plane.container.j2} (62%) delete mode 100644 roles/dcm_deploy/templates/dcm-gateway.container.j2 delete mode 100644 roles/dcm_deploy/templates/dcm-placement-manager.container.j2 delete mode 100644 roles/dcm_deploy/templates/dcm-policy-manager.container.j2 diff --git a/molecule/default/verify.yml b/molecule/default/verify.yml index 621d3d6..f989dda 100644 --- a/molecule/default/verify.yml +++ b/molecule/default/verify.yml @@ -7,11 +7,7 @@ core_containers: - dcm-postgres.container - dcm-nats.container - - dcm-service-provider-manager.container - - dcm-catalog-manager.container - - dcm-policy-manager.container - - dcm-placement-manager.container - - dcm-gateway.container + - dcm-control-plane.container - dcm-ui.container network_files: - dcm-network.network @@ -23,20 +19,14 @@ - dcm-k8s-container-service-provider.container - dcm-acm-cluster-service-provider.container - dcm-three-tier-demo-service-provider.container - # Manager images use Pull=always; infra containers (postgres, nats, gateway) do not - manager_containers: - - dcm-service-provider-manager.container - - dcm-catalog-manager.container - - dcm-policy-manager.container - - dcm-placement-manager.container + # DCM images use Pull=always; infra containers (postgres, nats) do not + pull_always_containers: + - dcm-control-plane.container - dcm-ui.container # Containers that use EnvironmentFile for shared env vars env_file_containers: - dcm-postgres.container - - dcm-service-provider-manager.container - - dcm-catalog-manager.container - - dcm-policy-manager.container - - dcm-placement-manager.container + - dcm-control-plane.container - dcm-three-tier-demo-service-provider.container tasks: # --- File existence --- @@ -158,19 +148,19 @@ loop_control: label: "{{ item.item }}" - # --- Manager containers have Pull=always --- - - name: Slurp manager container files + # --- DCM containers have Pull=always --- + - name: Slurp DCM container files ansible.builtin.slurp: src: "{{ quadlet_dir }}/{{ item }}" - register: manager_slurp - loop: "{{ manager_containers }}" + register: pull_always_slurp + loop: "{{ pull_always_containers }}" - - name: Assert manager containers have Pull=always + - name: Assert DCM containers have Pull=always ansible.builtin.assert: that: >- 'Pull=always' in (item.content | b64decode) fail_msg: "{{ item.item }} is missing Pull=always" - loop: "{{ manager_slurp.results }}" + loop: "{{ pull_always_slurp.results }}" loop_control: label: "{{ item.item }}" diff --git a/molecule/rootless/verify.yml b/molecule/rootless/verify.yml index 6376950..6444fd2 100644 --- a/molecule/rootless/verify.yml +++ b/molecule/rootless/verify.yml @@ -7,11 +7,7 @@ core_containers: - dcm-postgres.container - dcm-nats.container - - dcm-service-provider-manager.container - - dcm-catalog-manager.container - - dcm-policy-manager.container - - dcm-placement-manager.container - - dcm-gateway.container + - dcm-control-plane.container - dcm-ui.container network_files: - dcm-network.network @@ -21,10 +17,7 @@ # Containers that use EnvironmentFile for shared env vars env_file_containers: - dcm-postgres.container - - dcm-service-provider-manager.container - - dcm-catalog-manager.container - - dcm-policy-manager.container - - dcm-placement-manager.container + - dcm-control-plane.container tasks: # --- File existence --- - name: Stat core container files diff --git a/roles/dcm_deploy/defaults/main.yml b/roles/dcm_deploy/defaults/main.yml index e3a7eae..33efbde 100644 --- a/roles/dcm_deploy/defaults/main.yml +++ b/roles/dcm_deploy/defaults/main.yml @@ -4,15 +4,9 @@ dcm_postgres_image: "docker.io/library/postgres" dcm_postgres_image_tag: "16-alpine" dcm_nats_image: "docker.io/library/nats" dcm_nats_image_tag: "2-alpine" -dcm_traefik_image: "docker.io/traefik" -dcm_traefik_image_tag: "v3.4" - -# Container images — DCM managers +# Container images — DCM control plane dcm_image_registry: "quay.io/dcm-project" -dcm_service_provider_manager_version: "main" -dcm_catalog_manager_version: "main" -dcm_policy_manager_version: "main" -dcm_placement_manager_version: "main" +dcm_control_plane_version: "main" # Container images — DCM UI dcm_ui_version: "main" @@ -30,7 +24,7 @@ dcm_db_password: "adminpass" dcm_allow_default_password: false # Published ports -dcm_gateway_port: 9080 +dcm_control_plane_port: 8080 dcm_ui_port: 7007 # Set to true to publish postgres to the host — off by default to limit attack surface dcm_publish_postgres_port: false @@ -42,10 +36,9 @@ dcm_nats_monitor_port: 8222 dcm_config_dir: "/srv/containers/dcm/config" dcm_quadlet_dir: "/etc/containers/systemd" -# api-gateway repo (cloned at deploy time for config files) -dcm_api_gateway_repo: "https://github.com/dcm-project/api-gateway.git" -dcm_api_gateway_version: "main" -dcm_api_gateway_clone_dir: "/tmp/dcm-api-gateway" +# control-plane repo (cloned at deploy time for postgres init SQL) +dcm_control_plane_repo: "https://github.com/dcm-project/control-plane.git" +dcm_control_plane_clone_dir: "/tmp/dcm-control-plane" # Feature toggles for optional service providers dcm_provider_kubevirt: false diff --git a/roles/dcm_deploy/tasks/deploy_quadlet_files.yml b/roles/dcm_deploy/tasks/deploy_quadlet_files.yml index 12cee00..c95fe13 100644 --- a/roles/dcm_deploy/tasks/deploy_quadlet_files.yml +++ b/roles/dcm_deploy/tasks/deploy_quadlet_files.yml @@ -38,9 +38,7 @@ dcm_expected_quadlets: >- {{ ['dcm-postgres.container', 'dcm-nats.container', - 'dcm-service-provider-manager.container', 'dcm-catalog-manager.container', - 'dcm-policy-manager.container', 'dcm-placement-manager.container', - 'dcm-gateway.container', 'dcm-ui.container'] + + 'dcm-control-plane.container', 'dcm-ui.container'] + (['dcm-kubevirt-service-provider.container'] if dcm_provider_kubevirt else []) + (['dcm-k8s-container-service-provider.container'] if dcm_provider_k8s_container else []) + (['dcm-acm-cluster-service-provider.container'] if dcm_provider_acm_cluster else []) + @@ -109,11 +107,7 @@ loop: - dcm-postgres.container - dcm-nats.container - - dcm-service-provider-manager.container - - dcm-catalog-manager.container - - dcm-policy-manager.container - - dcm-placement-manager.container - - dcm-gateway.container + - dcm-control-plane.container - dcm-ui.container - name: Deploy KubeVirt service provider quadlet diff --git a/roles/dcm_deploy/tasks/generate_configs.yml b/roles/dcm_deploy/tasks/generate_configs.yml index 88eb9c5..22a8461 100644 --- a/roles/dcm_deploy/tasks/generate_configs.yml +++ b/roles/dcm_deploy/tasks/generate_configs.yml @@ -9,42 +9,20 @@ become: true become_user: "{{ _dcm_become_user }}" -- name: Clone api-gateway repo, copy config files, and clean up +- name: Clone control-plane repo, copy config files, and clean up block: - - name: Clone api-gateway repository + - name: Clone control-plane repository ansible.builtin.git: - repo: "{{ dcm_api_gateway_repo }}" - version: "{{ dcm_api_gateway_version }}" - dest: "{{ dcm_api_gateway_clone_dir }}" + repo: "{{ dcm_control_plane_repo }}" + version: "{{ dcm_control_plane_version }}" + dest: "{{ dcm_control_plane_clone_dir }}" force: true become: true become_user: "{{ _dcm_become_user }}" - - name: Copy Traefik static configuration - ansible.builtin.copy: - src: "{{ dcm_api_gateway_clone_dir }}/config/traefik.yml" - dest: "{{ dcm_config_dir }}/traefik/traefik.yml" - owner: "{{ _dcm_file_owner }}" - group: "{{ _dcm_file_group }}" - mode: "0644" - remote_src: true - become: true - become_user: "{{ _dcm_become_user }}" - - - name: Copy Traefik dynamic routes - ansible.builtin.copy: - src: "{{ dcm_api_gateway_clone_dir }}/config/dynamic/routes.yml" - dest: "{{ dcm_config_dir }}/traefik/dynamic/routes.yml" - owner: "{{ _dcm_file_owner }}" - group: "{{ _dcm_file_group }}" - mode: "0644" - remote_src: true - become: true - become_user: "{{ _dcm_become_user }}" - - name: Copy PostgreSQL init SQL ansible.builtin.copy: - src: "{{ dcm_api_gateway_clone_dir }}/hack/postgres-init/01-create-databases.sql" + src: "{{ dcm_control_plane_clone_dir }}/deploy/postgres-init/01-create-databases.sql" dest: "{{ dcm_config_dir }}/postgres-init/01-create-databases.sql" owner: "{{ _dcm_file_owner }}" group: "{{ _dcm_file_group }}" @@ -66,9 +44,9 @@ become_user: "{{ _dcm_become_user }}" always: - - name: Remove cloned api-gateway repository + - name: Remove cloned control-plane repository ansible.builtin.file: - path: "{{ dcm_api_gateway_clone_dir }}" + path: "{{ dcm_control_plane_clone_dir }}" state: absent become: true become_user: "{{ _dcm_become_user }}" diff --git a/roles/dcm_deploy/tasks/initialize_database.yml b/roles/dcm_deploy/tasks/initialize_database.yml index 08ac834..2e57c3c 100644 --- a/roles/dcm_deploy/tasks/initialize_database.yml +++ b/roles/dcm_deploy/tasks/initialize_database.yml @@ -16,10 +16,7 @@ environment: "{{ _dcm_rootless_env }}" register: db_check loop: - - service-provider - - policy-manager - - catalog-manager - - placement-manager + - control-plane changed_when: false - name: Create missing core databases diff --git a/roles/dcm_deploy/tasks/prerequisites.yml b/roles/dcm_deploy/tasks/prerequisites.yml index e370f45..78ecac0 100644 --- a/roles/dcm_deploy/tasks/prerequisites.yml +++ b/roles/dcm_deploy/tasks/prerequisites.yml @@ -20,9 +20,9 @@ state: started enabled: true -- name: Open DCM gateway port in firewall +- name: Open DCM control-plane port in firewall ansible.posix.firewalld: - port: "{{ dcm_gateway_port }}/tcp" + port: "{{ dcm_control_plane_port }}/tcp" zone: "{{ dcm_firewall_zone }}" permanent: true state: enabled @@ -56,5 +56,4 @@ group: "{{ _dcm_file_group }}" mode: "0755" loop: - - "{{ dcm_config_dir }}/traefik/dynamic" - "{{ dcm_config_dir }}/postgres-init" diff --git a/roles/dcm_deploy/tasks/start_services.yml b/roles/dcm_deploy/tasks/start_services.yml index d4b2fca..189c309 100644 --- a/roles/dcm_deploy/tasks/start_services.yml +++ b/roles/dcm_deploy/tasks/start_services.yml @@ -15,46 +15,26 @@ port: "{{ dcm_nats_port }}" timeout: 60 -- name: Start DCM manager services +- name: Start DCM control-plane service ansible.builtin.systemd_service: - name: "{{ item }}" + name: dcm-control-plane.service state: started enabled: true scope: "{{ _dcm_systemd_scope }}" become: true become_user: "{{ _dcm_become_user }}" environment: "{{ _dcm_rootless_env }}" - loop: - - dcm-service-provider-manager.service - - dcm-catalog-manager.service - - dcm-policy-manager.service - - dcm-placement-manager.service -- name: Wait for manager containers to be healthy - ansible.builtin.command: podman inspect --format {% raw %}'{{.State.Health.Status}}'{% endraw %} {{ item }} +- name: Wait for control-plane container to be healthy + ansible.builtin.command: podman inspect --format {% raw %}'{{.State.Health.Status}}'{% endraw %} control-plane become: true become_user: "{{ _dcm_become_user }}" environment: "{{ _dcm_rootless_env }}" - register: manager_health - until: manager_health.stdout | trim == "healthy" + register: control_plane_health + until: control_plane_health.stdout | trim == "healthy" retries: 30 delay: 2 changed_when: false - loop: - - service-provider-manager - - catalog-manager - - policy-manager - - placement-manager - -- name: Start DCM gateway service - ansible.builtin.systemd_service: - name: dcm-gateway.service - state: started - enabled: true - scope: "{{ _dcm_systemd_scope }}" - become: true - become_user: "{{ _dcm_become_user }}" - environment: "{{ _dcm_rootless_env }}" - name: Start DCM UI service ansible.builtin.systemd_service: diff --git a/roles/dcm_deploy/tasks/validate_deployment.yml b/roles/dcm_deploy/tasks/validate_deployment.yml index 261ce03..92119fc 100644 --- a/roles/dcm_deploy/tasks/validate_deployment.yml +++ b/roles/dcm_deploy/tasks/validate_deployment.yml @@ -1,21 +1,10 @@ --- -- name: Verify Traefik health +- name: Verify control-plane health endpoint ansible.builtin.uri: - url: "http://localhost:{{ dcm_gateway_port }}/ping" + url: "http://localhost:{{ dcm_control_plane_port }}/api/v1alpha1/health" method: GET status_code: [200] -- name: Verify manager health endpoints - ansible.builtin.uri: - url: "http://localhost:{{ dcm_gateway_port }}{{ item }}" - method: GET - status_code: [200] - loop: - - /api/v1alpha1/health/providers - - /api/v1alpha1/health/catalog - - /api/v1alpha1/health/policies - - /api/v1alpha1/health/placement - - name: Verify DCM UI is accessible ansible.builtin.uri: url: "http://localhost:{{ dcm_ui_port }}/" @@ -37,11 +26,7 @@ loop: - postgres - nats - - service-provider-manager - - catalog-manager - - policy-manager - - placement-manager - - gateway + - control-plane - dcm-ui - name: Assert KubeVirt provider is running diff --git a/roles/dcm_deploy/templates/dcm-acm-cluster-service-provider.container.j2 b/roles/dcm_deploy/templates/dcm-acm-cluster-service-provider.container.j2 index 12316ed..6fe61eb 100644 --- a/roles/dcm_deploy/templates/dcm-acm-cluster-service-provider.container.j2 +++ b/roles/dcm_deploy/templates/dcm-acm-cluster-service-provider.container.j2 @@ -1,7 +1,7 @@ [Unit] Description=DCM ACM Cluster Service Provider -After=dcm-service-provider-manager.service dcm-nats.service -Requires=dcm-service-provider-manager.service dcm-nats.service +After=dcm-control-plane.service dcm-nats.service +Requires=dcm-control-plane.service dcm-nats.service [Container] Image={{ dcm_image_registry }}/acm-cluster-service-provider:{{ dcm_acm_cluster_service_provider_version }} @@ -11,7 +11,7 @@ Pull=always EnvironmentFile={{ dcm_quadlet_dir }}/dcm-acm-cluster.env Environment=SP_NAME={{ dcm_acm_cluster_sp_name }} Environment=SP_ENDPOINT=http://acm-cluster-service-provider:8080 -Environment=DCM_REGISTRATION_URL=http://service-provider-manager:8080/api/v1alpha1 +Environment=DCM_REGISTRATION_URL=http://control-plane:8080/api/v1alpha1 Environment=SP_NATS_URL=nats://nats:4222 Environment=SP_CLUSTER_NAMESPACE={{ dcm_acm_cluster_sp_namespace }} Environment=SP_BASE_DOMAIN={{ dcm_acm_cluster_sp_base_domain }} diff --git a/roles/dcm_deploy/templates/dcm-catalog-manager.container.j2 b/roles/dcm_deploy/templates/dcm-catalog-manager.container.j2 deleted file mode 100644 index 37fe299..0000000 --- a/roles/dcm_deploy/templates/dcm-catalog-manager.container.j2 +++ /dev/null @@ -1,26 +0,0 @@ -[Unit] -Description=DCM Catalog Manager -After=dcm-postgres.service -Requires=dcm-postgres.service - -[Container] -Image={{ dcm_image_registry }}/catalog-manager:{{ dcm_catalog_manager_version }} -ContainerName=catalog-manager -Network=dcm-network.network -Pull=always -EnvironmentFile={{ dcm_quadlet_dir }}/dcm.env -Environment=BIND_ADDRESS=:8080 -Environment=DB_NAME=catalog-manager -Environment=PLACEMENT_MANAGER_URL=http://placement-manager:8080 -HealthCmd=bash -c 'echo > /dev/tcp/localhost/8080' -HealthInterval=2s -HealthRetries=15 -HealthTimeout=3s -HealthStartPeriod=10s - -[Service] -Restart=always -TimeoutStartSec=300 - -[Install] -WantedBy={{ _dcm_wanted_by }} diff --git a/roles/dcm_deploy/templates/dcm-service-provider-manager.container.j2 b/roles/dcm_deploy/templates/dcm-control-plane.container.j2 similarity index 62% rename from roles/dcm_deploy/templates/dcm-service-provider-manager.container.j2 rename to roles/dcm_deploy/templates/dcm-control-plane.container.j2 index 558e08d..d4da8cb 100644 --- a/roles/dcm_deploy/templates/dcm-service-provider-manager.container.j2 +++ b/roles/dcm_deploy/templates/dcm-control-plane.container.j2 @@ -1,17 +1,19 @@ [Unit] -Description=DCM Service Provider Manager +Description=DCM Control Plane After=dcm-postgres.service dcm-nats.service Requires=dcm-postgres.service dcm-nats.service [Container] -Image={{ dcm_image_registry }}/service-provider-manager:{{ dcm_service_provider_manager_version }} -ContainerName=service-provider-manager +Image={{ dcm_image_registry }}/control-plane:{{ dcm_control_plane_version }} +ContainerName=control-plane Network=dcm-network.network Pull=always EnvironmentFile={{ dcm_quadlet_dir }}/dcm.env -Environment=DB_NAME=service-provider -Environment=SVC_ADDRESS=:8080 +Environment=BIND_ADDRESS=:8080 +Environment=DB_NAME=control-plane +Environment=LOG_LEVEL=info Environment=NATS_URL=nats://nats:4222 +PublishPort={{ dcm_control_plane_port }}:8080 HealthCmd=bash -c 'echo > /dev/tcp/localhost/8080' HealthInterval=2s HealthRetries=15 diff --git a/roles/dcm_deploy/templates/dcm-gateway.container.j2 b/roles/dcm_deploy/templates/dcm-gateway.container.j2 deleted file mode 100644 index 1d75103..0000000 --- a/roles/dcm_deploy/templates/dcm-gateway.container.j2 +++ /dev/null @@ -1,20 +0,0 @@ -[Unit] -Description=DCM API Gateway (Traefik) -After=dcm-service-provider-manager.service dcm-catalog-manager.service dcm-policy-manager.service dcm-placement-manager.service -Requires=dcm-service-provider-manager.service dcm-catalog-manager.service dcm-policy-manager.service dcm-placement-manager.service - -[Container] -Image={{ dcm_traefik_image }}:{{ dcm_traefik_image_tag }} -ContainerName=gateway -Network=dcm-network.network -Exec=--configFile=/etc/traefik/traefik.yml -PublishPort={{ dcm_gateway_port }}:9080 -Volume={{ dcm_config_dir }}/traefik/traefik.yml:/etc/traefik/traefik.yml:ro,z -Volume={{ dcm_config_dir }}/traefik/dynamic:/etc/traefik/dynamic:ro,z - -[Service] -Restart=always -TimeoutStartSec=300 - -[Install] -WantedBy={{ _dcm_wanted_by }} diff --git a/roles/dcm_deploy/templates/dcm-k8s-container-service-provider.container.j2 b/roles/dcm_deploy/templates/dcm-k8s-container-service-provider.container.j2 index 16971da..4f03d7a 100644 --- a/roles/dcm_deploy/templates/dcm-k8s-container-service-provider.container.j2 +++ b/roles/dcm_deploy/templates/dcm-k8s-container-service-provider.container.j2 @@ -1,7 +1,7 @@ [Unit] Description=DCM K8s Container Service Provider -After=dcm-service-provider-manager.service dcm-nats.service -Requires=dcm-service-provider-manager.service dcm-nats.service +After=dcm-control-plane.service dcm-nats.service +Requires=dcm-control-plane.service dcm-nats.service [Container] Image={{ dcm_image_registry }}/k8s-container-service-provider:{{ dcm_k8s_container_service_provider_version }} @@ -10,7 +10,7 @@ Network=dcm-network.network Pull=always Environment=SP_NAME={{ dcm_k8s_container_sp_name }} Environment=SP_ENDPOINT=http://k8s-container-service-provider:8080 -Environment=DCM_REGISTRATION_URL=http://service-provider-manager:8080/api/v1alpha1 +Environment=DCM_REGISTRATION_URL=http://control-plane:8080/api/v1alpha1 Environment=SP_NATS_URL=nats://nats:4222 Environment=SP_K8S_NAMESPACE={{ dcm_k8s_container_sp_namespace }} Environment=SP_K8S_KUBECONFIG=/kubeconfig diff --git a/roles/dcm_deploy/templates/dcm-kubevirt-service-provider.container.j2 b/roles/dcm_deploy/templates/dcm-kubevirt-service-provider.container.j2 index 3d834bc..24d9282 100644 --- a/roles/dcm_deploy/templates/dcm-kubevirt-service-provider.container.j2 +++ b/roles/dcm_deploy/templates/dcm-kubevirt-service-provider.container.j2 @@ -1,7 +1,7 @@ [Unit] Description=DCM KubeVirt Service Provider -After=dcm-service-provider-manager.service -Requires=dcm-service-provider-manager.service +After=dcm-control-plane.service +Requires=dcm-control-plane.service [Container] Image={{ dcm_image_registry }}/kubevirt-service-provider:{{ dcm_kubevirt_service_provider_version }} @@ -9,7 +9,7 @@ ContainerName=kubevirt-service-provider Network=dcm-network.network Pull=always Environment=NATS_URL=nats://nats:4222 -Environment=SERVICE_MANAGER_ENDPOINT=http://service-provider-manager:8080/api/v1alpha1 +Environment=SERVICE_MANAGER_ENDPOINT=http://control-plane:8080/api/v1alpha1 Environment=PROVIDER_NAME={{ dcm_kubevirt_provider_name }} Environment=PROVIDER_ENDPOINT=http://{{ dcm_kubevirt_provider_name }}:8081/api/v1alpha1/vms Environment=KUBERNETES_NAMESPACE={{ dcm_kubevirt_namespace }} diff --git a/roles/dcm_deploy/templates/dcm-placement-manager.container.j2 b/roles/dcm_deploy/templates/dcm-placement-manager.container.j2 deleted file mode 100644 index ec0d916..0000000 --- a/roles/dcm_deploy/templates/dcm-placement-manager.container.j2 +++ /dev/null @@ -1,27 +0,0 @@ -[Unit] -Description=DCM Placement Manager -After=dcm-postgres.service -Requires=dcm-postgres.service - -[Container] -Image={{ dcm_image_registry }}/placement-manager:{{ dcm_placement_manager_version }} -ContainerName=placement-manager -Network=dcm-network.network -Pull=always -EnvironmentFile={{ dcm_quadlet_dir }}/dcm.env -Environment=BIND_ADDRESS=:8080 -Environment=DB_NAME=placement-manager -Environment=POLICY_MANAGER_EVALUATION_URL=http://policy-manager:8081 -Environment=SP_RESOURCE_MANAGER_URL=http://service-provider-manager:8080 -HealthCmd=bash -c 'echo > /dev/tcp/localhost/8080' -HealthInterval=2s -HealthRetries=15 -HealthTimeout=3s -HealthStartPeriod=10s - -[Service] -Restart=always -TimeoutStartSec=300 - -[Install] -WantedBy={{ _dcm_wanted_by }} diff --git a/roles/dcm_deploy/templates/dcm-policy-manager.container.j2 b/roles/dcm_deploy/templates/dcm-policy-manager.container.j2 deleted file mode 100644 index 271ee4b..0000000 --- a/roles/dcm_deploy/templates/dcm-policy-manager.container.j2 +++ /dev/null @@ -1,26 +0,0 @@ -[Unit] -Description=DCM Policy Manager -After=dcm-postgres.service -Requires=dcm-postgres.service - -[Container] -Image={{ dcm_image_registry }}/policy-manager:{{ dcm_policy_manager_version }} -ContainerName=policy-manager -Network=dcm-network.network -Pull=always -EnvironmentFile={{ dcm_quadlet_dir }}/dcm.env -Environment=BIND_ADDRESS=:8080 -Environment=LOG_LEVEL=info -Environment=DB_NAME=policy-manager -HealthCmd=bash -c 'echo > /dev/tcp/localhost/8080' -HealthInterval=2s -HealthRetries=15 -HealthTimeout=3s -HealthStartPeriod=10s - -[Service] -Restart=always -TimeoutStartSec=300 - -[Install] -WantedBy={{ _dcm_wanted_by }} diff --git a/roles/dcm_deploy/templates/dcm-three-tier-demo-service-provider.container.j2 b/roles/dcm_deploy/templates/dcm-three-tier-demo-service-provider.container.j2 index bd29c0a..c8f75e2 100644 --- a/roles/dcm_deploy/templates/dcm-three-tier-demo-service-provider.container.j2 +++ b/roles/dcm_deploy/templates/dcm-three-tier-demo-service-provider.container.j2 @@ -1,7 +1,7 @@ [Unit] Description=DCM Three-Tier Demo Service Provider -After=dcm-service-provider-manager.service dcm-nats.service dcm-k8s-container-service-provider.service dcm-postgres.service -Requires=dcm-service-provider-manager.service dcm-nats.service dcm-k8s-container-service-provider.service dcm-postgres.service +After=dcm-control-plane.service dcm-nats.service dcm-k8s-container-service-provider.service dcm-postgres.service +Requires=dcm-control-plane.service dcm-nats.service dcm-k8s-container-service-provider.service dcm-postgres.service [Container] Image={{ dcm_image_registry }}/three-tier-app-demo-service-provider:{{ dcm_three_tier_demo_service_provider_version }} @@ -13,7 +13,7 @@ Environment=DB_NAME=three-tier-sp Environment=CONTAINER_SP_URL=http://k8s-container-service-provider:8080 Environment=SP_NAME={{ dcm_three_tier_demo_sp_name }} Environment=SP_ENDPOINT=http://three-tier-demo-service-provider:8080 -Environment=DCM_REGISTRATION_URL=http://service-provider-manager:8080/api/v1alpha1 +Environment=DCM_REGISTRATION_URL=http://control-plane:8080/api/v1alpha1 Environment=SP_NATS_URL=nats://nats:4222 Environment=SP_K8S_NAMESPACE={{ dcm_three_tier_demo_sp_namespace }} Environment=SP_K8S_KUBECONFIG=/kubeconfig diff --git a/roles/dcm_deploy/templates/dcm-ui.container.j2 b/roles/dcm_deploy/templates/dcm-ui.container.j2 index 1ad04f5..692ab9a 100644 --- a/roles/dcm_deploy/templates/dcm-ui.container.j2 +++ b/roles/dcm_deploy/templates/dcm-ui.container.j2 @@ -1,7 +1,7 @@ [Unit] Description=DCM Web UI -After=dcm-gateway.service -Requires=dcm-gateway.service +After=dcm-control-plane.service +Requires=dcm-control-plane.service [Container] Image={{ dcm_image_registry }}/dcm-ui:{{ dcm_ui_version }} @@ -9,7 +9,7 @@ ContainerName=dcm-ui Network=dcm-network.network Pull=always Environment=APP_BASE_URL=http://{{ ansible_host }}:{{ dcm_ui_port }} -Environment=DCM_API_GATEWAY_URL=http://gateway:9080 +Environment=DCM_API_GATEWAY_URL=http://control-plane:8080 PublishPort={{ dcm_ui_port }}:7007 [Service] diff --git a/verify_compose_alignment.yml b/verify_compose_alignment.yml index dfa0b47..29ba981 100644 --- a/verify_compose_alignment.yml +++ b/verify_compose_alignment.yml @@ -12,9 +12,10 @@ gather_facts: false vars: - api_gateway_repo: "https://github.com/dcm-project/api-gateway.git" - api_gateway_version: "main" - clone_dest: "/tmp/dcm-api-gateway-alignment-check" + control_plane_repo: "https://github.com/dcm-project/control-plane.git" + control_plane_version: "main" + clone_dest: "/tmp/dcm-control-plane-alignment-check" + compose_path: "{{ clone_dest }}/deploy/compose.yaml" template_dir: "{{ playbook_dir }}/roles/dcm_deploy/templates" # Core services (non-profile) that must have quadlet templates. @@ -22,11 +23,7 @@ expected_core_services: - postgres - nats - - gateway - - service-provider-manager - - catalog-manager - - policy-manager - - placement-manager + - control-plane - ui # compose service 'dcm-ui' — its name already contains the dcm- prefix # Optional services (behind compose profiles) — templates exist but are # conditionally deployed @@ -44,11 +41,7 @@ service_to_template: postgres: dcm-postgres.container.j2 nats: dcm-nats.container.j2 - gateway: dcm-gateway.container.j2 - service-provider-manager: dcm-service-provider-manager.container.j2 - catalog-manager: dcm-catalog-manager.container.j2 - policy-manager: dcm-policy-manager.container.j2 - placement-manager: dcm-placement-manager.container.j2 + control-plane: dcm-control-plane.container.j2 ui: dcm-ui.container.j2 kubevirt-service-provider: dcm-kubevirt-service-provider.container.j2 k8s-container-service-provider: dcm-k8s-container-service-provider.container.j2 @@ -68,6 +61,9 @@ - POSTGRES_DB - POSTGRES_USER - POSTGRES_PASSWORD + # Quadlet uses ansible_host for browser access; compose uses localhost + ui: + - APP_BASE_URL # Infrastructure images use fully-variable names in templates (e.g., # {{ dcm_postgres_image }}) so we can't string-parse the image name. @@ -75,16 +71,15 @@ infra_image_mapping: postgres: dcm_postgres_image nats: dcm_nats_image - traefik: dcm_traefik_image tasks: - name: Clone, verify, and clean up block: # -- Phase 1: Clone and parse ---------------------------------------- - - name: Clone api-gateway repository + - name: Clone control-plane repository ansible.builtin.git: - repo: "{{ api_gateway_repo }}" - version: "{{ api_gateway_version }}" + repo: "{{ control_plane_repo }}" + version: "{{ control_plane_version }}" dest: "{{ clone_dest }}" single_branch: true depth: 1 @@ -92,7 +87,7 @@ - name: Read compose.yaml ansible.builtin.slurp: - src: "{{ clone_dest }}/compose.yaml" + src: "{{ compose_path }}" register: compose_raw - name: Parse full compose data From f624e228343a3ae0062b0acc59394d3b0aa6b7d9 Mon Sep 17 00:00:00 2001 From: Gloria Ciavarrini Date: Fri, 19 Jun 2026 10:40:17 +0200 Subject: [PATCH 2/3] docs: describe control-plane quadlet stack and variables Assisted-By: Claude (Anthropic) Signed-off-by: Gloria Ciavarrini --- CLAUDE.md | 37 ++++++++++++++--------------- README.md | 69 ++++++++++++++++++++----------------------------------- 2 files changed, 44 insertions(+), 62 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 88de426..210220c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -25,7 +25,7 @@ ansible-playbook -i inventory/hosts --extra-vars "vars_path=vars/dcm.yml" main.y # Run a single deployment phase ansible-playbook -i inventory/hosts --extra-vars "role_name=dcm_deploy" --extra-vars "task_name=validate_deployment" run_role_task.yml -# Check quadlet templates match upstream compose.yaml (runs locally, no inventory needed) +# Check quadlet templates match upstream deploy/compose.yaml (runs locally, no inventory needed) ansible-playbook verify_compose_alignment.yml # Run Molecule template rendering tests (no inventory needed) @@ -81,9 +81,9 @@ The `pull_secret` must be a valid `.dockerconfigjson` JSON string, base64-encode **Playbook entry points:** `main.yml` runs the full role. `run_role.yml`, `run_role_task.yml`, and `run_task.yml` are helpers for running individual roles or task phases. All four load variables from `vault_path`/`vault_dir` and `vars_path`/`vars_dir` extra-vars before executing. -**The role** (`roles/dcm_deploy/`) deploys 12 containers in six sequential phases defined in `tasks/main.yml`: prerequisites → generate_configs → deploy_quadlet_files → initialize_database → start_services → validate_deployment. An optional `resolve_rootless_vars` phase runs first (when `dcm_rootless: true`) to set internal facts that adapt all paths, ownership, and systemd scope for rootless Podman deployment. +**The role** (`roles/dcm_deploy/`) deploys 8 core containers (plus optional providers) in six sequential phases defined in `tasks/main.yml`: prerequisites → generate_configs → deploy_quadlet_files → initialize_database → start_services → validate_deployment. An optional `resolve_rootless_vars` phase runs first (when `dcm_rootless: true`) to set internal facts that adapt all paths, ownership, and systemd scope for rootless Podman deployment. -**Config source of truth:** Traefik config and PostgreSQL init SQL are NOT templated — they're copied from a clone of the upstream [api-gateway](https://github.com/dcm-project/api-gateway) repo at deploy time. Only `dcm.env.j2` and the quadlet unit files are Jinja2 templates. +**Config source of truth:** PostgreSQL init SQL is NOT templated — it's copied from a clone of the upstream [control-plane](https://github.com/dcm-project/control-plane) repo at deploy time. Only `dcm.env.j2` and the quadlet unit files are Jinja2 templates. ## Critical Naming Convention @@ -104,15 +104,17 @@ Mixing these up breaks either systemd dependency ordering or container DNS resol All quadlet templates are in `roles/dcm_deploy/templates/`. When editing: - Every container must have `dcm-network-network.service` in both `After=` and `Requires=` -- Manager images use `Pull=always` (important for `main` tags that update) +- DCM images (control-plane, dcm-ui) use `Pull=always` (important for `main` tags that update) - Volume mounts need SELinux suffixes: `:Z` for private (data volumes), `:z` for shared (read-only configs) -- Environment variables shared across managers go in `dcm.env.j2`; per-service vars go as `Environment=` directives in the container template -- Cross-reference env vars against upstream `compose.yaml` — the compose file is the source of truth +- Environment variables shared across services go in `dcm.env.j2`; per-service vars go as `Environment=` directives in the container template +- Cross-reference env vars against upstream `deploy/compose.yaml` — the compose file is the source of truth ## Provider Templates Optional providers (kubevirt, k8s-container, acm-cluster, three-tier-demo) are gated by `dcm_provider_*` boolean vars. Each provider's required vars are validated before templating — kubevirt/k8s-container only need a kubeconfig, but ACM needs five additional fields (see "Deploying Providers" above). The kubeconfig env var name differs per provider (`KUBERNETES_KUBECONFIG`, `SP_K8S_KUBECONFIG`, `KUBECONFIG`) — don't copy-paste between templates. +Service providers register with the control-plane monolith at `http://control-plane:8080/api/v1alpha1` (not separate manager services). + The three-tier-demo provider requires `dcm_provider_k8s_container` to be enabled; it shares the `dcm_k8s_container_sp_kubeconfig` path. ## Rootless Support @@ -129,13 +131,13 @@ The `dcm_quadlet_dir` and `dcm_config_dir` variables are overridden via `set_fac Rootless and rootful are mutually exclusive on the same host. There is no migration path between them — data volumes are stored in different Podman storage locations. -## Syncing with Upstream api-gateway +## Syncing with Upstream control-plane -The upstream compose.yaml at `https://github.com/dcm-project/api-gateway` is the source of truth. When it changes, this role must be updated to match. Run `ansible-playbook verify_compose_alignment.yml` first — it checks template file existence, environment variable coverage, dependency ordering (`depends_on` vs `After=`/`Requires=`), port mappings, and image name alignment. If it passes, the templates are in sync with compose. +The upstream `deploy/compose.yaml` at `https://github.com/dcm-project/control-plane` is the source of truth. When it changes, this role must be updated to match. Run `ansible-playbook verify_compose_alignment.yml` first — it checks template file existence, environment variable coverage, dependency ordering (`depends_on` vs `After=`/`Requires=`), port mappings, and image name alignment. If it passes, the templates are in sync with compose. ### New service added to compose.yaml -First classify it: **core manager** (needs DB, always deployed) or **optional provider** (behind a feature flag, needs kubeconfig). If unclear, check the `dcm-project` GitHub org — a service image `quay.io/dcm-project/` typically has its source at `https://github.com/dcm-project/`. Read the repo's README and Dockerfile for env vars, health endpoints, and dependencies. +First classify it: **core service** (always deployed) or **optional provider** (behind a feature flag, needs kubeconfig). If unclear, check the `dcm-project` GitHub org — a service image `quay.io/dcm-project/` typically has its source at `https://github.com/dcm-project/`. Read the repo's README and Dockerfile for env vars, health endpoints, and dependencies. Files to update (in order): @@ -144,11 +146,10 @@ Files to update (in order): 3. `roles/dcm_deploy/tasks/deploy_quadlet_files.yml` — TWO places: add to the `dcm_expected_quadlets` set_fact (used for stale file detection) AND to the core deploy loop (or as a conditional block with provider validation for optional providers). These lists overlap but serve different purposes — `dcm_expected_quadlets` includes all enabled services, the deploy loop only includes unconditional core services 4. `roles/dcm_deploy/tasks/start_services.yml` — add to startup sequence and running-state verification loop 5. `roles/dcm_deploy/tasks/validate_deployment.yml` — add to container assertions (and health check if it has one) -6. `roles/dcm_deploy/tasks/initialize_database.yml` — add database name if the service needs one. Core manager DBs go in the unconditional loop; optional provider DBs get their own conditional check/create tasks gated by `dcm_provider_*` -7. `roles/dcm_deploy/templates/dcm-gateway.container.j2` — if it's a core manager routed through Traefik, add to `After=`/`Requires=` -8. `verify_compose_alignment.yml` — add to `expected_core_services` or `expected_optional_services`, `service_to_template` mapping, and `infra_image_mapping` if it's an infrastructure image (not a DCM manager) -9. `molecule/default/verify.yml` — add to the appropriate container list (`core_containers` or `provider_containers`) and any relevant assertion groups (`manager_containers`, `env_file_containers`) -10. `README.md` — update stack components table and variable reference +6. `roles/dcm_deploy/tasks/initialize_database.yml` — add database name if the service needs one. Core DBs go in the unconditional loop; optional provider DBs get their own conditional check/create tasks gated by `dcm_provider_*` +7. `verify_compose_alignment.yml` — add to `expected_core_services` or `expected_optional_services`, `service_to_template` mapping, and `infra_image_mapping` if it's an infrastructure image (not a DCM image) +8. `molecule/default/verify.yml` — add to the appropriate container list (`core_containers` or `provider_containers`) and any relevant assertion groups (`pull_always_containers`, `env_file_containers`) +9. `README.md` — update stack components table and variable reference ### Existing service changed (env vars, dependencies, ports) @@ -160,11 +161,11 @@ Run `ansible-playbook verify_compose_alignment.yml` — it will catch most drift ### Image version bumps -Only update `defaults/main.yml` if compose pins a new major/minor (e.g., `postgres:16→17`, `traefik:v3.4→v3.5`). Manager versions default to `main` — don't change unless compose pins a specific tag. +Only update `defaults/main.yml` if compose pins a new major/minor (e.g., `postgres:16→17`). Control-plane and UI versions default to `main` — don't change unless compose pins a specific tag. -### Config file changes (traefik.yml, routes.yml, init SQL) +### Config file changes (postgres init SQL) -These are copied at deploy time from the cloned repo — usually no action needed here. But if new config files are added upstream (e.g., additional Traefik middleware), update `tasks/generate_configs.yml` to copy them. +These are copied at deploy time from the cloned control-plane repo — usually no action needed here unless new init files are added upstream, in which case update `tasks/generate_configs.yml` to copy them. ## CI @@ -173,7 +174,7 @@ GitHub Actions runs six jobs on every PR targeting `main`: - **check-clean-commits** — shared workflow that checks for merge commits, fixup/squash/WIP markers, vague commit messages - **Lint** — `yamllint` + `ansible-lint` - **Syntax check** — `ansible-playbook --syntax-check` on all playbooks -- **Compose-to-quadlet alignment** — runs `verify_compose_alignment.yml` against live upstream compose.yaml +- **Compose-to-quadlet alignment** — runs `verify_compose_alignment.yml` against live upstream `deploy/compose.yaml` - **Quadlet template rendering** — `molecule test` renders all core quadlet templates locally and asserts naming conventions, dependency symmetry, SELinux suffixes, Pull policy, env file references, and network membership - **Quadlet template rendering (rootless)** — `molecule test -s rootless` renders templates with `dcm_rootless: true` and asserts rootless-specific paths, `WantedBy=default.target`, and systemd scope diff --git a/README.md b/README.md index ecbdf89..699a69f 100644 --- a/README.md +++ b/README.md @@ -2,19 +2,15 @@ Deploy [DCM (Data Center Management)](https://github.com/dcm-project) as a systemd-managed Podman quadlet service stack on RHEL 9 or Fedora. -DCM is a microservice platform for managing service providers, catalogs, policies, and placement across infrastructure targets. This repo provides the canonical Ansible role for deploying all DCM services as individual quadlet containers with systemd integration — automatic restarts, dependency ordering, journal logging, and lifecycle management. It is the recommended production deployment path for running DCM on a RHEL 9 host without Kubernetes. +DCM is a platform for managing service providers, catalogs, policies, and placement across infrastructure targets. This repo provides the canonical Ansible role for deploying all DCM services as individual quadlet containers with systemd integration — automatic restarts, dependency ordering, journal logging, and lifecycle management. It is the recommended production deployment path for running DCM on a RHEL 9 host without Kubernetes. ## Stack Components | Service | Image | Description | |---------|-------|-------------| -| postgres | `docker.io/library/postgres:16-alpine` | Shared PostgreSQL database (5 databases) | +| postgres | `docker.io/library/postgres:16-alpine` | Shared PostgreSQL database | | nats | `docker.io/library/nats:2-alpine` | NATS message broker with JetStream | -| service-provider-manager | `quay.io/dcm-project/service-provider-manager` | Manages service provider registrations | -| catalog-manager | `quay.io/dcm-project/catalog-manager` | Service type catalog and instances | -| policy-manager | `quay.io/dcm-project/policy-manager` | Policy evaluation engine | -| placement-manager | `quay.io/dcm-project/placement-manager` | Resource placement decisions | -| gateway | `docker.io/traefik:v3.4` | Traefik reverse proxy (API gateway) | +| control-plane | `quay.io/dcm-project/control-plane` | DCM monolith (catalog, policy, placement, SP management) | | dcm-ui | `quay.io/dcm-project/dcm-ui` | DCM web interface | ### Optional Service Providers @@ -33,22 +29,18 @@ All services run as standalone containers on a shared bridge network (`dcm-netwo ``` dcm-network-network.service ├── dcm-postgres.service - │ ├── dcm-service-provider-manager.service (+ dcm-nats.service) - │ ├── dcm-catalog-manager.service - │ ├── dcm-policy-manager.service - │ └── dcm-placement-manager.service ├── dcm-nats.service - └── dcm-gateway.service (after all 4 managers) - ├── dcm-ui.service - ├── dcm-kubevirt-service-provider.service (optional) - ├── dcm-k8s-container-service-provider.service (optional) - │ └── dcm-three-tier-demo-service-provider.service (optional) - └── dcm-acm-cluster-service-provider.service (optional) + │ └── dcm-control-plane.service + │ ├── dcm-ui.service + │ ├── dcm-kubevirt-service-provider.service (optional) + │ ├── dcm-k8s-container-service-provider.service (optional) + │ │ └── dcm-three-tier-demo-service-provider.service (optional) + │ └── dcm-acm-cluster-service-provider.service (optional) ``` -Container names match the upstream `compose.yaml` exactly (no prefix). Systemd unit names use a `dcm-` prefix. Services resolve each other by container name via Podman DNS. +Container names match the upstream `deploy/compose.yaml` exactly (no prefix). Systemd unit names use a `dcm-` prefix. Services resolve each other by container name via Podman DNS. -Configuration files (Traefik routes, PostgreSQL init SQL) are sourced from the [api-gateway](https://github.com/dcm-project/api-gateway) repository, cloned at deploy time. This keeps api-gateway as the single source of truth. +PostgreSQL init SQL is sourced from the [control-plane](https://github.com/dcm-project/control-plane) repository, cloned at deploy time. This keeps control-plane as the single source of truth. ## Prerequisites @@ -63,12 +55,12 @@ Configuration files (Traefik routes, PostgreSQL init SQL) are sourced from the [ The `dcm_deploy` role executes in six phases (seven when `dcm_rootless: true`): 1. **Resolve rootless vars** *(optional, rootless only)* — creates the service user, configures subuid/subgid, enables lingering, starts the user systemd instance, and sets internal facts for user-scoped paths and systemd -1. **Prerequisites** — installs container tools, firewalld, and git; opens the gateway and UI ports; creates config directories -2. **Generate configs** — clones the api-gateway repo, copies Traefik config and PostgreSQL init SQL, templates the shared environment file, then cleans up the clone +1. **Prerequisites** — installs container tools, firewalld, and git; opens the control-plane and UI ports; creates config directories +2. **Generate configs** — clones the control-plane repo, copies PostgreSQL init SQL, templates the shared environment file, then cleans up the clone 3. **Deploy quadlet files** — places `.container`, `.network`, and `.volume` unit files into `/etc/containers/systemd/` and reloads systemd 4. **Initialize database** — starts PostgreSQL, creates all service databases if they don't exist -5. **Start services** — phased startup: NATS, then all four managers (with health checks), then the gateway, then the UI, then optional providers -6. **Validate** — checks the Traefik `/ping` endpoint, verifies all manager health endpoints through the gateway, and asserts all expected containers are running +5. **Start services** — phased startup: NATS, then control-plane (with health check), then the UI, then optional providers +6. **Validate** — checks the control-plane health endpoint and asserts all expected containers are running ## Usage @@ -124,18 +116,13 @@ ansible-playbook -i inventory/hosts \ | `dcm_postgres_image_tag` | `16-alpine` | PostgreSQL tag | | `dcm_nats_image` | `docker.io/library/nats` | NATS image | | `dcm_nats_image_tag` | `2-alpine` | NATS tag | -| `dcm_traefik_image` | `docker.io/traefik` | Traefik image | -| `dcm_traefik_image_tag` | `v3.4` | Traefik tag | | `dcm_image_registry` | `quay.io/dcm-project` | Registry for DCM service images | -### Manager Versions +### Control Plane and UI Versions | Variable | Default | Description | |----------|---------|-------------| -| `dcm_service_provider_manager_version` | `main` | Service provider manager image tag | -| `dcm_catalog_manager_version` | `main` | Catalog manager image tag | -| `dcm_policy_manager_version` | `main` | Policy manager image tag | -| `dcm_placement_manager_version` | `main` | Placement manager image tag | +| `dcm_control_plane_version` | `main` | Control-plane image tag | | `dcm_ui_version` | `main` | DCM UI image tag | ### Database @@ -149,7 +136,7 @@ ansible-playbook -i inventory/hosts \ | Variable | Default | Description | |----------|---------|-------------| -| `dcm_gateway_port` | `9080` | Traefik gateway port published to host | +| `dcm_control_plane_port` | `8080` | Control-plane API port published to host | | `dcm_ui_port` | `7007` | DCM UI port published to host (also used in `APP_BASE_URL`) | | `dcm_postgres_port` | `5432` | PostgreSQL port published to host | | `dcm_nats_port` | `4222` | NATS client port published to host | @@ -164,12 +151,12 @@ The DCM UI's `APP_BASE_URL` defaults to `http://:`. I | `dcm_config_dir` | `/srv/containers/dcm/config` | Configuration files on target host | | `dcm_quadlet_dir` | `/etc/containers/systemd` | Quadlet unit file directory | -### API Gateway Source +### Control Plane Source | Variable | Default | Description | |----------|---------|-------------| -| `dcm_api_gateway_repo` | `https://github.com/dcm-project/api-gateway.git` | Repo cloned for config files | -| `dcm_api_gateway_version` | `main` | Branch/tag to clone | +| `dcm_control_plane_repo` | `https://github.com/dcm-project/control-plane.git` | Repo cloned for postgres init SQL | +| `dcm_control_plane_version` | `main` | Branch/tag to clone | ### Feature Toggles @@ -269,14 +256,8 @@ Set `dcm_rootless_create_user: false` if user management is handled externally ( After deployment, verify the stack is healthy: ```bash -# Traefik gateway responds -curl http://:9080/ping - -# Manager health endpoints (through gateway) -curl http://:9080/api/v1alpha1/health/providers -curl http://:9080/api/v1alpha1/health/catalog -curl http://:9080/api/v1alpha1/health/policies -curl http://:9080/api/v1alpha1/health/placement +# Control-plane health endpoint +curl http://:8080/api/v1alpha1/health # DCM UI accessible curl http://:7007 @@ -299,7 +280,7 @@ podman exec postgres psql -U admin -l ## Compose Alignment -A standalone playbook `verify_compose_alignment.yml` checks that every service in the upstream `compose.yaml` has a corresponding quadlet template. Run it in CI to detect drift: +A standalone playbook `verify_compose_alignment.yml` checks that every service in the upstream `deploy/compose.yaml` has a corresponding quadlet template. Run it in CI to detect drift: ```bash ansible-playbook verify_compose_alignment.yml @@ -307,6 +288,6 @@ ansible-playbook verify_compose_alignment.yml ## Related Repositories -- [dcm-project/api-gateway](https://github.com/dcm-project/api-gateway) — upstream compose file, Traefik config, and init SQL +- [dcm-project/control-plane](https://github.com/dcm-project/control-plane) — upstream compose file and postgres init SQL - [dcm-project/utilities](https://github.com/dcm-project/utilities) — podman-compose dev deployment and E2E tooling - [brianredbeard/rhis-builder-quay](https://github.com/brianredbeard/rhis-builder-quay) — structural inspiration for the Ansible quadlet deployment pattern From 903751178c421a3619dff2179f2ff2403916224d Mon Sep 17 00:00:00 2001 From: Gloria Ciavarrini Date: Fri, 19 Jun 2026 16:05:20 +0200 Subject: [PATCH 3/3] fix(dcm_deploy): group control-plane version with repo defaults Assisted-By: Claude (Anthropic) Signed-off-by: Gloria Ciavarrini --- README.md | 18 +++++++++--------- roles/dcm_deploy/defaults/main.yml | 8 +++----- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 699a69f..1f336a3 100644 --- a/README.md +++ b/README.md @@ -118,11 +118,18 @@ ansible-playbook -i inventory/hosts \ | `dcm_nats_image_tag` | `2-alpine` | NATS tag | | `dcm_image_registry` | `quay.io/dcm-project` | Registry for DCM service images | -### Control Plane and UI Versions +### Control Plane + +| Variable | Default | Description | +|----------|---------|-------------| +| `dcm_control_plane_version` | `main` | Image tag and git clone ref | +| `dcm_control_plane_repo` | `https://github.com/dcm-project/control-plane.git` | Repo cloned for postgres init SQL | +| `dcm_control_plane_clone_dir` | `/tmp/dcm-control-plane` | Clone destination on target host | + +### DCM UI | Variable | Default | Description | |----------|---------|-------------| -| `dcm_control_plane_version` | `main` | Control-plane image tag | | `dcm_ui_version` | `main` | DCM UI image tag | ### Database @@ -151,13 +158,6 @@ The DCM UI's `APP_BASE_URL` defaults to `http://:`. I | `dcm_config_dir` | `/srv/containers/dcm/config` | Configuration files on target host | | `dcm_quadlet_dir` | `/etc/containers/systemd` | Quadlet unit file directory | -### Control Plane Source - -| Variable | Default | Description | -|----------|---------|-------------| -| `dcm_control_plane_repo` | `https://github.com/dcm-project/control-plane.git` | Repo cloned for postgres init SQL | -| `dcm_control_plane_version` | `main` | Branch/tag to clone | - ### Feature Toggles | Variable | Default | Description | diff --git a/roles/dcm_deploy/defaults/main.yml b/roles/dcm_deploy/defaults/main.yml index 33efbde..6b7be92 100644 --- a/roles/dcm_deploy/defaults/main.yml +++ b/roles/dcm_deploy/defaults/main.yml @@ -4,9 +4,11 @@ dcm_postgres_image: "docker.io/library/postgres" dcm_postgres_image_tag: "16-alpine" dcm_nats_image: "docker.io/library/nats" dcm_nats_image_tag: "2-alpine" -# Container images — DCM control plane +# DCM control plane (container image + deploy-time config clone) dcm_image_registry: "quay.io/dcm-project" dcm_control_plane_version: "main" +dcm_control_plane_repo: "https://github.com/dcm-project/control-plane.git" +dcm_control_plane_clone_dir: "/tmp/dcm-control-plane" # Container images — DCM UI dcm_ui_version: "main" @@ -36,10 +38,6 @@ dcm_nats_monitor_port: 8222 dcm_config_dir: "/srv/containers/dcm/config" dcm_quadlet_dir: "/etc/containers/systemd" -# control-plane repo (cloned at deploy time for postgres init SQL) -dcm_control_plane_repo: "https://github.com/dcm-project/control-plane.git" -dcm_control_plane_clone_dir: "/tmp/dcm-control-plane" - # Feature toggles for optional service providers dcm_provider_kubevirt: false dcm_provider_k8s_container: false