Convert Podman Quadlet deployment from rootful to rootless (rebased) - #12
Open
pablomh wants to merge 43 commits into
Open
Convert Podman Quadlet deployment from rootful to rootless (rebased)#12pablomh wants to merge 43 commits into
pablomh wants to merge 43 commits into
Conversation
pablomh
force-pushed
the
rootless_rebase
branch
21 times, most recently
from
March 26, 2026 12:28
3db50fb to
0c156cf
Compare
pablomh
force-pushed
the
rootless_rebase
branch
2 times, most recently
from
March 26, 2026 22:34
bf89edc to
cea2b0f
Compare
Signed-off-by: Eric D. Helms <ericdhelms@gmail.com>
pablomh
force-pushed
the
rootless_rebase
branch
7 times, most recently
from
April 22, 2026 21:00
4a98db9 to
db2d934
Compare
Adds helpers to conftest.py that delegate to `foremanctl service`, making all test assertions go through the operational tool: - service_is_running(server, name) — foremanctl service status - service_is_enabled(server, name) — systemctl --user is-enabled - service_exists(server, name) — systemctl --user status (rc != 4) - service_start/stop/restart(server, name) - foremanctl_run(server, cmd) — run as foremanctl user - foremanctl_exec(server, ctr, cmd)— foremanctl service exec Also adds foremanctl_service_test.py which tests the tool itself: help output, status, brief mode, startup order, ps, unknown subcommand, and exec. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Replaces server.service() and raw podman/systemctl calls with the new test helpers that delegate to foremanctl service. Tests now exercise the operational tool at the same time as verifying service state. - service_is_running() replaces server.service().is_running - service_is_enabled()/service_exists() for enable/existence checks - service_start/stop/restart() in target_lifecycle_test - foremanctl_exec() replaces raw podman exec invocations - Port reachability tests kept where ports are published to loopback Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Creates the foremanctl system user that owns all containerized services in rootless mode: - Creates foremanctl group and user (home /var/lib/foremanctl, no login) - Derives XDG_RUNTIME_DIR from the user's actual UID - Writes subuid/subgid entries (100000:65536) for user namespace mapping - Sets net.ipv4.ip_unprivileged_port_start=80 via sysctl - Enables systemd lingering so services survive without an active session - Verifies XDG_RUNTIME_DIR exists (fails fast if lingering didn't work - Creates ~/.config/containers/systemd and ~/.config/systemd/user dirs Exposes rootless_user_xdg_runtime_dir fact for the deploy playbook to map into the foremanctl namespace. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com> EOF )
Reusable role that creates named Podman bridge networks in the foremanctl user namespace. Called multiple times from the deploy playbook with different parameters to create the tiered network topology (foreman-db, foreman-cache, foreman-app, foreman-proxy-net). Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Play 1 sets up the rootless foremanctl user and derives foremanctl_xdg_runtime_dir before vars_files are loaded. Play 2 deploys all services, now with four bridge networks replacing host networking: foreman-db (internal, isolated) — postgresql only foreman-cache (internal, isolated) — redis only foreman-app (bridge) — foreman, pulp, candlepin foreman-proxy-net (bridge) — foreman-proxy, iop-gateway base.yaml gains foremanctl_* vars and foremanctl_runtime_env. database.yml changes database_host from localhost to the postgresql container DNS name. default_certificates.yml changes the cert directory from /root/certificates to /var/lib/foremanctl/certificates. pull-images.yaml follows the same two-play split so images are pulled in the foremanctl Podman namespace. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
- Image updated to postgresql-16-c10s (PG16 defaults to scram-sha-256) - All podman/systemd operations wrapped in become_user: foremanctl block - Socket dir mounted at /tmp/socket to avoid sclorg entrypoint corruption - unix_socket_directories configured post-startup for community.postgresql - POSTGRESQL_LISTEN_ADDRESSES=* for bridge-networked TCP clients - Network changed from host to foreman-db (internal, isolated) - Handler updated with become_user and scope: user Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
- All operations in a single become_user: foremanctl block including podman unshare chown for container UID 1001 - Network changed from host to foreman-cache (internal, isolated) - Systemd operations use scope: user Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
- Keystore/truststore paths moved to /var/lib/foremanctl/ - certs.yml/artemis.yml: root ops remain root, podman_secret calls grouped into become_user blocks - Network changed from host to foreman-app; hostname set to candlepin - Port 23443 published to 127.0.0.1 for httpd proxy access - Handler updated with become_user and scope: user Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
- All operations in a single become_user: foremanctl block - Networks: foreman-app, foreman-db, foreman-cache - PULP_REDIS_URL changed to redis://redis (container DNS) - Ports 24817/24816 published to 127.0.0.1 for httpd - Worker symlinks and pulp-worker.target moved to foremanctl dirs - Worker cleanup uses find on quadlet dir instead of service_facts - Handlers updated with become_user and scope: user Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
- All operations in a single become_user: foremanctl block - Networks: foreman-app, foreman-db, foreman-cache, foreman-proxy-net - Port 3000 published to 127.0.0.1 for httpd proxy - DYNFLOW_REDIS_URL changed to redis://redis (container DNS) - Dynflow symlinks and recurring timers moved to foremanctl dirs - Handlers updated with become_user and scope: user Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Moves foreman.target from /etc/systemd/system/ to the foremanctl user's ~/.config/systemd/user/ directory. All operations use become_user: foremanctl with scope: user. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
- All container/secret/systemd operations in become_user blocks - Network changed from host to foreman-proxy-net - Port 8443 published externally for managed host connectivity - container.d drop-in path moved to foremanctl_quadlet_dir - remote_execution_ssh: SSH keypair generated inside foremanctl block - Handlers updated with become_user and scope: user Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
- Default cert directory changed from /root/certificates to /var/lib/foremanctl/certificates (also updated in default_certificates.yml) - Directory creation tasks set owner/group to foremanctl - Final recursive chown in main.yml covers all files generated by openssl commands that run as root Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
The role now checks /etc/subuid and /etc/subgid for the foremanctl user (set up by the rootless_user role) rather than the deploying user. Adds defaults/main.yaml with rootless_user_name: foremanctl so the variable is available when called from Play 2. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
- Adds acl package (required for Ansible become_user with unprivileged users) - Adds fapolicyd rule when fapolicyd is active: allows Ansible become_user to copy Python modules to /var/tmp/ (RHEL-37912) Rule: allow perm=open exe=/usr/bin/python3 : dir=/var/tmp/ ftype=text/x-python Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
- Replace iop_network role with deploy_network (internal, isolated) - Wrap all container/systemd operations in become_user: foremanctl blocks - Add scope: user to all systemd tasks and handlers - Gateway uses dedicated iop-core-gateway certificates instead of localhost - Gateway connects via container DNS on foreman-proxy-net (no host port) - IOP inventory frontend uses rootless podman for image pull and extraction - Remove per-role _registry_auth_file vars (foremanctl_runtime_env handles it) Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
- Convert all IOP test files to use rootless helpers (service_is_running, foremanctl_run, container_exec, SYSTEMCTL_USER) - Update quadlet file paths to rootless user directory - Fix frontend asset paths to match role defaults - Fix timer paths to user systemd directory - Test gateway port via bridge network (not published to localhost) - Fix systemctl stop in upgrade workflow for rootless user scope Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
pablomh
force-pushed
the
rootless_rebase
branch
4 times, most recently
from
April 26, 2026 16:44
9aec640 to
9fa4f12
Compare
Reverting foreman-proxy back to foreman-proxy-net to isolate whether the network name collision with the container name causes REX failures in rootless mode. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
pablomh
force-pushed
the
rootless_rebase
branch
from
April 26, 2026 20:47
9fa4f12 to
7c4b9e2
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Rebase of the rootless conversion commit on top of current origin/master.