Configuration¶
zoryn reads configuration from three places, in order of specificity:
| File | Purpose |
|---|---|
~/.zoryn | Global user config (TOML). Required for zoryn to work. |
~/.config/zoryn/builders.d/*.conf | One .conf per builder — local or remote hasher machine. |
.gear/version-up | Per-package overrides: upstream version mapping, CVE sources, merge hints. |
Run zoryn gen environment to bootstrap ~/.zoryn plus SSH, hasher and GPG configs in one shot.
~/.zoryn¶
Minimal example — zoryn works with just this:
All other sections have sensible defaults. Override only what genuinely differs for you.
Full example¶
[build]
command = "hsh -v --number={hasher_number} --mountpoint=/proc,/dev/pts,/dev/kvm --lazy-cleanup {hasher_dir}"
log_filename = "build.{batch}.{builder}.log"
[builders]
default = "local"
default_arch = "x86_64"
parallel = "off"
results_download_dir = "{git_root}/hasher_out"
batch_repo = "~/zoryn-batch-repo"
[gitery]
host = "gitery"
remote = "gitery"
login = "rider"
[gitoskop]
url = "https://git.altlinux.org/gitoskop/api"
[gyle]
host = "gyle"
[sources]
srpms_path = "/mnt/ftp/pub/distributions/ALTLinux/Sisyphus/files/SRPMS/"
[rebuild]
command = "hsh -v --mountpoint=/proc,/dev/pts,/dev/kvm --lazy-cleanup"
log_dir = "/tmp/rebuild-logs"
[add_changelog]
up_template = "- {old_version} -> {new_version} {cves}"
[ssh]
multiplexing = true # reuse TCP connections via ControlMaster (default: true)
persist = "10m" # keep master connection alive after last use (default: 10m)
[notify]
enabled = true # desktop notifications for long-running commands (default: true)
[commands]
# Optional: override paths and arguments for external commands
# git = "/usr/local/bin/git"
# git.fetch = "{git} fetch --prune"
# ssh = "ssh -o ConnectTimeout=10"
# ssh.gitery = "{ssh} -p 2222 -i ~/.ssh/alt_key"
Section reference¶
[build]¶
command— hsh command for local builds.zoryn gen environmentwriteshsh -v --packager={packager} --mountpoint=/proc,/dev/pts,/dev/kvm --lazy-cleanup {hasher_dir}. The{hasher_dir}argument keeps builds and other local-builder operations in the same directory (~/hasherby default). Usehsh, notgear-hsh— the tarball is created separately withgear --commit. For parallel builds with multiple local hashers, also use{hasher_number}.log_filename— log filename template (default:build.{batch}.{builder}.log). Placeholders:{builder},{batch},{pkgname}.packager— packager string (Name <email>) passed tohsh --packager=for local hasher builds (default: unset — hsh uses its own configured packager).
[builders]¶
default— default builder(s) when no--builderis specified and no per-branch override applies. Comma-separated string or TOML array (e.g."local"or["local", "arm-server"]).default_arch— default architecture(s) for multi-builder mode. Comma-separated string or TOML array. When multiple architectures are listed, multi-builder mode is enabled automatically.parallel— default parallel mode for multi-builder builds (onoroff, default:off). Override with--parallel/--sequential.results_download_dir— directory for downloading remote build results (default:{git_root}/hasher_out). Supports{git_root}.batch_repo— directory for accumulating RPMs during batch builds. Used bydownload_rpms/upload_rpms.repo_workdir— root directory under whichzoryn task mkrepowrites generated task repositories (<repo_workdir>/<task_id>/repo). Can be set globally here or per-builder.
[builders.<branch>] — per-branch defaults¶
[builders]
default = "sis-x86, sis-arm"
default_arch = "x86_64"
[builders.p11]
default = "p11-x86"
default_arch = "x86_64"
[gitery]¶
host— SSH alias for gitery. Must match an entry in~/.ssh/config.remote— name of the git remote pointing to gitery, used for push operations.login— gitery/ALT Linux login, used byzoryn giteryto resolve a bare repository name topeople/<login>/packages/<name>. Required for bare-name resolution; unused when a full path or-n/--namespaceis given. When this key is unset, the login is derived from your gituser.emailif it is an@altlinux.orgaddress — its local part (before the@) becomes the login.
[gitoskop]¶
url— gitoskop HTTP API base URL, used by the read commands ofzoryn gitery(default:https://git.altlinux.org/gitoskop/api). A trailing slash is stripped.
[gyle]¶
host— SSH alias for the gyle build system.
[sources]¶
srpms_path— local SRPMS mirror (required forzoryn task rebuild).
[rebuild]¶
command— hasher command for rebuilding packages (default:hsh -v --mountpoint=/proc,/dev/pts,/dev/kvm --lazy-cleanup).log_dir— base directory for build logs (default:/tmp/rebuild-logs).
[tasks]¶
api_url— Tasks API base URL (default:https://git.altlinux.org/tasks/api).user— girar username for API queries (default: extracted from%packageremail in~/.rpmmacros).
[rdb]¶
api_url— RDB API base URL (default:https://rdb.altlinux.org/api).
[clone]¶
api_url— API endpoint that returns a package's git clone URL, used byzoryn clone(default:{[rdb] api_url}/package/clone_url). A trailing slash is stripped.
[repoteka]¶
url— Repoteka base URL for package/arch queries (default:https://rdb.altlinux.org/repoteka). A trailing slash is stripped.
[hosts] — builder host monitoring limits¶
Load thresholds checked before dispatching a build to a host. Set them globally in [hosts], or per-host in [hosts."<hostname>"] (a host-specific value wins over the global one).
min_free_ram— minimum free RAM before the host is considered busy (default:2G). Accepts suffixes such as2G,512M.max_load_avg— maximum 1-minute load average (default:8.0).max_io_wait— maximum I/O-wait percentage (default:50).
[add_changelog]¶
up_template— changelog entry template forzoryn up(default:- updated from {old_version} to {new_version} {cves}).{old_version},{new_version},{cves}(the latter expands to(Fixes: CVE-...)or empty).- The per-package
.gear/version-up[add_changelog]takes priority over~/.zoryn. - Trailing whitespace is trimmed automatically.
[submit]¶
run— whether to run a task after creating/modifying (default:false).test_only— whether to mark tasks as test-only (default:true).
To restore the pre-zoryn behaviour (run with --commit by default):
[ssh]¶
multiplexing— enable SSH connection multiplexing via OpenSSH ControlMaster (default:true). Reuses TCP connections to the same host, reducing latency for multi-step builder operations.persist— how long the master connection stays alive after the last session ends (default:10m). Uses the same time format asssh_config(5)ControlPersist.alive_interval—ServerAliveIntervalfor the multiplexed connection, in seconds (default:15).alive_count_max—ServerAliveCountMaxfor the multiplexed connection (default:3).- Socket files are stored in
$XDG_RUNTIME_DIR/zoryn/(or$TMPDIRfallback) and cleaned up automatically on exit.
[notify]¶
enabled— enable desktop notifications for long-running commands (default:true). Sends OSC 99 escape codes (kitty protocol) followed by BEL to stderr. Kitty, WezTerm and foot show a popup; other terminals play the bell. Notifications fire at completion of:build,up,task rebuild,task test-rebuild,task batch.
[commands]¶
- Override paths and global arguments for external commands (
git,ssh,gear-*,rpm, etc.). - Subcommands inherit from their base:
git.fetch = "{git} fetch --prune"— ifgitis overridden,git.fetchuses the override. ~/and$HOMEare expanded to absolute paths.- Shell metacharacters (
;,|,`,$()) are rejected at startup.
[devenv]¶
backend— default backend forzoryn devenv:bwraporpodman. When unset,podmanis used if installed, otherwisebwrap.packages— extra packages to install in the development environment on top of the spec'sBuildRequires:(e.g. debuggers, editors, profilers).image— base image for the podman backend (default:registry.altlinux.org/<branch>/alt:latest). Set this when the default is not pullable on the current host (e.g. a local mirror or private registry);zoryn devenv --image IMAGEoverrides it per invocation. Not read from.gear/devenv.build— array of shell commands run asRUNsteps when building the podman image, as root, after the dependency install and before theUSERswitch. Machine config only — not read from.gear/devenv.build_user— likebuild, but run as the host user after theUSERswitch (per-user installers, e.g.curl … | bashinto~/.local/bin); usesudofor root steps. Machine config only.mounts— array of host paths /host:container[:opts]specs bind-mounted into the podman container (each-vat container-create time, in addition to the always-mounted project directory). A bare path is bound at the same path. Podman backend only; machine config only — not read from.gear/devenv.pids_limit— integer pid cap for the podman container (--pids-limit; default 4096,0or a negative value for unlimited). The container also runs with--initso zombie subprocesses (e.g.git's background auto-gc) are reaped. Podman backend only; machine config only.prompt— literal bashPS1string baked into the podman image's user~/.bashrc, so the interactive shell uses it. Standard prompt escapes (\u,\h,\w, colour\[\e[…m\]…\[\e[0m\]) are interpreted at prompt time. Changing it rebuilds the image. Podman backend only; machine config only — not read from.gear/devenv.outbound_interface— host network interface name (e.g.eth1). When set, the podman container is switched off--network hostonto a rootlesspastanetwork namespace whose outbound IPv4/IPv6 traffic is bound to that interface, so its outgoing connections leave the host via that interface (and host-localhost services are no longer shared). Changing it recreates the container. Podman backend only; machine config only — not read from.gear/devenv.forward_ssh_agent— whentrue, forward the host SSH agent into the podman container (host$SSH_AUTH_SOCKbind-mounted to/run/ssh-agent.sock) so tools inside use your agent keys;zoryn devenv --ssh-agent/-Aenables it per run. Podman backend only; machine config only.branch— target ALT branch (defaultsisyphus); also derives the default podman base image whenimageis unset.zoryn devenv --branch/-Boverrides it for one run.apt_config— host apt config path: an apt.conf-format file, asources.listfile, or a directory containing either. For the bwrap backend: normalised to an apt.conf file forhsh --apt-config(asources.listis wrapped into a generated apt.conf) so the chroot is populated from the chosen repositories. For the podman backend: used as the apt sources for the container image (replaces the base image'ssources.list). Tilde-expanded; must exist. Machine config only.apt_builder— builder name whose apt config is reused for the podman container'ssources.list(e.g."local"). Podman backend only; machine config only.apt_sources— array of apt source lines written verbatim into the podman container'ssources.list(e.g.["rpm file:///mnt/alt x86_64 classic"]). Localfile:repositories are bind-mounted read-only at the same path; a missing host path is an error. Podman backend only; machine config only.default_profile— name of the[devenv.profiles.<name>]profile to apply when--profileis not given. Base-only — never read from within a profile.[devenv.features.<id>]— select devenv feature<id>(a reusable bundle of packages + install steps + mounts); the table's keys are the feature's options. A local~/.config/zoryn/devenv/features/<id>/definition overrides the built-in. Podman only; machine config only.
A profile is a named, fully independent [devenv] configuration declared as [devenv.profiles.<name>]. When it is active, every [devenv] key is read only from the profile; the base [devenv] section is not inherited or merged into it (the base applies only when no profile is active). A package's own BuildRequires and committed .gear/devenv packages still apply regardless of profile. Select with zoryn devenv --profile <name>. See zoryn devenv.
[devenv]
backend = "bwrap"
packages = ["gdb", "vim", "strace"]
# image = "registry.example.com/alt/sisyphus"
# mounts = ["/srv/sources:/srv/sources:ro"]
# prompt = "\\[\\e[32m\\]\\u@\\h\\[\\e[0m\\]:\\w\\$ "
# outbound_interface = "eth1"
# default_profile = "sisyphus"
# [devenv.profiles.p11]
# branch = "p11"
See zoryn devenv for the full dependency resolution order and per-project overrides.
~/.config/zoryn/builders.d/¶
Each .conf file defines one builder — a local or remote hasher machine.
# ~/.config/zoryn/builders.d/arm-server.conf
[builder]
name = "arm-server"
type = "remote"
arch = "aarch64"
branch = "sisyphus"
host = "builder-arm.internal"
hasher_dir = "~/hasher"
remote_dir = "~/build"
# hasher_number = 1 # for parallel builds (requires hasher-useradd --number=N)
[commands]
upload = "rsync -av {tarball} {host}:{remote_dir}/"
build = "hsh -v --lazy-cleanup --apt-config=$HOME/hasher_{hasher_number}.env/{branch}/apt.conf {hasher_dir} {remote_dir}/{tarball_name}"
# download uses smart download by default (only newly built packages)
cleanup = "ssh {host} \"rm -rf {remote_dir}/*\""
shell = "hsh-shell {hasher_dir}"
install = "hsh-install {hasher_dir} {packages}"
[builder]¶
name— builder name (used for--builder).type—localorremote.arch— target architecture (x86_64,aarch64,i586, …).branch— target branch (sisyphus,p11, …).host— SSH host for remote builders.hasher_dir— hasher working directory (default:~/hasher).remote_dir— working directory on remote host.hasher_number— hasher subconfig number for parallel builds.repo_workdir— root directory under whichzoryn task mkrepowrites generated task repositories (<repo_workdir>/<task_id>/repo). Overrides the global[builders] repo_workdir.
[commands]¶
upload— upload tarball (runs locally).build— build command (wrapped in SSH for remote builders).download— download results (runs locally). Smart by default: downloads only newly built packages viarsync --files-from. Old configs with full repo download are auto-migrated.list_rpms— list RPMs with mtimes in hasher repo (default:find {hasher_dir}/repo -name '*.rpm' -printf '%P\t%T@\n'). Feeds smart download.cleanup— cleanup command after build.shell— forzoryn builder shell.install— forzoryn builder install.check_busy,download_rpms,upload_rpms— auto-generated if not specified.
To customise --mountpoint=... — for example to drop /dev/kvm on shared hosts without virtualisation — override build and rebuild here. zoryn validates mountpoints against the effective command, not the default. See Builder without /dev/kvm.
Variables available in command templates:
{host}, {hasher_dir}, {remote_dir}, {tarball}, {tarball_name}, {results_download_dir}, {git_root}, {packages}, {batch_repo}, {arch}, {name}, {hasher_number}, {branch}.
See zoryn builder add for the interactive and mass-creation workflows.
[build]¶
timeout— how long (minutes) zoryn waits for a free builder slot before giving up.inactivity_timeout— how long (minutes) a running build may produce no new log output before it is killed as stalled (default: 60). Set to0to disable. The clock starts only once the build writes its first byte, so a long silent pre-output phase (e.g. chroot setup) is never mistaken for a stall — as a consequence, a build that hangs before writing any log output is not caught by this check. Raise the value (or set0) on slow builders where a single huge compilation unit or an LTO link can legitimately stay silent longer than an hour.max_log_mb— maximum build log size in MiB before the build is killed as stalled (default: 1024). Set to0to disable. Catches builds stuck in a tight output loop where the log keeps growing but no real build work is done.
All three [build] keys may also be set once in the global ~/.zoryn [build] section; a value in a builder's own builders.d/*.conf always takes precedence over the global one.
Parallel builds only
The stall watchdog (inactivity_timeout / max_log_mb) runs only in the parallel dispatcher — i.e. when building on 2 or more builders without --sequential, or in the interactive --top TUI (which always uses the dispatcher). A single-builder, non---top --sequential run executes each build in-process with no monitoring, so these keys have no effect there (zoryn prints a warning when they are set but the run is sequential).
Remote builders: local slot only
On a remote builder the kill tears down the local ssh process but does not cross the SSH boundary, so a stalled remote hsh is not directly reaped — it keeps holding the builder's hasher workdir until it finishes on its own. The watchdog frees the local slot immediately, so the next task may be queued to the same remote builder. hasher's workdir lock keeps the two from corrupting each other, but the new build then blocks on that lock producing no log output, and the inactivity watchdog does not start its clock while a log is empty — so that builder can stay wedged until the orphan finishes (a deadlocked orphan wedges it for the rest of the run). On local builders the whole build process group is torn down.
Killed builds leave hasher state
A watchdog (or Ctrl+C) kill sends SIGTERM, waits a short grace, then SIGKILL. A build killed by SIGKILL cannot run hasher's cleanup, so bind mounts and a dirty workdir may be left on the builder and accumulate across a run. If a builder starts failing after repeated stalls, clean its hasher workdir (e.g. hsh --initroot / unmount leftovers) before reusing it.
.gear/version-up¶
Per-package overrides for how zoryn converts upstream tags to RPM versions, where to fetch CVEs from, and merge strategy. TOML format.
[version]
pattern = "{major:+}.{minor:+}.{patch:+}"
template = "{major}.{minor}.{patch}"
strip-prefix = "v"
create-alias = true
filter = "minor=4"
[changelog]
file = "CHANGELOG.md"
# or use remote URL:
# url = "https://curl.se/docs/vuln.json"
# parser = "osv-json"
# cve-format = "extended"
# or use OSV API for projects without changelog files (e.g. Wireshark):
# parser = "osv-api"
# osv-package = "gitlab.com/wireshark/wireshark"
# osv-ecosystem = "GIT"
[merge]
use-theirs = ["meson.build", "configure.ac"]
# scheme = "git-merge" # override auto-detection: "git-merge" or "tarball"
[tarball]
gear-update-opts = "--all"
For HTML release notes (Wireshark example):
[changelog]
parser = "web_regex"
url = "https://www.wireshark.org/docs/relnotes/wireshark-{new_version}.html"
web-regex-pattern = 'wnpa-sec-\S+\s+(?<desc>(?:[^.]|\.\d)+?)\.\s+Issue\s+\d+(?:\s*,\s*Issue\s+\d+)*\s*\.\s+(?<id>CVE-\d{4}-\d+)'
web-regex-stop-at = "Prior Versions"
Validate your config with zoryn check version-up.
[version] — tag → RPM version mapping¶
Placeholder format: {name:length}
name— capture group name (e.g.major,minor,patch,year,month,day).length— digit count specifier:+or*— one or more digits (regex[0-9]+)N(number) — exactly N digits (regex[0-9]{N})
Literal characters: . matches a literal dot; -, _ match literal hyphen/underscore; any other character matches as-is.
Template field: uses captured group names without length specifier: {major}, {minor}, … A group may carry a default: {patch:0} emits the captured value, or 0 when the group was absent from the tag.
Pattern examples¶
| Upstream tag | pattern | template | RPM version |
|---|---|---|---|
v1.2.3 | v{major:+}.{minor:+}.{patch:+} | {major}.{minor}.{patch} | 1.2.3 |
release-1.2 | release-{major:+}.{minor:+} | {major}.{minor} | 1.2 |
20240115 | {year:4}{month:2}{day:2} | {year}.{month}.{day} | 2024.01.15 |
2.0.0-rc1 | {major:+}.{minor:+}.{patch:+}-{pre:+} | {major}.{minor}.{patch} | 2.0.0 |
camlidl113 | camlidl{major:1}{minor:2} | {major}.{minor} | 1.13 |
RELEASE_8_4_5 | RELEASE_{major:+}_{minor:+}_{patch:+} | {major}.{minor}.{patch} | 8.4.5 |
4.18 / 4.18_02 | {major:+}.{minor:+}(?:_{patch:+})? | {major}.{minor}(?:.{patch})? | 4.18 / 4.18.02 |
v5.8-505 / v5.8.1-506 | v{major:+}.{minor:+}(?:.{patch:+})?-{build:+} | v{major}.{minor}.{patch:0}.{build} | 5.8.0.505 / 5.8.1.506 |
Optional groups use standard regex (?:...)?. When the optional part is absent in the tag, the corresponding segment in the template is omitted. A {name:default} default only applies to placeholders outside an optional section — inside (?:...)? the whole section is dropped when the group is absent, so the default never fires.
When upstream sometimes drops a component (e.g. v5.8-505 with no patch, then later v5.8.1-506 with one), omitting the segment instead produces a shorter version where the next component lands in the wrong slot — 5.8.505 would then sort above 5.8.1.506 and block the update. Make the component optional in pattern but give it a default in template ({patch:0}) so the layout stays fixed and versions remain monotonic: 5.8.0.505 < 5.8.1.506.
Filtering tags¶
filter limits which tags are considered. filter = "minor=4" matches only tags where captured minor equals 4. Multiple filters: filter = "major=8, minor=4".
[changelog] — CVE scanning source¶
Both CVE-YYYY-NNNNN and CVE:YYYY-NNNNN (ISC format) are normalized to the standard CVE-YYYY-NNNNN. Version headers like Product X.Y.Z (status) released on Date (ISC Kea/BIND) are recognised.
file— local changelog path (CHANGELOG.md,NEWS,ChangeLog).url— URL with security advisories (e.g.https://curl.se/docs/vuln.json).parser— parser type:auto(default) — auto-detect from content.osv-json/json— OSV JSON format (used by curl).markdown/md— standard markdown changelog.html/html-table— HTML table with CVE info.osv-api— query OSV API directly (requiresosv-package).oracle-csaf— Oracle CSAF JSON advisory (for Oracle products like MySQL).mozilla— Mozilla security advisories scraped from the mozilla.org security-advisories website. Use forfirefox,firefox-esr,thunderbird.web_regex— universal HTML parser using a PCRE regex with named groups(?<id>...)and(?<desc>...). For upstreams whose CVEs are published on a HTML release-notes page (e.g. Wireshark) and not present in OSV. Requiresweb-regex-pattern; supports optionalweb-regex-stop-atsubstring marker.
osv-package— package name(s) in the OSV database. Accepts a single name, comma-separated list, or TOML array.gitlab.com/wireshark/wireshark,"stdlib,toolchain",["stdlib", "toolchain"].osv-ecosystem— OSV ecosystem (default:GIT; alsoPyPI,npm,crates.io,Go,Maven).oracle-advisory-product— Oracle product name for filtering (e.g.MySQL Server). Auto-detected from SRPM name if not set.oracle-advisory-max-body-size— max response size for CSAF download in bytes (default: ~4 MB).mozilla-product— Mozilla product name used to match the advisory-index<product> <version>entries (e.g.Firefox,Firefox ESR,Thunderbird). Auto-detected from the SRPM name when omitted (firefox→Firefox,firefox-esr→Firefox ESR,thunderbird→Thunderbird).web-regex-pattern— PCRE forparser = web_regex. Must contain named groups(?<id>CVE-...)and(?<desc>...). Matches with non-CVEidare silently dropped. Validated byzoryn check version-upbefore any HTTP request.web-regex-stop-at— case-sensitive substring marker forparser = web_regex. Content from the first occurrence onward is ignored. Use this to skip "Prior Versions" / older-release sections of cumulative HTML pages. If not found, the parser scans the whole document and emits a warning. Empty value is rejected.cve_format— CVE entry format in the RPM changelog:compact(default) — inline:(Fixes: CVE-..., CVE-...).compact_continuation— continuation lines with 4 CVEs per line:+ (fixes: CVE-..., ...).extended— multi-line with OSV descriptions:- Fixes:/* CVE-...: description.- With
compactand an existing spec, the format is auto-detected from the prior changelog style — both+and*sub-item markers are recognised, and the detected style is preserved.
url takes precedence over file if both are set. For parser = osv-api both url and file are ignored — the OSV API is queried directly. For parser = oracle-csaf, url is optional: the latest quarterly CPU URL is generated automatically if absent, and if that quarter's advisory is not published yet the fetcher falls back to progressively older quarters (up to a year) until it finds one. For parser = mozilla, url and file are ignored — advisories are scraped from the mozilla.org security-advisories website: the index page maps <mozilla-product> <new-version> to an advisory (MFSA) slug, and that advisory page is then parsed for its CVE IDs. For parser = web_regex, both url and web-regex-pattern are required; the URL supports {old_version} and {new_version} placeholders (the same substitution applies to markdown/osv-json/html-table URLs), and the page is HTML-stripped (<script>/<style> bodies removed, tags removed, comments and entities decoded, whitespace collapsed) before the regex runs. CVE descriptions are RPM-macro-escaped (% → %%) before being written into the spec %changelog, so upstream prose containing literal % is safe.
Finding osv-package¶
- Open osv.dev and search for the project (e.g.
wireshark,curl). - Open any vulnerability for that project.
- Look at the Affected packages section — the package name is shown (e.g.
gitlab.com/wireshark/wiresharkfor theGITecosystem). - Copy name and ecosystem into the config.
Or query the API directly:
curl -s -X POST https://api.osv.dev/v1/query \
-d '{"package":{"name":"gitlab.com/wireshark/wireshark","ecosystem":"GIT"},"version":"4.4.3"}' \
| python3 -m json.tool | head -20
| Ecosystem | Package format | Example |
|---|---|---|
GIT (default) | Repository URL path | gitlab.com/wireshark/wireshark |
PyPI | PyPI name | requests |
npm | npm name | express |
crates.io | Crate name | tokio |
Go | Go module path | golang.org/x/net |
Maven | group:artifact | org.apache.logging.log4j:log4j-core |
Full list: https://ossf.github.io/osv-schema/#affectedpackage-field
[merge]¶
scheme— override auto-detection of update scheme:"git-merge"or"tarball". Automatically set by--switch-to-upstream-git.use-theirs— files to take from upstream on conflict (comma/space separated). Useful for version-bearing files likemeson.build,configure.ac.
[tarball]¶
gear-update-opts— extra options forgear-update(e.g.--allto extract every directory from the archive).subdir— subdirectory name inside the tarball to extract (passed asgear-update --subdir=<value>). Supports{version}and{name}placeholders, e.g.subdir = "thunderbird-{version}". Useful for tarballs with multiple top-level entries like./and<name>-<version>/(Mozilla source tarballs). Validated against shell metacharacters and path separators before use.
[add_changelog] — per-package override¶
up_template— changelog entry template forzoryn up. Supports{old_version},{new_version},{cves}. Example:up_template = "- {old_version} -> {new_version} {cves}".
[sandbox] — hook sandbox packages¶
Per-package controls for the hybrid sandbox that runs .gear/up.d/ and .gear/merge-up.d/ hooks. This is a .gear/version-up-only section — it is not read from ~/.zoryn.
packages— extra packages to install into the chroot (on top of the spec'sBuildRequires:).gitis always installed.specbr— boolean, defaulttrue. Whenfalse, the package'sBuildRequires:are skipped: the chroot is initialised bare (hsh --initroot-only, no src.rpm build); the configured packages (git,[sandbox.chroot] packagesfrom~/.zoryn, andpackageshere) are still installed. Withspecbr = falsea custom[sandbox.chroot] preparecommand from~/.zorynis ignored (a warning is printed).
[specsubst] — specsubst values for submit¶
One key per specsubst variable. Currently kflavour is read for kernel-image repos (comma-separated for several tags). Overrides the branch's <flavour>/<dist> prefix; -k on the command line wins over both.
Date-based versions — example¶
Validation¶
zoryn validates config files when it reads them and prints a warning for any unknown section or key — for example unknown key 'pacakges' in [sandbox.hasher]. Warnings are non-fatal; the rest of the config is still applied. This catches typos such as putting packages under [sandbox.hasher] instead of [sandbox.chroot].