R-001: Gitea container registry (OCI, docker login/push, anon pull when public) R-002: tea repos edit --private false (visibility flip for REQ-045) R-003: Gitea releases API (Authorization: token header, asset download URLs) R-004: ORCA_HOME propagation audit (3 sites: certpaths/store/init) R-005: distroless static-debian12 base (CGO-free, modernc/sqlite) R-006: install.sh curl|sh conventions + in-place update pattern Pitfalls P-001..P-003 (docker-in-CI, public-history leak, CGO_ENABLED=0) PERSONAS.md: devops-engineer reactivated, data/security/network deactivated for v0.5 ---ci--- project: orca phase: 0 milestone: v0.5 status: research ---/ci---
7.7 KiB
Research: Orca v0.5 — Distribution
Research findings for the v0.5 Distribution milestone (install, namespace, docker, public releases). Conducted during P0 RESEARCH under full autonomy.
R-001: Gitea Container Registry
Source: https://docs.gitea.com/usage/packages/container (Gitea 1.27.1 docs)
Findings:
- Gitea ships a built-in OCI-compliant container registry.
- Image naming convention:
{registry}/{owner}/{image}:{tag}. For orca:git.cloudinit.dev/coreci/orca:{tag}. - Auth:
docker login git.cloudinit.devwith username + personal access token (or password if no 2FA). TheGITEA_TOKENenv var already used for release publishing works as the password. - Push:
docker push git.cloudinit.dev/coreci/orca:v0.4.4. - Pull: anonymous pull works if the repo is public (REQ-045 flips this). For private repos, pull requires auth.
- Tags are case-insensitive — use lowercase image names.
- The registry supports multi-arch manifests via
docker buildx.
Implication for P03: scripts/release.sh must add a docker build
docker login+docker pushstep. The.coreci.ymlrelease pipeline needs acontainer-publishstep. Credential isGITEA_TOKEN(reused from the existing release flow — no new secret needed).
R-002: tea repos edit — Repo Visibility
Source: tea repos edit --help (tea 0.14.1 installed locally)
Findings:
- Command:
tea repos edit --private false --repo coreci/orca - The
--privateflag acceptstrue/false(string, not bool). - Default login
bot(cloudinit-bot) is already configured and is the default login. No extra auth needed. - The change is immediate and reversible (re-run with
--private true).
Implication for P0 ship: Run this as an operational step during the
P0 ship. Verify with unauth curl against the releases API afterward.
R-003: Gitea Releases API — Asset Download URLs
Source: /api/v1/repos/coreci/orca/releases/latest (authed probe)
Findings:
- Auth header format:
Authorization: token <GITEA_TOKEN>(NOT basic auth — basic auth returns "invalid username, password or token"). - Latest release endpoint:
GET /api/v1/repos/coreci/orca/releases/latest→ JSON withtag_name,name,body,assets[]. - Each asset has
browser_download_url— the direct download URL. - Public access: once the repo is public (R-002), the releases API
and asset downloads work without authentication. This is what
install.shrelies on (REQ-043). - Asset naming convention from existing releases:
orca-{version}-linux-amd64.tar.gz(perscripts/release.sh).
Implication for P02 install.sh:
- Query
GET /api/v1/repos/coreci/orca/releases/latest(unauth, post-R-002). - Parse
tag_namefor the version. - Find the asset with
namematchingorca-{tag}-linux-{arch}.tar.gz. - Download
browser_download_urlwithcurl -fsSL. - Extract and install.
R-004: ORCA_HOME Propagation Points (Codebase Audit)
Source: grep for UserHomeDir|os.Getenv("ORCA|\.orca across *.go
Findings — exactly 3 production code sites determine the namespace root today:
| File | Current behavior | Needs change? |
|---|---|---|
internal/certpaths/certpaths.go:21-26 |
Dir() honors ORCA_HOME → ~/.orca |
No — this is the single source of truth. Already correct. |
internal/store/store.go:13-19 |
Open("") hardcodes ~/.orca/orca.db (ignores ORCA_HOME) |
Yes — route through certpaths.DBPath() instead. |
internal/cli/init.go:16-22 |
Hardcodes ~/.orca via os.UserHomeDir() |
Yes — route through certpaths.Dir(). |
All other call sites (node.go:openDB, daemon.go, job.go, doctor.go,
cert.go) already go through certpaths.DBPath() or certpaths.Dir()
indirectly. No other files need changes for REQ-041.
For REQ-042 (--system): Add a --system persistent flag on
rootCmd. When set, rootCmd.PersistentPreRunE sets
os.Setenv("ORCA_HOME", "/root/.orca") before any subcommand runs.
This is the minimal-touch approach — all downstream code already
honors ORCA_HOME. The flag is a CLI convenience that maps to the
env var, not a parallel mechanism.
Backward compatibility: empty ORCA_HOME + no --system →
~/.orca (unchanged). Existing tests that t.Setenv("ORCA_HOME", ...)
continue to work.
R-005: Distroless Base Image for CGO-free Go Binaries
Source: Go module audit — modernc.org/sqlite (pure Go, CGO-free),
go.mod has no CGO dependencies.
Findings:
gcr.io/distroless/static-debian12is the correct base for static Go binaries with no CGO and no libc dependency. ~2MB image.- orca uses
modernc.org/sqlite(pure Go) — no CGO, no libc. ✓ - Multi-stage Dockerfile:
- Stage 1 (
golang:1.25): build with-trimpath -ldflags(same as Makefile), outputbin/orca. - Stage 2 (
gcr.io/distroless/static-debian12):COPY bin/orca /orca,ENTRYPOINT ["/orca"].
- Stage 1 (
CGO_ENABLED=0must be set in the build stage to guarantee a static binary (Go defaults to CGO_ENABLED=1 on platforms with a C compiler).- The image runs as
nonrootuser by default in distroless — but orca writes to~/.orca(or/root/.orcafor--system). For the container image, defaultORCA_HOME=/var/lib/orcaand document volume mount at that path.
Implication for P03: Dockerfile is ~15 lines. The .coreci.yml
release pipeline adds a docker build --build-arg VERSION=$VERSION -t git.cloudinit.dev/coreci/orca:$VERSION . step + login + push.
R-006: install.sh Conventions (curl|sh pattern)
Source: Common patterns from deno, rustup, homebrew installers.
Findings:
- 1-liner:
curl -fsSL <url> | bash(or| bash -s -- --system). - The script must be downloadable from a stable URL. orca's script
lives at
scripts/install.shin the repo, accessible viahttps://git.cloudinit.dev/coreci/orca/raw/branch/main/scripts/install.sh(once repo is public per R-002). - Args passed via
bash -s -- --system --version v0.4.4. - In-place update: detect existing binary at install path, read its
version via
orca version --json(parseversionfield), print "updated from X to Y", overwrite binary. Never touch the namespace dir (~/.orcaor/root/.orca) — that's user state. - User-level default:
~/.local/bin/orca(XDG-ish, on PATH on most modern distros). System-level:/usr/local/bin/orca(requires root).
Implication for P02: install.sh is ~80-100 lines of bash. Idempotent.
Tested via a scripts/install_test.sh that mocks the download and
verifies path selection + update-in-place.
Pitfalls (P-001..P-003)
-
P-001:
dockermay not be available in the CoreCI release pipeline container. The.coreci.ymlrelease step usesimage: golang:1.25which does NOT include docker. Mitigation: the release pipeline must use adocker:dindsidecar or a step image that has the docker CLI. Alternatively,scripts/release.shhandles docker publish only when run locally or in a CI step that has docker. The.coreci.ymlcontainer step must use an image with docker CLI (e.g.,catthehacker/docker:docker-latestor a custom image). -
P-002: Making the repo public exposes git history including the pre-existing
.envSHA-1 leak (commit00127cedocumented the rotate-forward decision;.gitleaks-baseline.jsonsuppresses it for scanning). The leak is a non-secret (the token was rotated). This is an accepted risk per the existing decision — no new action needed, but document it in the P0 ship commit. -
P-003:
CGO_ENABLED=0must be explicit in the Dockerfile build stage. Without it,go buildingolang:1.25may produce a dynamically-linked binary that won't run in distroless. Verified: orca has no CGO deps, butCGO_ENABLED=0is belt-and-suspenders.