Skip to content

Deploying packit-service via quadlets - #3167

Open
LecrisUT wants to merge 6 commits into
packit:mainfrom
LecrisUT:quadlet
Open

Deploying packit-service via quadlets#3167
LecrisUT wants to merge 6 commits into
packit:mainfrom
LecrisUT:quadlet

Conversation

@LecrisUT

Copy link
Copy Markdown
Collaborator

The goal of such a setup is to have a more composable deployment setup than the docker-compose setup. This makes use of the systemd drop-in configuration files to be able to select the components that you want, e.g. dev being a setup that would use the current sources and pick up the live edits. In principle the user would simply run

$ systemctl --user daemon-reload
$ systemctl --user start packit-service

(after setting up systemd to pick up these quadlets file, see quadlet/README.md for more info)

TODO:

  • Document basic quadlet setup
  • Define all necessary quadlet files

@LecrisUT
LecrisUT requested a review from a team as a code owner August 20, 2026 06:13
@LecrisUT
LecrisUT requested review from betulependule and removed request for a team August 20, 2026 06:13
@fullsend-ai-review

fullsend-ai-review Bot commented Aug 20, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 6:14 AM UTC · Completed 6:34 AM UTC

Commit: d832317 · View workflow run →

@LecrisUT

Copy link
Copy Markdown
Collaborator Author

CC @FrostyX you would probably be interested to try this out (once we figure out the actual components). Could also be interesting for copr to check

@centosinfra-prod-github-app

Copy link
Copy Markdown
Contributor

@fullsend-ai-review

fullsend-ai-review Bot commented Aug 20, 2026

Copy link
Copy Markdown

Review

Findings

High

  • [undefined-variable] files/recipe-worker.yaml:11recipe-worker.yaml imports tasks/common.yaml, which now references {{ editable_install }} in the pip task's editable parameter. However, recipe-worker.yaml does not define editable_install in its vars section (only recipe.yaml defines it). This will cause an Ansible undefined variable error when building the worker image via make worker or Dockerfile.worker, breaking the worker container build.
    Remediation: Add editable_install: "{{ lookup('env', 'DEPLOYMENT') == 'dev' }}" to the vars section in files/recipe-worker.yaml.

Medium

  • [logic-error] files/run_httpd.sh:28 — The --http2 flag is unconditionally added to http_flags, including the plain HTTP code path (the else branch). Apache's mod_http2 requires TLS for the h2 protocol. Passing --http2 with --port (plain HTTP) may cause mod_wsgi-express to fail to start or silently ignore the flag.
    Remediation: Move --http2 into the TLS branch (inside the if [[ -f /secrets/privkey.pem ]] block).

  • [fail-open] files/run_httpd.sh:33 — The new conditional logic silently falls back to plain HTTP (port 8080) when /secrets/privkey.pem is absent. Previously, the server always attempted HTTPS and would fail if certificates were missing (fail-closed). This also affects the existing docker-compose deployment path — a misconfiguration (e.g., missing certificate volume mount) could cause the service to silently serve unencrypted traffic.
    Remediation: Add an explicit warning log in the else branch. Consider restricting the HTTP fallback to dev/local deployments only (e.g., gating on DEPLOYMENT env var).

  • [scope-mismatch] — The PR title is prefixed with [WIP] and the TODO list has an incomplete item ("Define all necessary quadlet files"), yet the PR carries the ready-for-merge label and is not a draft. These are contradictory signals.
    Remediation: Either remove [WIP] and complete remaining TODOs, or remove the ready-for-merge label until the work is complete.

  • [stale-doc] CONTRIBUTING.md:62 — The "binding on localhost" section assumes HTTPS is always used (port 443, curl -k --head https://..., "Port 443 is used because the certificate is bundled with it"). After this PR, HTTPS is conditional and the service may run on HTTP port 8080 when certificates are absent.
    Remediation: Add a note explaining the HTTP fallback behavior.

Low

  • [missing-authorization] — No linked issue for a non-trivial change introducing a new deployment paradigm (22 files). The PR body describes the motivation, but changes of this scope should be traceable to a tracked issue.

  • [stale-doc] CONTRIBUTING.md:84 — The "binding on other hosts" section shows only HTTPS examples with port 8443. The HTTP fallback (port 8080) is not mentioned.

  • [build-time-environment] files/recipe.yaml:10editable_install reads DEPLOYMENT at Ansible execution time. The existing Dockerfile build path does not set this variable, so editable install only works via the new quadlet build path. Likely intentional but undocumented.

  • [naming-convention] files/run_httpd.sh:25http_flags uses lowercase while all other substantive variables in the file use UPPER_CASE (ATTEMPTS, SERVER_NAME, PORT, PACKIT_SERVICE_CONFIG).

  • [scope-creep] files/recipe.yaml:10 — Adding editable_install to the shared Ansible recipe couples the new quadlet workflow to the existing Dockerfile build pipeline. The existing behavior is preserved (DEPLOYMENT unset → non-editable), but the coupling is undocumented.

  • [missing-doc] CONTRIBUTING.md:40 — The "Running packit-service locally" section describes only the docker-compose approach. The new quadlet deployment option is not referenced; consider adding a pointer to quadlets/README.md.


Next steps:

  • /fs-fix — agent addresses review findings automatically
  • /fs-fix <your instruction> — agent fixes with your specific guidance
  • Push commits directly — review re-runs automatically on push
  • /fs-fix-stop — disable automatic fix runs for this PR
Previous run

Review

Findings

Low

  • [api-contract] quadlets/dev/packit-service.build:5 — Uses Environment=SOURCE_BRANCH=main in the [Build] section. While Environment= maps to podman build --env and makes the variable available during RUN instructions (so the Dockerfile's ARG SOURCE_BRANCH check should pass), it is semantically intended for build-time environment, not for satisfying Dockerfile ARG declarations. Consider using PodmanArgs=--build-arg SOURCE_BRANCH=main for clarity, since BuildArg= does not exist in the .build quadlet spec.

  • [logic-error] quadlets/base/packit-dashboard.container:7 — The base dashboard container uses Image=quay.io/packit/dashboard:prod, while docker-compose.yml uses the :stg tag. The quadlet's layered architecture (base defaults + environment drop-ins) makes :prod as a base default reasonable, but verify this is intentional.

  • [edge-case] quadlets/dev/packit-service.container.d/dev.conf:4 — Volume directives use relative paths (../../packit_service, ../../alembic). Relative paths in systemd units resolve relative to the service's WorkingDirectory, not the unit file location. Without an explicit WorkingDirectory, these may not resolve to the intended repo root paths.

  • [scope-mismatch] quadlets/ — The PR title contains [WIP] and the body has an incomplete TODO checklist (Define all necessary quadlet files is unchecked), yet the PR is not marked as a draft (draft: false).

  • [architectural-coherence] quadlets/ — Consider documenting whether quadlets will supplement or eventually replace docker-compose.

  • [scope-completeness] quadlets/base/packit-service.container — Only 2 of the ~10 docker-compose services are defined. The current quadlet files lack port mappings, secrets volumes, and required environment variables for a functional deployment.

  • [naming-coherence] quadlets/base/packit-service.container:3 — Image name quay.io/packit/service:prod differs from docker-compose's quay.io/packit/packit-service:dev — verify the correct image name (packit/service vs packit/packit-service).

  • [naming-convention] quadlets/dev/packit-service.build:2ImageTag=localhost/packit-service:dev uses localhost/ prefix, which is standard Podman practice for locally-built images but differs from the quay.io/ convention used elsewhere.

  • [naming-convention] quadlets/prod/packit-service.container.d/prod.conf — Prod overrides only set DEPLOYMENT=prod. Required env vars from docker-compose (REDIS_SERVICE_HOST, POSTGRESQL_*, etc.) are absent — expected given WIP status.


Labels: PR adds systemd quadlet deployment configuration files under quadlets/

fullsend-ai-review[bot]

This comment was marked as outdated.

@fullsend-ai-review fullsend-ai-review Bot added ready-for-merge All reviewers approved — ready to merge area/deployment Related to the Packit's deployment labels Aug 20, 2026
Signed-off-by: Cristian Le <git@lecris.dev>
Signed-off-by: Cristian Le <git@lecris.dev>
Signed-off-by: Cristian Le <git@lecris.dev>
Signed-off-by: Cristian Le <git@lecris.dev>
Signed-off-by: Cristian Le <git@lecris.dev>
Signed-off-by: Cristian Le <git@lecris.dev>
@fullsend-ai-review

fullsend-ai-review Bot commented Aug 21, 2026

Copy link
Copy Markdown

🤖 Review · ❌ Terminated · Started 6:41 AM UTC · Ended 7:00 AM UTC

Commit: ad641e2 · View workflow run →

@centosinfra-prod-github-app

Copy link
Copy Markdown
Contributor

@fullsend-ai-review fullsend-ai-review Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See the review comment for full details.

Comment thread files/run_httpd.sh

http_flags=(
--http2
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[medium] logic-error

The --http2 flag is unconditionally added to http_flags, including the plain HTTP code path. Apache's mod_http2 requires TLS for h2. Passing --http2 with --port (plain HTTP) may cause mod_wsgi-express to fail to start or silently ignore the flag.

Suggested fix: Move --http2 into the TLS branch (inside the if [[ -f /secrets/privkey.pem ]] block).

Comment thread files/run_httpd.sh
http_flags+=(
--https-port "${PORT:-8443}"
--ssl-certificate-file /secrets/fullchain.pem
--ssl-certificate-key-file /secrets/privkey.pem

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[medium] fail-open

Silent fallback to plain HTTP (port 8080) when /secrets/privkey.pem is absent. Previously the server always attempted HTTPS and would fail if certificates were missing (fail-closed). This also affects the existing docker-compose deployment path — a misconfiguration could cause unencrypted traffic.

Suggested fix: Add an explicit warning log in the else branch. Consider restricting the HTTP fallback to dev/local deployments only (e.g., gating on DEPLOYMENT env var).

Comment thread files/recipe.yaml
vars:
home_path: "{{ lookup('env', 'HOME') }}"
packit_service_path: /src
editable_install: "{{ lookup('env', 'DEPLOYMENT') == 'dev' }}"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[low] build-time environment

editable_install reads DEPLOYMENT at Ansible execution time. The existing Dockerfile build path does not set this variable, so editable install only works via the new quadlet build path. Likely intentional but undocumented.

Comment thread files/run_httpd.sh
SERVER_NAME=$(sed -nr 's/^server_name: ([^:]+)(:([0-9]+))?$/\1/p' "$PACKIT_SERVICE_CONFIG")
HTTPS_PORT=$(sed -nr 's/^server_name: ([^:]+)(:([0-9]+))?$/\3/p' "$PACKIT_SERVICE_CONFIG")
PORT=$(sed -nr 's/^server_name: ([^:]+)(:([0-9]+))?$/\3/p' "$PACKIT_SERVICE_CONFIG")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[low] naming-convention

http_flags uses lowercase while all other substantive variables in the file use UPPER_CASE (ATTEMPTS, SERVER_NAME, PORT, PACKIT_SERVICE_CONFIG).

Comment thread files/recipe.yaml
vars:
home_path: "{{ lookup('env', 'HOME') }}"
packit_service_path: /src
editable_install: "{{ lookup('env', 'DEPLOYMENT') == 'dev' }}"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[low] scope-creep

Adding editable_install to the shared Ansible recipe couples the new quadlet workflow to the existing Dockerfile build pipeline. Existing behavior is preserved (DEPLOYMENT unset = non-editable), but the coupling is undocumented.

@fullsend-ai-review fullsend-ai-review Bot removed the ready-for-merge All reviewers approved — ready to merge label Aug 21, 2026
@fullsend-ai-review

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 6:41 AM UTC · Completed 7:00 AM UTC

Commit: ad641e2 · View workflow run →

@LecrisUT LecrisUT changed the title [WIP] Deploying packit-service via quadlets Deploying packit-service via quadlets Aug 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/deployment Related to the Packit's deployment

Projects

Development

Successfully merging this pull request may close these issues.

2 participants