[bodhi2] Add script to make flatpak repos public #3412

Merged
zlopez merged 1 commit from zlopez/ansible:11543 into main 2026-06-24 08:01:53 +00:00
Owner

The repos created through docker push are created as private by default.
This script will run every hour and sets any private repo visibility to
public.

This should be next step to finish
infra/tickets#11543

Signed-off-by: Michal Konecny mkonecny@redhat.com

The repos created through docker push are created as private by default. This script will run every hour and sets any private repo visibility to public. This should be next step to finish https://forge.fedoraproject.org/infra/tickets/issues/11543 Signed-off-by: Michal Konecny <mkonecny@redhat.com>
[bodhi2] Add script to make flatpak repos public
Some checks failed
Linter / yamllint (pull_request) Successful in 29s
AI Code Review / ai-review (pull_request_target) Successful in 31s
Linter / ansible-lint (pull_request) Failing after 1m7s
c5f24b101f
The repos created through docker push are created as private by default.
This script will run every hour and sets any private repo visibility to
public.

This should be next step to finish
infra/tickets#11543

Signed-off-by: Michal Konecny <mkonecny@redhat.com>

AI Code Review

Detailed Code Review

The implementation correctly targets the issue of repositories defaulting to private on push. However, there is a critical Jinja2 syntax error in the cron template that will prevent authentication from working properly. Additionally, the Python script lacks necessary safeguards against API failures and hanging network connections, which are important for scripts running unattended via cron.

📂 File Reviews

📄 `roles/bodhi2/backend/files/flatpak_quayio_repo_publisher.py` - A Python script that fetches private repositories from Quay.io and changes their visibility to public.
  • Major [Bug]: If the Quay.io API returns a non-200 response (e.g., 500 Internal Server Error), the script prints an error but immediately attempts to parse the response as JSON. This will likely raise a JSONDecodeError and crash the script unexpectedly.
    • Suggestion: Raise an exception or return early when encountering an unexpected HTTP status code.
        if response.status_code != 200:
            print(f"Couldn't reach {url}. Status code: {response.status_code}")
            print(response.text)
            response.raise_for_status() # Stop execution on failure
  • Minor [Performance]: Network requests lack a timeout parameter. In an automated cron environment, a hanging network connection can cause the script to run indefinitely, potentially leading to overlapping executions and resource exhaustion.
    • Suggestion: Add a timeout parameter to all requests.get and requests.post calls.
        response = requests.get(url, headers=header, params=params, timeout=30)
📄 `roles/bodhi2/backend/templates/flatpak_quayio_repo_publisher.cron.j2` - Jinja2 template defining the cron job for the publisher script.
  • Critical [Bug]: The template uses single curly braces {variable} for the OAuth tokens instead of Ansible's Jinja2 standard double curly braces {{ variable }}. This will result in the literal string '{bodhi2_quayio_oauth}' being passed to the script rather than the actual token.
    • Suggestion: Replace {} with {{ }} for variable evaluation.
MAILTO=root@fedoraproject.org
{% if env == "staging" %}
0 * * * * QUAYIO_NAMESPACE=fedora-flatpaks-staging QUAYIO_OAUTH_TOKEN={{ bodhi2_quayio_oauth_stg }} /usr/local/bin/flatpak_quayio_repo_publisher.py
{% else %}
0 * * * * QUAYIO_NAMESPACE=fedora-flatpaks QUAYIO_OAUTH_TOKEN={{ bodhi2_quayio_oauth }} /usr/local/bin/flatpak_quayio_repo_publisher.py
{% endif %}

Summary

  • Overall Assessment: The review identified a critical templating bug that will prevent script execution, alongside major missing error handling in the Python script. These issues must be resolved before deployment.
  • Priority Issues:
    • Fix Jinja2 templating syntax for OAuth tokens in flatpak_quayio_repo_publisher.cron.j2 by using {{ }} instead of {}.
    • Handle non-200 HTTP responses in get_private_repos properly to prevent JSONDecodeError exceptions during execution.
  • Minor Suggestions:
    • Add strict timeouts to requests.get() and requests.post() in the Python script to prevent process hanging.

🤖 AI Code Review | Generated with ai-code-review | Model: gemini-3.1-pro-preview

⚠️ AI-generated suggestions may be incorrect. Verify before applying. Not a replacement for human review.

## AI Code Review ### Detailed Code Review The implementation correctly targets the issue of repositories defaulting to private on push. However, there is a critical Jinja2 syntax error in the cron template that will prevent authentication from working properly. Additionally, the Python script lacks necessary safeguards against API failures and hanging network connections, which are important for scripts running unattended via cron. #### 📂 File Reviews <details> <summary><strong>📄 `roles/bodhi2/backend/files/flatpak_quayio_repo_publisher.py`</strong> - A Python script that fetches private repositories from Quay.io and changes their visibility to public.</summary> - **Major** [Bug]: If the Quay.io API returns a non-200 response (e.g., 500 Internal Server Error), the script prints an error but immediately attempts to parse the response as JSON. This will likely raise a `JSONDecodeError` and crash the script unexpectedly. - *Suggestion:* Raise an exception or return early when encountering an unexpected HTTP status code. ```` if response.status_code != 200: print(f"Couldn't reach {url}. Status code: {response.status_code}") print(response.text) response.raise_for_status() # Stop execution on failure ```` - **Minor** [Performance]: Network requests lack a `timeout` parameter. In an automated cron environment, a hanging network connection can cause the script to run indefinitely, potentially leading to overlapping executions and resource exhaustion. - *Suggestion:* Add a timeout parameter to all `requests.get` and `requests.post` calls. ```` response = requests.get(url, headers=header, params=params, timeout=30) ```` </details> <details> <summary><strong>📄 `roles/bodhi2/backend/templates/flatpak_quayio_repo_publisher.cron.j2`</strong> - Jinja2 template defining the cron job for the publisher script.</summary> - **Critical** [Bug]: The template uses single curly braces `{variable}` for the OAuth tokens instead of Ansible's Jinja2 standard double curly braces `{{ variable }}`. This will result in the literal string '{bodhi2_quayio_oauth}' being passed to the script rather than the actual token. - *Suggestion:* Replace `{}` with `{{ }}` for variable evaluation. ```` MAILTO=root@fedoraproject.org {% if env == "staging" %} 0 * * * * QUAYIO_NAMESPACE=fedora-flatpaks-staging QUAYIO_OAUTH_TOKEN={{ bodhi2_quayio_oauth_stg }} /usr/local/bin/flatpak_quayio_repo_publisher.py {% else %} 0 * * * * QUAYIO_NAMESPACE=fedora-flatpaks QUAYIO_OAUTH_TOKEN={{ bodhi2_quayio_oauth }} /usr/local/bin/flatpak_quayio_repo_publisher.py {% endif %} ```` </details> ### ✅ Summary - **Overall Assessment:** The review identified a critical templating bug that will prevent script execution, alongside major missing error handling in the Python script. These issues must be resolved before deployment. - **Priority Issues:** - Fix Jinja2 templating syntax for OAuth tokens in `flatpak_quayio_repo_publisher.cron.j2` by using `{{ }}` instead of `{}`. - Handle non-200 HTTP responses in `get_private_repos` properly to prevent `JSONDecodeError` exceptions during execution. - **Minor Suggestions:** - Add strict timeouts to `requests.get()` and `requests.post()` in the Python script to prevent process hanging. --- 🤖 **AI Code Review** | Generated with [ai-code-review](https://gitlab.com/redhat/edge/ci-cd/ai-code-review) | **Model:** `gemini-3.1-pro-preview` ⚠️ *AI-generated suggestions may be incorrect. Verify before applying. Not a replacement for human review.*
zlopez force-pushed 11543 from c5f24b101f
Some checks failed
Linter / yamllint (pull_request) Successful in 29s
AI Code Review / ai-review (pull_request_target) Successful in 31s
Linter / ansible-lint (pull_request) Failing after 1m7s
to 70db1df8bd
Some checks failed
Linter / yamllint (pull_request) Successful in 33s
AI Code Review / ai-review (pull_request_target) Successful in 25s
Linter / ansible-lint (pull_request) Failing after 1m25s
2026-06-12 13:31:35 +00:00
Compare

AI Code Review

Detailed Code Review

The merge request implements a straightforward Python script and accompanying Ansible tasks to automate the visibility of Quay.io repositories. The logic for interacting with the Quay.io API is sound and handles pagination correctly.

However, there is a critical issue in the system cron job configuration. Files placed in /etc/cron.d/ require a username field before the command, which is currently missing. Without this, the cron daemon will fail to execute the script. Additionally, it is highly recommended to add basic timeout parameters to the network requests in the Python script to prevent the cron job from hanging indefinitely if the Quay API is unresponsive.

📂 File Reviews

📄 `roles/bodhi2/backend/templates/flatpak_quayio_repo_publisher.cron.j2` - Adds a template for the cron job that runs the publisher script hourly.
  • Critical [Bug]: Cron files placed in /etc/cron.d/ require a username field (e.g., root or bodhi) between the time specification and the command. Without it, cron will interpret QUAYIO_NAMESPACE... as the username and fail to execute.
    • Suggestion: Add the executing user (likely root or bodhi) after the time schedule.
MAILTO=root@fedoraproject.org
{% if env == "staging" %}
0 * * * * root QUAYIO_NAMESPACE=fedora-flatpaks-staging QUAYIO_OAUTH_TOKEN={{ bodhi2_quayio_oauth_stg }} /usr/local/bin/flatpak_quayio_repo_publisher.py
{% else %}
0 * * * * root QUAYIO_NAMESPACE=fedora-flatpaks QUAYIO_OAUTH_TOKEN={{ bodhi2_quayio_oauth }} /usr/local/bin/flatpak_quayio_repo_publisher.py
{% endif %}

📄 `roles/bodhi2/backend/files/flatpak_quayio_repo_publisher.py` - Python script to interact with the Quay.io API to fetch private repositories and change their visibility to public.
  • Major [Performance]: The requests.get and requests.post calls are missing timeout arguments. In a cron job, if the remote server becomes unresponsive, the script will hang indefinitely instead of timing out, potentially leading to overlapping overlapping cron executions.
    • Suggestion: Add a sensible timeout (e.g., 10-30 seconds) to all requests calls.
        response = requests.get(url, headers=header, params=params, timeout=30)

# ... and in set_repo_public ...

    response = requests.post(
        url,
        headers=header,
        json=data,
        timeout=30
    )

Summary

  • Overall Assessment: The core logic is correct, but a critical syntax error in the cron configuration will prevent execution. Please fix the cron file syntax and add timeouts to the network requests before merging.

🤖 AI Code Review | Generated with ai-code-review | Model: gemini-3.1-pro-preview

⚠️ AI-generated suggestions may be incorrect. Verify before applying. Not a replacement for human review.

## AI Code Review ### Detailed Code Review The merge request implements a straightforward Python script and accompanying Ansible tasks to automate the visibility of Quay.io repositories. The logic for interacting with the Quay.io API is sound and handles pagination correctly. However, there is a critical issue in the system cron job configuration. Files placed in `/etc/cron.d/` require a username field before the command, which is currently missing. Without this, the cron daemon will fail to execute the script. Additionally, it is highly recommended to add basic timeout parameters to the network requests in the Python script to prevent the cron job from hanging indefinitely if the Quay API is unresponsive. #### 📂 File Reviews <details> <summary><strong>📄 `roles/bodhi2/backend/templates/flatpak_quayio_repo_publisher.cron.j2`</strong> - Adds a template for the cron job that runs the publisher script hourly.</summary> - **Critical** [Bug]: Cron files placed in `/etc/cron.d/` require a username field (e.g., `root` or `bodhi`) between the time specification and the command. Without it, cron will interpret `QUAYIO_NAMESPACE...` as the username and fail to execute. - *Suggestion:* Add the executing user (likely `root` or `bodhi`) after the time schedule. ```` MAILTO=root@fedoraproject.org {% if env == "staging" %} 0 * * * * root QUAYIO_NAMESPACE=fedora-flatpaks-staging QUAYIO_OAUTH_TOKEN={{ bodhi2_quayio_oauth_stg }} /usr/local/bin/flatpak_quayio_repo_publisher.py {% else %} 0 * * * * root QUAYIO_NAMESPACE=fedora-flatpaks QUAYIO_OAUTH_TOKEN={{ bodhi2_quayio_oauth }} /usr/local/bin/flatpak_quayio_repo_publisher.py {% endif %} ```` </details> <details> <summary><strong>📄 `roles/bodhi2/backend/files/flatpak_quayio_repo_publisher.py`</strong> - Python script to interact with the Quay.io API to fetch private repositories and change their visibility to public.</summary> - **Major** [Performance]: The `requests.get` and `requests.post` calls are missing timeout arguments. In a cron job, if the remote server becomes unresponsive, the script will hang indefinitely instead of timing out, potentially leading to overlapping overlapping cron executions. - *Suggestion:* Add a sensible timeout (e.g., 10-30 seconds) to all `requests` calls. ```` response = requests.get(url, headers=header, params=params, timeout=30) # ... and in set_repo_public ... response = requests.post( url, headers=header, json=data, timeout=30 ) ```` </details> ### ✅ Summary - **Overall Assessment:** The core logic is correct, but a critical syntax error in the cron configuration will prevent execution. Please fix the cron file syntax and add timeouts to the network requests before merging. --- 🤖 **AI Code Review** | Generated with [ai-code-review](https://gitlab.com/redhat/edge/ci-cd/ai-code-review) | **Model:** `gemini-3.1-pro-preview` ⚠️ *AI-generated suggestions may be incorrect. Verify before applying. Not a replacement for human review.*
zlopez force-pushed 11543 from 70db1df8bd
Some checks failed
Linter / yamllint (pull_request) Successful in 33s
AI Code Review / ai-review (pull_request_target) Successful in 25s
Linter / ansible-lint (pull_request) Failing after 1m25s
to 9bd7038f46
Some checks failed
Linter / yamllint (pull_request) Successful in 29s
Linter / ansible-lint (pull_request) Failing after 1m7s
2026-06-12 13:37:00 +00:00
Compare
zlopez force-pushed 11543 from 9bd7038f46
Some checks failed
Linter / yamllint (pull_request) Successful in 29s
Linter / ansible-lint (pull_request) Failing after 1m7s
to 05ac1a1e77
Some checks failed
Linter / yamllint (pull_request) Successful in 48s
Linter / ansible-lint (pull_request) Failing after 1m24s
2026-06-24 07:56:50 +00:00
Compare
zlopez merged commit 05ac1a1e77 into main 2026-06-24 08:01:53 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
infra/ansible!3412
No description provided.