|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +foremanctl is a deployment tool for Foreman and Katello using Podman quadlets and Ansible. It targets Foreman 3.18 with Katello 4.20, Pulp 3.85, and Candlepin 4.6 on CentOS Stream 9 with ansible-core 2.14. |
| 8 | + |
| 9 | +The project uses the [obsah](https://pypi.org/project/obsah/) CLI framework. Two main executables wrap obsah: |
| 10 | + |
| 11 | +- `./foremanctl` - production deployment tool (uses src/ directory) |
| 12 | +- `./forge` - development/testing tool (uses development/ directory) |
| 13 | + |
| 14 | +## Setup |
| 15 | + |
| 16 | +```bash |
| 17 | +./setup-environment # Creates virtualenv and installs dependencies |
| 18 | +source .venv/bin/activate # Activate the virtualenv |
| 19 | +``` |
| 20 | + |
| 21 | +This installs dependencies from `src/requirements.txt` and `development/requirements.txt`, and builds Ansible collections in `build/collections/`. |
| 22 | + |
| 23 | +## Common Commands |
| 24 | + |
| 25 | +### Deployment (Development) |
| 26 | + |
| 27 | +```bash |
| 28 | +./forge vms start # Start Vagrant VMs |
| 29 | +./foremanctl deploy --foreman-initial-admin-password=changeme --tuning development # Deploy Foreman |
| 30 | +./forge vms stop # Stop VMs |
| 31 | +``` |
| 32 | + |
| 33 | +### Optional Features |
| 34 | + |
| 35 | +```bash |
| 36 | +./forge setup-repositories # Setup repositories |
| 37 | +./foremanctl deploy --add-feature hammer # Deploy with hammer CLI |
| 38 | +./foremanctl features # List enabled and available features |
| 39 | +``` |
| 40 | + |
| 41 | +### Testing |
| 42 | + |
| 43 | +```bash |
| 44 | +./forge test # Run pytest-based integration tests (requires deployment) |
| 45 | +./forge smoker # Run smoker-based tests |
| 46 | +``` |
| 47 | + |
| 48 | +Test execution generates SSH config at `.tmp/ssh-config` and runs pytest with testinfra. Tests require an active deployment. Hammer tests require hammer to be deployed. |
| 49 | + |
| 50 | +To run specific tests or with custom pytest arguments, use: |
| 51 | + |
| 52 | +```bash |
| 53 | +./forge test -- -k test_name # Pass additional pytest arguments after -- |
| 54 | +``` |
| 55 | + |
| 56 | +### Linting |
| 57 | + |
| 58 | +```bash |
| 59 | +ansible-lint src/ # Lint production playbooks/roles |
| 60 | +ansible-lint development/ # Lint development playbooks/roles |
| 61 | +``` |
| 62 | + |
| 63 | +Configuration is in `.ansible-lint`. |
| 64 | + |
| 65 | +### Building |
| 66 | + |
| 67 | +```bash |
| 68 | +make dist # Create distribution tarball (foremanctl-VERSION.tar.gz) |
| 69 | +make clean-var # Clean .var directory |
| 70 | +``` |
| 71 | + |
| 72 | +## Architecture |
| 73 | + |
| 74 | +### Directory Structure |
| 75 | + |
| 76 | +- **src/** - Production Ansible content |
| 77 | + - **playbooks/** - Main playbooks organized by action (deploy, checks, pull-images, features, setup-*) |
| 78 | + - **roles/** - Ansible roles for each component (foreman, pulp, candlepin, postgresql, httpd, hammer, certificates, etc.) |
| 79 | + - **vars/** - Configuration variables |
| 80 | + - **flavors/** - Feature sets (e.g., katello.yml defines enabled features) |
| 81 | + - **tuning/** - Resource tuning profiles (development, default, medium, large, extra-large, extra-extra-large) |
| 82 | + - **base.yaml**, **database.yml**, **foreman.yml**, **images.yml** - Base configuration |
| 83 | + - **default_certificates.yml**, **installer_certificates.yml** - Certificate sources |
| 84 | + - **features.yaml** - Feature definitions with dependencies |
| 85 | + - **filter_plugins/**, **callback_plugins/** - Ansible plugins |
| 86 | + |
| 87 | +- **development/** - Development-specific Ansible content |
| 88 | + - **playbooks/** - Development playbooks (vms, test, smoker, setup-repositories, etc.) |
| 89 | + - **roles/** - Development-specific roles |
| 90 | + |
| 91 | +- **tests/** - pytest-based integration tests |
| 92 | + - Uses testinfra for infrastructure testing |
| 93 | + - Uses apypie for Foreman API testing |
| 94 | + - **conftest.py** - pytest fixtures for server, client, database connections, and Foreman API resources |
| 95 | + |
| 96 | +- **inventories/** - Ansible inventory files |
| 97 | + - **broker.py** - Dynamic inventory script |
| 98 | + |
| 99 | +- **build/collections/** - Built Ansible collections (generated, not committed) |
| 100 | + - **foremanctl/** - Production collections |
| 101 | + - **forge/** - Development collections |
| 102 | + |
| 103 | +### Core Components |
| 104 | + |
| 105 | +Each Ansible role manages a specific service/component: |
| 106 | + |
| 107 | +- **foreman** - Main Foreman application |
| 108 | +- **pulp** - Content management (RPM, Deb, Container, File repositories) |
| 109 | +- **candlepin** - Subscription management |
| 110 | +- **postgresql** - Database (internal mode only) |
| 111 | +- **httpd** - Web server/reverse proxy |
| 112 | +- **redis** - Cache |
| 113 | +- **foreman_proxy** - Smart proxy (optional feature) |
| 114 | +- **hammer** - CLI tool (optional feature) |
| 115 | +- **certificates** - SSL/TLS certificate management |
| 116 | + |
| 117 | +### Configuration as Podman Secrets |
| 118 | + |
| 119 | +Service configuration files are stored as Podman secrets and mounted into containers. |
| 120 | + |
| 121 | +Naming convention: |
| 122 | + |
| 123 | +- Config files: `<role_namespace>-<filename>-<extension>` or `<role_namespace>-<app>-<filename>-<extension>` |
| 124 | +- Strings: `<role_namespace>-<descriptive_name>` or `<role_namespace>-<app>-<descriptive_name>` |
| 125 | + |
| 126 | +Required labels: |
| 127 | + |
| 128 | +- Config files: `filename`, `app` |
| 129 | +- Strings: `app` |
| 130 | + |
| 131 | +Commands: |
| 132 | + |
| 133 | +```bash |
| 134 | +podman secret ls # List secrets |
| 135 | +podman secret inspect --showsecret --format "{{.SecretData}}" <name> # View secret content |
| 136 | +``` |
| 137 | + |
| 138 | +### Features System |
| 139 | + |
| 140 | +Features are defined in `src/features.yaml` and control which components are deployed. Each feature can specify: |
| 141 | + |
| 142 | +- **description** - Human-readable description |
| 143 | +- **foreman** - Foreman plugin configuration |
| 144 | +- **foreman_proxy** - Proxy plugin configuration |
| 145 | +- **hammer** - Hammer CLI plugin |
| 146 | +- **dependencies** - Required features |
| 147 | +- **internal** - Whether feature is user-facing or internal-only |
| 148 | + |
| 149 | +Flavors (in `src/vars/flavors/`) define preset feature sets. The katello flavor includes foreman, katello, and content management features (rpm, deb, container, ansible). |
| 150 | + |
| 151 | +### Deploy Playbook Flow |
| 152 | + |
| 153 | +The main deployment playbook (`src/playbooks/deploy/deploy.yaml`) executes roles in order: |
| 154 | + |
| 155 | +1. pre_install - Pre-installation tasks |
| 156 | +2. checks - System requirement validation |
| 157 | +3. certificates - Generate/configure certificates (if certificate_source == 'default') |
| 158 | +4. certificate_checks - Validate certificates |
| 159 | +5. postgresql - Database setup (if database_mode == 'internal') |
| 160 | +6. redis - Redis cache |
| 161 | +7. candlepin - Subscription management |
| 162 | +8. httpd - Web server |
| 163 | +9. pulp - Content management |
| 164 | +10. foreman - Main application |
| 165 | +11. systemd_target - Systemd target for service management |
| 166 | +12. foreman_proxy - Smart proxy (if 'foreman-proxy' in enabled_features) |
| 167 | +13. hammer - CLI (if 'hammer' in enabled_features) |
| 168 | +14. post_install - Post-installation tasks |
| 169 | + |
| 170 | +### Test Architecture |
| 171 | + |
| 172 | +Tests use pytest with fixtures defined in `tests/conftest.py`: |
| 173 | + |
| 174 | +- **server**, **client**, **database** - testinfra hosts via paramiko SSH |
| 175 | +- **foremanapi** - apypie ForemanApi client |
| 176 | +- **organization**, **product**, **yum_repository**, **file_repository**, **container_repository** - Foreman API resources (auto-created/cleaned) |
| 177 | +- **lifecycle_environment**, **content_view**, **activation_key** - Content management fixtures |
| 178 | + |
| 179 | +Tests connect to VMs using SSH config generated at `.tmp/ssh-config` from Ansible inventory. |
| 180 | + |
| 181 | +## Development Notes |
| 182 | + |
| 183 | +### obsah Framework |
| 184 | + |
| 185 | +Both `foremanctl` and `forge` are bash wrappers that configure environment variables and exec `obsah`. Key environment variables: |
| 186 | + |
| 187 | +- `OBSAH_NAME` - Tool name |
| 188 | +- `OBSAH_DATA` - Playbook directory (src/ or development/) |
| 189 | +- `OBSAH_INVENTORY` - Inventory directory |
| 190 | +- `OBSAH_STATE` - State directory (.var/lib/foremanctl) |
| 191 | +- `ANSIBLE_COLLECTIONS_PATH` - Collections path (build/collections/foremanctl or forge) |
| 192 | +- `ANSIBLE_LOG_PATH` - Log file location |
| 193 | + |
| 194 | +### Vagrant Development Environment |
| 195 | + |
| 196 | +The Vagrantfile defines VMs for testing. Use `./forge vms start` and `./forge vms stop` to manage them. |
| 197 | + |
| 198 | +### Running Single Tests |
| 199 | + |
| 200 | +```bash |
| 201 | +source .venv/bin/activate |
| 202 | +pytest tests/foreman_api_test.py::test_foreman_organization -vv |
| 203 | +pytest tests/ -k "repository" -vv |
| 204 | +``` |
| 205 | + |
| 206 | +Ensure deployment is active before running tests. |
0 commit comments