Documentation
¶
Overview ¶
Package teamsource resolves a kuketeams.io/v1 ProjectTeam's structured `source` reference to a local clone of the agents repo and loads the Role, Harness, and ImageCatalog documents the project's roster references (epic #792). The source is host-explicit (`repo: <host>/<owner>/<repo>`) and carries exactly one ref intent: a pinned `tag`/`commit` (reproducible — the cache is cloned once and reused as-is) or a floating `branch` (refetched and reset to the branch tip on every init, so a stale roster is never silently reused). The default clone transport is SSH (`git@<host>:<owner>/<repo>.git`) using TeamsConfig.spec.git.sshKey as the clone identity; TeamsConfig.spec. sources is consulted only as an optional per-repo transport override (HTTPS, internal mirror, non-standard port). Document loading delegates to the existing kuketeams parser, so parse errors carry the offending file path verbatim. No daemon is required — the package is unit-testable against a local fixture remote.
Index ¶
- func CloneURL(tc *model.TeamsConfig, src Source) string
- func HarnessDir(cacheDir, name string) string
- func HarnessPath(cacheDir, name string) string
- func ImageCatalogPath(cacheDir string) string
- func LoadHarness(cacheDir, name string) (*model.Harness, error)
- func LoadImageCatalog(cacheDir string) (*model.ImageCatalog, error)
- func LoadRole(cacheDir, ref string) (*model.Role, error)
- func RolePath(cacheDir, ref string) string
- type Bundle
- type Cache
- type RefKind
- type Source
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func CloneURL ¶
func CloneURL(tc *model.TeamsConfig, src Source) string
CloneURL returns the clone URL for src. The default transport is SSH — `git@<host>:<owner>/<repo>.git`, cloned under the sshKey identity (threaded separately into the git env). TeamsConfig.spec.sources is consulted only as an optional transport override: an entry keyed by the host-qualified repo or the bare `<owner>/<repo>` (in that order) with a non-blank value replaces the SSH default. The common case needs no sources entry.
func HarnessDir ¶
HarnessDir is the on-disk directory the named harness's harness.yaml lives in. teamrender resolves harness.Spec.Template relative to this directory and scans it for sibling *.tmpl.yaml partials, so the renderer and the loader agree on the layout without each open-coding the path.
func HarnessPath ¶
HarnessPath is the on-disk harness.yaml location for name under cacheDir.
func ImageCatalogPath ¶
ImageCatalogPath is the on-disk harnesses/images.yaml location under cacheDir.
func LoadHarness ¶
LoadHarness reads <cacheDir>/harnesses/<name>/harness.yaml and returns the typed Harness. A document of the wrong kind surfaces ErrTeamHarnessFileKind.
func LoadImageCatalog ¶
func LoadImageCatalog(cacheDir string) (*model.ImageCatalog, error)
LoadImageCatalog reads <cacheDir>/harnesses/images.yaml and returns the typed ImageCatalog. A document of the wrong kind surfaces ErrTeamImageCatalogFileKind.
func LoadRole ¶
LoadRole reads <cacheDir>/<ref>/role.yaml, parses it via the kuketeams parser, and returns the typed Role. A document of the wrong kind surfaces ErrTeamRoleFileKind; parse errors carry the file path verbatim.
func RolePath ¶
RolePath is the on-disk role.yaml location for ref under cacheDir. Roles live at the agents source's top level (<cacheDir>/<ref>/role.yaml) — the asymmetry vs the `harnesses/`-nested HarnessPath / ImageCatalogPath layout matches the canonical agents repo (github.com/eminwux/agents), which keeps each role under its own top-level directory and groups harnesses (plus the shared images.yaml) under a `harnesses/` umbrella.
Types ¶
type Bundle ¶
type Bundle struct {
// Source is the resolved reference (repo, host, owner/repo, ref, kind).
Source Source
// CacheDir is the on-disk clone root — passed to the render pipeline when
// it needs to read blueprint templates or other repo-relative paths.
CacheDir string
// Roles maps the role ref (ProjectTeam.spec.roles[].ref) to its loaded Role.
Roles map[string]*model.Role
// Harnesses maps the harness name (ProjectTeam.spec.defaults.harnesses[])
// to its loaded Harness.
Harnesses map[string]*model.Harness
// ImageCatalog is the single harnesses/images.yaml in the agents source.
ImageCatalog *model.ImageCatalog
}
Bundle is the materialized agents source plus the Role / Harness / ImageCatalog documents the project's roster references.
func Resolve ¶
func Resolve( ctx context.Context, cache Cache, tc *model.TeamsConfig, pt *model.ProjectTeam, ) (*Bundle, error)
Resolve validates pt.Spec.Source, derives the clone URL (SSH default, with tc.spec.sources as an optional override), materializes the agents source under cache using tc.spec.git.sshKey as the clone identity, and loads every Role referenced by pt.Spec.Roles, every Harness referenced by pt.Spec.Defaults.Harnesses, and the ImageCatalog. Parse errors surface with the offending file path.
type Cache ¶
type Cache struct {
Base string
}
Cache is the on-disk cache root for materialized agents sources. Each reference lives at <Base>/<host>/<owner>/<repo>@<ref>, so the ref is encoded in the leaf directory name. For a pinned tag/commit the existence of that directory is sufficient to decide reuse; a floating branch refetches the branch tip in place on every materialize.
func NewCache ¶
NewCache returns a Cache rooted at base. Pair with teamhost.Layout.CacheDir for the standard ~/.kuke/cache location.
func (Cache) Materialize ¶
func (c Cache) Materialize(ctx context.Context, src Source, cloneURL, sshKey string) (string, error)
Materialize ensures src is present at its cache path and returns that path, honoring the ref kind:
- pinned (tag/commit): an existing cache directory is reused as-is; a missing one is cloned into a sibling temp directory and renamed into place atomically, so an interrupted clone never leaves a half-materialized cache dir behind.
- floating (branch): an existing cache directory is refetched (`git fetch`) and hard-reset to the branch tip on every call — blind reuse of a floating branch would silently run stale agents. A missing one is cloned like the pinned path.
sshKey, when non-empty, is wired into GIT_SSH_COMMAND (`-i <key> -o IdentitiesOnly=yes`) so the SSH-default transport clones under the operator's declared identity. The non-interactive git env (GIT_TERMINAL_PROMPT=0, StrictHostKeyChecking=accept-new BatchMode=yes SSH) mirrors kuketty's processRepos so a first-time clone of an unseen host never hangs.
type Source ¶
type Source struct {
// Repo is the normalized host-qualified `<host>/<owner>/<repo>` — the
// cache-directory key (with @ref appended) and override-lookup key.
Repo string
// Host is the git host (`github.com`, `git.example:22`).
Host string
// OwnerRepo is the `<owner>/<repo>` (or `<group>/<sub>/<repo>`) half — the
// SSH path and the bare override-lookup key.
OwnerRepo string
// Ref is the single tag/branch/commit value.
Ref string
// Kind is the ref classification (tag/branch/commit) driving reuse.
Kind RefKind
}
Source is a resolved, host-explicit agents reference.
func FromModel ¶
func FromModel(m model.TeamSource) (Source, error)
FromModel validates and normalizes a model.TeamSource into a resolved Source: the repo host is defaulted to github.com when bare, and the single tag/branch/commit ref is extracted. A malformed source surfaces errdefs.ErrTeamSourceInvalid via the shared parser validation.