3b8a2c4e75
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---
161 lines
7.7 KiB
Markdown
161 lines
7.7 KiB
Markdown
# 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.dev` with username + personal access
|
|
token (or password if no 2FA). The `GITEA_TOKEN` env 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 push` step. The `.coreci.yml` release
|
|
pipeline needs a `container-publish` step. Credential is `GITEA_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 `--private` flag accepts `true`/`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 with `tag_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.sh` relies on (REQ-043).
|
|
- Asset naming convention from existing releases:
|
|
`orca-{version}-linux-amd64.tar.gz` (per `scripts/release.sh`).
|
|
|
|
**Implication for P02 install.sh**:
|
|
1. Query `GET /api/v1/repos/coreci/orca/releases/latest` (unauth, post-R-002).
|
|
2. Parse `tag_name` for the version.
|
|
3. Find the asset with `name` matching `orca-{tag}-linux-{arch}.tar.gz`.
|
|
4. Download `browser_download_url` with `curl -fsSL`.
|
|
5. 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-debian12` is 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), output `bin/orca`.
|
|
- Stage 2 (`gcr.io/distroless/static-debian12`): `COPY bin/orca /orca`,
|
|
`ENTRYPOINT ["/orca"]`.
|
|
- `CGO_ENABLED=0` must 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 `nonroot` user by default in distroless — but orca
|
|
writes to `~/.orca` (or `/root/.orca` for `--system`). For the
|
|
container image, default `ORCA_HOME=/var/lib/orca` and 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.sh` in the repo, accessible via
|
|
`https://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` (parse `version` field), print
|
|
"updated from X to Y", overwrite binary. **Never** touch the
|
|
namespace dir (`~/.orca` or `/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**: `docker` may not be available in the CoreCI release
|
|
pipeline container. The `.coreci.yml` release step uses
|
|
`image: golang:1.25` which does NOT include docker. **Mitigation**:
|
|
the release pipeline must use a `docker:dind` sidecar or a step image
|
|
that has the docker CLI. Alternatively, `scripts/release.sh` handles
|
|
docker publish only when run locally or in a CI step that has docker.
|
|
The `.coreci.yml` container step must use an image with docker CLI
|
|
(e.g., `catthehacker/docker:docker-latest` or a custom image).
|
|
|
|
- **P-002**: Making the repo public exposes git history including the
|
|
pre-existing `.env` SHA-1 leak (commit `00127ce` documented the
|
|
rotate-forward decision; `.gitleaks-baseline.json` suppresses 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=0` must be explicit in the Dockerfile build
|
|
stage. Without it, `go build` in `golang:1.25` may produce a
|
|
dynamically-linked binary that won't run in distroless. Verified:
|
|
orca has no CGO deps, but `CGO_ENABLED=0` is belt-and-suspenders. |