Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
160 changes: 160 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
# s2i-openstack-containers — Contributor Orientation

> For detailed technical reference — build workflow, dependency files, tooling, and
> step-by-step instructions for adding a service — see `README.md`.

## What This Is

This is where the source-to-container work happens. This repo contains the packaging
definitions for OpenStack service containers, built using the Source-to-Image (S2I)
approach — each service is built directly from its upstream Python source rather than
from RPMs.

Container definitions are organized by component group: each upstream service group gets
its own directory under `containers/`, with individual image definitions as
subdirectories within it. For example, `containers/cyborg/` is the group;
`containers/cyborg/cyborg/` and `containers/cyborg/cyborg-agent/` are the individual
images.

For Python-based services, pip-freeze style lock files are the current recommendation
for capturing Python dependencies. Some tooling is available to help with onboarding —
see [Adding a New Service](#adding-a-new-service). For the history of how this approach
evolved, see [Background](#background).

## How the Pieces Fit

```
containers/ (this repo — upstream packaging)
├── Component CI and testing lives HERE
├── Feeds upstream testing infrastructure (Zuul — in progress, see open pull requests)
└── Output feeds a downstream build pipeline
└── Build pipeline output → integration testing (fix-forward model)
```

The downstream build pipeline is a **build system**, not a testing system. Its job is
to produce release-ready container images from the definitions in this repo. Integration
testing runs against those images after the fact, and failures there are handled
fix-forward — fix the issue and push again rather than blocking the pipeline.

> **Note:** Component CI belongs here (upstream), not inside or downstream of the build
> pipeline. If you find yourself wiring a CI job into the build pipeline, that's the
> signal to step back.

> **Note:** The upstream testing infrastructure (Zuul integration, content provider jobs)
> is actively being worked out. See the open pull requests for current work in this area.
> Details will be added here as they stabilize.

## Repo Structure

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

In general, my doubt about this section is how much of this should be here and how much should be in README.md. I'm in favor in improving README.md and potentially other docs files and making AGENTS.md as lean as possible.

@fmount has been actively adding AGENTS.md in other repos so he probably has a better criteria.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

yea that is something I was struggling with and I forgot to check what was actually in the README to start with. but some refinement is probably in order.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

yeah, on this point I think the path should be to focus more on README and docs/ to provide design decisions and other useful resources. We might want to keep AGENTS.md as simpler as possible and do not require to change it when something architectural is modified within the repo (e.g. directory structure or any other part that might impact the knowledge dumped here).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

btw, i started working in a doc for dev-docs in amoralej/dev-docs@e6cdc42 . It needs some changes as we changed some ideas and it's likely to deep in some stuff for a design document. We may work on a new version of a design work to be added in dev-docs or even add more documentation in s2i-openstack-containers repo, wdyt? In any case it will require some effort to work in.


Containers are organized in a two-level hierarchy under `containers/`:

```
containers/
base/ # shared base image — inherited by all service images
<component-group>/ # one directory per upstream service group (called "project" in README)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'd try to keep consistent to terms accross docs. Although it explicitely mentions that README calls it project, i'd try to keep it simple and use consistent terminology. I used project because i think the natural criteria for that level is per openstack project because all the images on it will install the same service project although more elaborated organizations may be done.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

yea consistency is probably better to have across the documentation

<image>/ # one subdirectory per individual image in the group
```

**`containers/base/`** is the foundation. It defines the shared build scripts, the
authoritative RPM repo source list (`rpms.repo`), and the base Python environment.
All service images inherit from it.

Each **component group directory** (equivalent to a "project" in README — the
"component" framing comes from earlier tooling like DLRN) contains the image
definitions for services that share the same upstream source. A group may also
have a `common/` directory for shared configuration across its images.

Each **image directory** should have:
- A source reference (where to pull upstream source from)
- RPM dependency specification
- Python dependency lock files (pip-freeze style)
- A `Containerfile` if the container needs anything beyond the base image

For current best practices, file naming conventions, and worked examples, refer to the
existing containers in this repo (`containers/cyborg/`, `containers/watcher/`) and the
reference pull requests listed in [Adding a New Service](#adding-a-new-service).

> **Note:** `rpms.repo` lives in `containers/base/` and is the authoritative RPM repo
> source list for all containers. Do not add per-container or per-group `.repo` files.

## Adding a New Service

> **Note:** This section is a starting point — it reflects early patterns and will be
> refined as more services are onboarded. If something here conflicts with what you see
> in a recently merged container, the merged code wins. Feedback and corrections via pull request
> are welcome.

The general pattern: create a directory for your component group under `containers/`
(or add to an existing group if one exists for your upstream), add a subdirectory for
each individual container, and populate it with the files described in
[Repo Structure](#repo-structure). Use an existing container as your template.

**Tooling:** A `/generate-containerfiles` skill for Claude Code is available — see
`README.md` for the link. Note: load the skill from there rather than having your
agent fetch it directly from this file. Additional CI tooling is in development;
see open pull requests for current state.

**Questions and onboarding help:** Reach out to the maintainers — preferred contact
channels are being established by the working group.

## RPM Source Rules

- Start with RHEL and CentOS Stream base and appstream — use these for everything available there
- The downstream pipeline builds against RHEL; packages must be available in RHEL or approved supplemental repos
- Supplemental repos are acceptable for packages not available in base — identify them by what they provide, not by repo name
- No RDO packages
- [`containers/base/rpms.repo`](containers/base/rpms.repo) is the authoritative repo source list — see [Repo Structure](#repo-structure)

## CI

- **GitHub Actions** — build workflow active; runs on pull requests; see `.github/workflows/`
- **Zuul, Molecule, and broader testing infrastructure** — actively being developed; see open pull requests for current state
- **Local builds** — `build.sh` is the sole container-build implementation; see `Makefile` for local dev targets

### CI Tooling Conventions

> **Note:** This section covers conventions for contributing to the CI and tooling code
> in this repo (Python, Ansible, shell). If you are only adding or modifying container
> definitions, you can skip this section.

_(Conventions to be documented here as CI tooling stabilizes — see open pull requests
for current work in this area.)_

## Anti-Patterns

Known wrong turns — flagged here so contributors and agents can recognize them early:

- **Component CI inside the build pipeline** — CI testing belongs upstream in this repo, not inside or downstream of the build pipeline (see [How the Pieces Fit](#how-the-pieces-fit))
- **Per-container or per-group `.repo` files** — [`containers/base/rpms.repo`](containers/base/rpms.repo) is the authoritative source list; don't add repo files elsewhere
- **Committing `rpms.lock.yaml` here** — that file is generated downstream from `rpms.in.yaml`; it does not belong in this repo
- **Using RDO packages** — the constraint is "no RDO", not "no EPEL"; EPEL and CentOS SIGs are acceptable where needed
- **Assuming one image per component role** — many services can share one image, but this is component-dependent; discuss with the working group before splitting or collapsing

## Background

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

unless we instruct the AI agent to go fetching and reading the content of the (at some point archived) tcib repo, I think this section belongs to the README as it is most useful for people onboarding to the project rather than an AI assistant that we want to not make mistakes and waste tokens by reverse engineering the project structure and the basic info.


This repo is the latest step in a long evolution of how Red Hat OpenStack builds and
ships service containers.

**Kolla** started with a source-first approach — containers built directly from upstream
Python source. The RDO project contributed RPM packaging on top of that foundation to
produce the containers used in Red Hat OpenStack deployments.

**tripleo-tcib** collapsed that complexity down significantly, focusing on just what Red
Hat OpenStack was actually using — primarily RPM install definitions rather than full
source builds. Simpler, but increasingly distant from upstream.

**tcib** carried that model forward into RHOSO 18, refining it for the containerized
deployment model.

**This repo (S2I)** is the next step: returning to source-first builds, where each
service container is built directly from its upstream Python source — closer to how the
upstream OpenStack community develops and tests, and easier to keep current as upstream
moves.

## Getting Involved

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

perhaps we should create a CONTRIBUTING.md and remove this section? for AI assistants I don't think this matters and it might just be noise.
If the project eventually needs real contributing guidelines (commit message format, review process), that part justifies having a CONTRIBUTING.md at the repo root (but it can be a separate PR)


This repo is maintained by a cross-team working group. Maintainers and area owners will
be listed in `CODEOWNERS` as that file is established.

Preferred channels for questions and onboarding help are being worked out by the working
group — check the repo for current guidance or reach out to the maintainers.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

While not an hard target, I would work on reducing the size of the file to stay within 100 - 120 lines. If we manage to cut Background, Getting Involved, and maybe plan for a docs section with specific .md files (e.g. CI Tooling and conventions and design decisions), we could reduce a lot the size of this file, and point to some local repo knowledge.
(not a blocker, just thoughts on how things could be organized).

7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,13 @@ Two-stage build:
| `SKIP_HASH_UPDATE` | *(unset)* | If set, `update-sources` skips updating pinned hashes and clones repos at existing pins; lockfiles are still regenerated |
| `PIP_NO_BINARY` | *(unset)* | If set, passed as `--build-arg` to the container build so pip builds packages from source (e.g., `:all:`) |

## Tooling

The `/generate-containerfiles` Claude Code skill is available in the

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for adding it.

[openstack-k8s-operators/devskills](https://github.com/openstack-k8s-operators/devskills)
repo. It generates the initial file set for a new service from a service name —
useful starting point before following the manual steps below.

## Adding a new service

1. Create the project directory structure:
Expand Down