Command Palette
Search for a command to run...

REPOSITORY

Adds or removes a third-party package repository. Each backend (apt, dnf, pacman, zypper) has its own native config shape, so the parameter set is split per manager. Set only the fields for the managers you actually use on the target devices; a disabled: true sub-config (or an absent one) makes the action a no-op skip on hosts running that manager.

The agent validates every field aggressively — before any privileged side effect. Control characters or newlines in any value are refused at validation time to prevent config injection, and the offending field is named without echoing its value.

Parameters

Common:

FieldTypeRequiredDescription
namestringyesRepository identifier used for file naming. Alphanumeric only, max 64 chars (enforced by server-side validation — ._- are accepted by the agent-side grammar but rejected by the proto validator before the action ever reaches the agent).

APT — written in deb822 format to /etc/apt/sources.list.d/<name>.sources, with the signing key dearmored into /etc/apt/keyrings/<name>.gpg and referenced via Signed-By:

FieldTypeDescription
apt.urlstringRepository URL. Deliberately not restricted to https — apt's trust anchor is the GPG-signed Release file.
apt.distributionstringDistro codename (e.g. bookworm, noble). Empty selects a flat repository (Suites: /).
apt.componentsstring[]Components (e.g. main, contrib).
apt.gpg_key_urlstringHTTPS URL the agent fetches the signing key from (capped at 10 MiB).
apt.gpg_keystringInline key (ASCII-armoured or binary), alternative to gpg_key_url.
apt.archstringArchitecture filter (amd64, arm64).
apt.trustedboolWrites Trusted: yes (skips signature checking). Defaults false; honoured only when no key is configured — a key always wins.
apt.disabledboolSkip the apt config on this action entirely.

DNF — written to /etc/yum.repos.d/<name>.repo:

FieldTypeDescription
dnf.baseurlstringRepo base URL (supports $releasever / $basearch).
dnf.descriptionstringHuman label (the .repo name= field; defaults to the repo name).
dnf.enabledboolWrites enabled=1/0. Unset means enabled=0 — set it explicitly.
dnf.gpgcheckboolWrites gpgcheck=1/0. Unset means gpgcheck=0, and the key is then neither written nor imported.
dnf.gpgkeystringKey reference (https URL or absolute path) written as gpgkey= and imported with rpm --import — not inline key material.
dnf.module_hotfixesboolWrites module_hotfixes=1 for modular content.
dnf.disabledboolSkip the dnf config on this action entirely.

Pacman — a section appended to /etc/pacman.conf:

FieldTypeDescription
pacman.serverstringMirror URL (supports $repo / $arch).
pacman.sig_levelstringpacman SigLevel value, e.g. Optional TrustAll or Required DatabaseOptional (letters and spaces only).
pacman.disabledboolSkip the pacman config on this action entirely.

Zypper — configured through zypper addrepo / modifyrepo:

FieldTypeDescription
zypper.urlstringRepo URL.
zypper.descriptionstringDisplay name (modifyrepo --name).
zypper.enabledboolmodifyrepo --enable/--disable. Unset means disabled — set it explicitly.
zypper.autorefreshboolAuto-refresh metadata (addrepo --refresh).
zypper.gpgcheckboolWhen false, adds --no-gpgcheck. Unset means gpgcheck off.
zypper.gpgkeystringKey reference imported with rpm --import.
zypper.typestringRepository type (addrepo --type, e.g. rpm-md, yast2, plaindir).
zypper.disabledboolSkip the zypper config on this action entirely.

Idempotency

apt, dnf, and pacman compare the desired config against what's on disk and skip the write when nothing changed (changed=false): apt compares the deb822 source and the dearmored key bytes, dnf requires a byte-identical .repo file, pacman compares its rebuilt pacman.conf. zypper is the exception — it reconfigures via removerepo + addrepo on every run and always reports changed=true.

desired_state: ABSENT removes the backend's config (the apt .sources file plus its keyring, the dnf .repo file, the pacman.conf section, or zypper removerepo). Removing an already-absent repository is a changed=false no-op. Keys imported into the rpm keyring (dnf/zypper) are not removed.

Example

Add the Docker apt repo on Debian:

type: REPOSITORY
name: docker
apt:
  url: https://download.docker.com/linux/debian
  distribution: bookworm
  components: [stable]
  gpg_key_url: https://download.docker.com/linux/debian/gpg
desired_state: PRESENT

Gotchas

  • Repository names are validated as alphanumeric-only at the server boundary. Dots and dashes are filesystem-safe but the proto's alphanum rule refuses them — if you need them for parity with a vendor's repo-name convention, file a tracker so we can either loosen the rule or document the workaround.
  • Only apt takes inline key material (apt.gpg_key, armoured or binary) or a key URL the agent downloads (apt.gpg_key_url, https-only). dnf.gpgkey and zypper.gpgkey are references — an https URL or an absolute path the package manager resolves itself.
  • apt.trusted: true skips signature verification. Don't use it outside dev / preview repos. It's ignored whenever a key is configured.
  • A repository action refreshes the metadata cache after the config changes (apt update, dnf makecache --repo <name>, pacman -Sy, zypper refresh), so the next PACKAGE action sees it. The refresh is non-fatal — a typo'd URL surfaces as a warning in the output, but the config still lands.