core.repo
Declare an OS package repository (apt / dnf / yum / apk).
core.repo declares an OS package repository: it writes a descriptor file into the manager's system directory, and for apt also a GPG key that the .list references via signed-by=. The backend (apt/dnf/yum/apk), file format, and path are chosen automatically from the host's package manager. The module only declares the repository and does not refresh the index (apt-get update / dnf makecache) — core.pkg does that on install. The states are idempotent: if the descriptor file already matches byte-for-byte (and for apt the key too), changed=false.
Requirements
- Rootnot required
- Side
soul-side - Collection
soulstack.system - Category
system
fs_write_rootAuto from the host's package manager (util.DetectPkgMgr): apt → /etc/apt/sources.list.d/<name>.list + keyring, dnf/yum → /etc/yum.repos.d/<name>.repo (ini), apk → a line in /etc/apk/repositories. If no manager is found, the step fails.
States
core.repo.present — The repository is declared: the descriptor file (and for apt the GPG key) is in place with the required content.
The target file was missing or differs byte-for-byte, or (apt with gpg_key) the key was missing or differs.
The file and key already match byte-for-byte.
Parameters
| Param | Type | Required / default | Description |
|---|---|---|---|
name | string | required | Repository name (= the descriptor file name, [A-Za-z0-9._-]). |
uri | string | required | Repository URL (http/https; http produces a mandatory warning). |
gpg_key | string | optional | URL or armored GPG key for supply-chain verification. |
gpg_check | bool | optional | Verify package signatures (default true; opt-out produces a warning). |
suite | string | optional | apt suite/distribution (e.g. stable). |
components | list<string> | optional | apt components (e.g. [main, contrib]). |
enabled | bool | optional | Repository is enabled (default true). |
Example — apt repository with an inline GPG key
- name: Declare internal apt repo module: core.repo.present params: name: example-internal uri: https://apt.example.com/debian suite: bookworm components: [main] gpg_key: "${ file('files/example.gpg.asc') }"Output
| Field | Type | Description |
|---|---|---|
name | string | |
backend | apt / yum / apk | |
path | string | the affected descriptor file |
warnings | [string] | on gpg_check opt-out / http uri / a missing key |
core.repo.absent — The repository descriptor is removed (the GPG key is left untouched).
The file or line existed and got removed.
Neither the file nor the line existed.
Parameters
| Param | Type | Required / default | Description |
|---|---|---|---|
name | string | required | Repository name (= the descriptor file name). |
Example — Remove an apk mirror (matched by uri)
- name: Drop old apk mirror module: core.repo.absent params: name: old-mirror uri: https://dl-cdn.alpinelinux.org/alpine/edge/testingOutput
| Field | Type | Description |
|---|---|---|
name | string | |
backend | apt / yum / apk | |
path | string |
Reference
Backends and target artifacts
The backend is chosen automatically from the host's package manager; the descriptor file's format and path depend on it.
| Backend | Distributions | Artifact |
|---|---|---|
| apt | Debian, Ubuntu | /etc/apt/sources.list.d/<name>.list (one-line) + key /etc/apt/keyrings/<name>.gpg via signed-by= |
| dnf / yum | RHEL, Fedora | /etc/yum.repos.d/<name>.repo (ini format) |
| apk | Alpine | a line in /etc/apk/repositories |
Notes
- The module only declares the repository — it does not run apt-get update / dnf makecache; core.pkg refreshes the index on install.
- apt uses the modern signed-by= keyring: trust is bound to a specific repository rather than the global trust store (unlike the deprecated apt-key).
- gpg_key is provided inline only; fetching the key by URL is not implemented in the MVP — the content can be substituted via CEL (${ file(...) } / vault).
- The write is preserve-by-default (AtomicWritePreserving): the existing file's permissions and owner are preserved.
- System paths (/etc/apt, /etc/yum.repos.d, /etc/apk) require write permission on the directory (usually root); the module does not declare a separate run_as_root.
- absent removes only the repository descriptor — the GPG key is left untouched (it may be used by other repositories; cleaning up the key is a separate explicit step).
Security & defaults
- gpg_key is critical for the supply chain: when set, the key is actually materialized (apt: keyring + signed-by=) / written into gpgkey= (dnf/yum) and participates in the idempotency comparison.
- gpg_check=false is allowed (opt-out), but Apply returns a mandatory warning "packages will NOT be cryptographically verified".
- gpg_check=true without gpg_key for dnf/yum breaks package installation (gpgcheck=1 without gpgkey=) — also a warning; apt/apk rely on their own trust stores.
- http:// in uri is allowed (an internal mirror), but with a mandatory warning "traffic is unencrypted".
- name is sanitized against path traversal (only [A-Za-z0-9._-], no / \ ..) — the name becomes the file name.