Skip to content

Commit 548b173

Browse files
ehelmsevgeni
authored andcommitted
Add development workflow with source on vm
Signed-off-by: Eric D. Helms <ericdhelms@gmail.com>
1 parent 307117f commit 548b173

File tree

18 files changed

+865
-27
lines changed

18 files changed

+865
-27
lines changed

.github/workflows/devel.yml

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
---
2+
name: Devel Test
3+
4+
on:
5+
push:
6+
branches:
7+
- master
8+
paths-ignore:
9+
- 'container-images/**'
10+
- '.github/workflows/container.yml'
11+
- 'docs/**'
12+
pull_request:
13+
paths-ignore:
14+
- 'container-images/**'
15+
- '.github/workflows/container.yml'
16+
- 'docs/**'
17+
18+
19+
concurrency:
20+
group: ${{ github.ref_name }}-${{ github.workflow }}
21+
cancel-in-progress: true
22+
23+
jobs:
24+
tests:
25+
strategy:
26+
fail-fast: false
27+
matrix:
28+
certificate_source:
29+
- default
30+
runs-on: ubuntu-24.04
31+
steps:
32+
- uses: actions/checkout@v5
33+
- name: Set up Python
34+
uses: actions/setup-python@v6
35+
with:
36+
python-version: '3.12'
37+
- name: Setup libvirt for Vagrant
38+
run: |
39+
sudo add-apt-repository --yes ppa:evgeni/vagrant
40+
sudo apt-get update
41+
sudo apt-get install -y --no-install-recommends vagrant vagrant-libvirt libvirt-clients libvirt-daemon-system libvirt-daemon qemu-system-x86 qemu-utils dnsmasq
42+
sudo chmod 666 /var/run/libvirt/libvirt-sock
43+
- name: Install Ansible
44+
run: pip install --upgrade ansible-core
45+
- name: Setup environment
46+
run: ./setup-environment
47+
- name: Start VMs
48+
run: |
49+
./forge vms start
50+
- name: Configure repositories
51+
run: |
52+
./forge setup-repositories
53+
- name: Run deployment
54+
run: |
55+
./forge deploy-dev
56+
- name: Setup upterm session
57+
if: ${{ failure() }}
58+
uses: owenthereal/action-upterm@v1
59+
with:
60+
## limits ssh access and adds the ssh public key for the user which triggered the workflow
61+
limit-access-to-actor: true
62+
## If no one connects after 5 minutes, shut down server.
63+
wait-timeout-minutes: 5

CLAUDE.md

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
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 Foreman and Katello deployment tool using Podman quadlets and Ansible. It supports Foreman 3.16, Katello 4.18, Pulp 3.73, and Candlepin 4.6, targeting ansible-core 2.14 as present in CentOS Stream 9.
8+
9+
## Development Environment Setup
10+
11+
Initialize the development environment:
12+
```bash
13+
./setup-environment
14+
source .venv/bin/activate
15+
```
16+
17+
This creates a Python virtual environment and installs dependencies from `src/requirements.txt` and `development/requirements.txt`, then builds Ansible collections for both production (`foremanctl`) and development (`forge`) use.
18+
19+
## Core Architecture
20+
21+
### CLI Tools
22+
- `./foremanctl` - Production deployment tool using obsah with production Ansible collections
23+
- `./forge` - Development/testing tool using obsah with development Ansible collections
24+
25+
Both tools are bash wrappers around the `obsah` CLI tool that set environment variables:
26+
- `OBSAH_NAME` - Tool identifier
27+
- `OBSAH_DATA` - Ansible data directory (`src` for foremanctl, `development` for forge)
28+
- `OBSAH_INVENTORY` - Ansible inventory path
29+
- `OBSAH_STATE` - State persistence directory
30+
- `ANSIBLE_COLLECTIONS_PATH` - Path to built collections
31+
32+
### Directory Structure
33+
- `src/` - Production Ansible roles, playbooks, and configurations
34+
- `development/` - Development-specific Ansible configurations
35+
- `tests/` - pytest-based test suite with testinfra integration
36+
- `inventories/` - Ansible inventory configurations
37+
- `build/collections/` - Built Ansible collections (generated)
38+
39+
### Ansible Roles
40+
Key roles in `src/roles/`:
41+
- `certificates` - Certificate management and issuance
42+
- `foreman` - Foreman application deployment
43+
- `candlepin` - Candlepin subscription management
44+
- `pulp` - Pulp content management
45+
- `postgresql` - Database setup
46+
- `httpd` - Web server configuration
47+
- `redis` - Redis cache configuration
48+
- `hammer` - Hammer CLI setup
49+
50+
## Common Development Tasks
51+
52+
### VM-based Development and Testing
53+
```bash
54+
# Start development environment
55+
./forge vms start
56+
57+
# Deploy Foreman with default settings
58+
./foremanctl deploy --foreman-initial-admin-password=changeme
59+
60+
# Setup hammer CLI (optional)
61+
./forge setup-repositories
62+
./foremanctl setup-hammer
63+
64+
# Run all tests
65+
./forge test
66+
67+
# Stop environment
68+
./forge vms stop
69+
```
70+
71+
### Building and Collections
72+
```bash
73+
# Build production collections
74+
make build/collections/foremanctl
75+
76+
# Build development collections
77+
make build/collections/forge
78+
79+
# Create distribution tarball
80+
make dist
81+
```
82+
83+
### Testing
84+
Tests use pytest with testinfra for infrastructure testing and apypie for Foreman API testing. Test configuration is in `tests/conftest.py` with fixtures for:
85+
- Server and client connection via Vagrant SSH
86+
- Foreman API client with authentication
87+
- Certificate management (default vs installer certificates)
88+
- Katello entities (organizations, products, repositories, content views, etc.)
89+
90+
Run individual test files:
91+
```bash
92+
# Run specific test module
93+
pytest tests/foreman_test.py
94+
95+
# Run with specific certificate source
96+
pytest --certificate-source=installer tests/
97+
```
98+
99+
## Configuration Management
100+
101+
### Service Configuration
102+
Services use Podman secrets for configuration files, following naming conventions:
103+
- Config files: `<role_namespace>-<filename>-<extension>`
104+
- Strings: `<role_namespace>-<descriptive_name>`
105+
- With app context: `<role_namespace>-<app>-<filename>-<extension>`
106+
107+
View configurations:
108+
```bash
109+
# List all secrets
110+
podman secret ls
111+
112+
# View specific secret
113+
podman secret inspect --showsecret --format "{{.SecretData}}" <secret-name>
114+
```
115+
116+
### Ansible Collections
117+
Production requirements in `src/requirements.yml`:
118+
- `community.postgresql` - PostgreSQL management
119+
- `community.crypto` - Certificate management
120+
- `ansible.posix` - POSIX utilities
121+
- `containers.podman` - Podman container management
122+
- `theforeman.foreman` - Foreman-specific modules
123+
124+
Development requirements in `development/requirements.yml` include additional collections for testing and VM management.
125+
126+
## Package Management
127+
128+
RPM packages available via COPR:
129+
```bash
130+
dnf copr enable @theforeman/foremanctl rhel-9-x86_64
131+
dnf install foremanctl
132+
```
133+
134+
## Important Notes
135+
136+
- Uses Vagrant with libvirt provider for VM-based development
137+
- All Ansible configuration managed through obsah CLI wrapper
138+
- State persistence handled automatically via `OBSAH_STATE` directory
139+
- Test fixtures create temporary Katello entities that are cleaned up automatically
140+
- Certificate management supports both default and installer-provided certificates

development/ansible.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
host_key_checking = False
33
stdout_callback=debug
44
stderr_callback=debug
5-
roles_path = ~/.ansible/roles:./roles
5+
roles_path = ~/.ansible/roles:./roles:../src/roles
66
display_skipped_hosts = no
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
---
2+
- name: Deploy Foreman Development Environment
3+
hosts: "{{ target_host if target_host is defined and target_host != '' else 'quadlet' }}"
4+
become: true
5+
vars_files:
6+
- "../../../src/vars/defaults.yml"
7+
- "../../../src/vars/{{ certificate_source }}_certificates.yml"
8+
- "../../../src/vars/images.yml"
9+
- "../../../src/vars/database.yml"
10+
- "../../../src/vars/foreman.yml"
11+
- "../../../src/vars/base.yaml"
12+
vars:
13+
httpd_foreman_backend: "http://localhost:3000"
14+
roles:
15+
- pre_install
16+
- role: certificates
17+
- role: postgresql
18+
vars:
19+
postgresql_databases:
20+
- name: "{{ candlepin_database_name }}"
21+
owner: "{{ candlepin_database_user }}"
22+
- name: "foreman_development"
23+
owner: "{{ foreman_database_user }}"
24+
- name: "foreman_development_test"
25+
owner: "{{ foreman_database_user }}"
26+
- name: "{{ pulp_database_name }}"
27+
owner: "{{ pulp_database_user }}"
28+
postgresql_users:
29+
- name: "{{ candlepin_database_name }}"
30+
password: "{{ candlepin_database_password }}"
31+
- name: "{{ foreman_database_name }}"
32+
password: "{{ foreman_database_password }}"
33+
- name: "{{ pulp_database_name }}"
34+
password: "{{ pulp_database_password }}"
35+
- role: redis
36+
- role: candlepin
37+
- role: httpd
38+
- role: pulp
39+
- role: foreman_development
40+
post_tasks:
41+
- name: Display development environment information
42+
ansible.builtin.debug:
43+
msg: |
44+
Foreman development environment deployed successfully!
45+
46+
Access URLs:
47+
- Foreman UI: https://{{ ansible_fqdn }}
48+
- Direct Rails: http://localhost:3000 (when running)
49+
50+
Credentials:
51+
- Username: {{ foreman_development_admin_user | default('admin') }}
52+
- Password: {{ foreman_development_admin_password | default('changeme') }}
53+
54+
Next steps:
55+
- SSH into the VM
56+
- Navigate to /home/{{ foreman_development_user }}/foreman
57+
- Run: bundle exec foreman start
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
help: |
3+
Deploy and manage Foreman development environment with git-based Foreman and containerized backend services.
4+
5+
variables:
6+
foreman_development_enabled_plugins:
7+
help: List of plugins to enable from registry (comma-separated)
8+
default: katello,foreman_remote_execution
9+
target_host:
10+
help: Target hostname or IP address for deployment
11+
action: store
12+
foreman_development_user:
13+
help: Username for the development user account
14+
action: store

development/requirements.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
---
22
collections:
33
- ansible.posix
4+
- community.crypto
5+
- community.postgresql
46
- community.general
7+
- name: containers.podman
8+
version: ">=1.16.4"
59
- name: https://github.com/theforeman/forklift
610
type: git
11+
- name: theforeman.foreman
712
- name: theforeman.operations
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
---
2+
foreman_development_user: "vagrant"
3+
foreman_development_group: "{{ foreman_development_user }}"
4+
foreman_development_deployment_dir: "/home/{{ foreman_development_user }}"
5+
foreman_development_foreman_dir: "{{ foreman_development_deployment_dir }}/foreman"
6+
foreman_development_cert_dir: "{{ foreman_development_deployment_dir }}/foreman-certs"
7+
8+
foreman_development_ca_certificate: "{{ foreman_ca_certificate }}"
9+
foreman_development_client_certificate: "{{ foreman_client_certificate }}"
10+
foreman_development_client_key: "{{ foreman_client_key }}"
11+
12+
foreman_development_admin_user: "admin"
13+
foreman_development_admin_password: "changeme"
14+
15+
foreman_development_git_repo: "https://github.com/theforeman/foreman.git"
16+
foreman_development_git_revision: "develop"
17+
18+
foreman_development_rails_port: 3000
19+
foreman_development_rails_command: "puma -w 2 -p {{ foreman_development_rails_port }} --preload"
20+
21+
foreman_development_database_host: "localhost"
22+
foreman_development_database_port: 5432
23+
foreman_development_database_name: "foreman_development"
24+
foreman_development_database_user: "foreman"
25+
foreman_development_database_password: "foreman"
26+
27+
foreman_development_nodejs_stream: "22"
28+
29+
foreman_development_plugin_registry:
30+
katello:
31+
name: "katello/katello"
32+
settings_template: "katello.yaml.j2"
33+
scm_revision: "master"
34+
manage_repo: true
35+
extra_gemfiles:
36+
- "gemfile.d/test.rb"
37+
foreman_remote_execution:
38+
name: "theforeman/foreman_remote_execution"
39+
scm_revision: "master"
40+
manage_repo: true
41+
foreman_ansible:
42+
name: "theforeman/foreman_ansible"
43+
settings_template: "foreman_ansible.yaml.j2"
44+
scm_revision: "master"
45+
manage_repo: true
46+
foreman_rh_cloud:
47+
name: "RedHatInsights/foreman_rh_cloud"
48+
scm_revision: "master"
49+
manage_repo: true
50+
foreman_discovery:
51+
name: "theforeman/foreman_discovery"
52+
scm_revision: "master"
53+
manage_repo: true
54+
foreman_openscap:
55+
name: "theforeman/foreman_openscap"
56+
scm_revision: "master"
57+
manage_repo: true
58+
foreman_bootdisk:
59+
name: "theforeman/foreman_bootdisk"
60+
scm_revision: "master"
61+
manage_repo: true
62+
63+
foreman_development_enabled_plugins:
64+
- katello
65+
- foreman_remote_execution
66+
67+
foreman_development_packages:
68+
- git
69+
- ruby-devel
70+
- npm
71+
- postgresql-devel
72+
- libxml2-devel
73+
- libxslt-devel
74+
- libcurl-devel
75+
- gcc-c++
76+
- make
77+
- rubygem-bundler
78+
- rubygem-irb
79+
- postgresql

0 commit comments

Comments
 (0)