Tag sideloaded images with both tag+digest and digest-only#18
Merged
Conversation
Lookup hardcoded SSHPort="2222" for the qemu backend, ignoring the sshPort recorded in the provisioner's state sidecar at <cache>/<name>.json. Any qemu cluster provisioned with a non-default port (e.g. APP_SSH_PORT=2229 in the appliance build scripts) was unreachable via `y-cluster images load`, `y-cluster ctr`, etc. -- the SSH handshake hit the wrong port and bailed with "no supported methods remain". qemuRunning now reads sshPort from the sidecar alongside the pidfile + key path. Lookup uses it; "" still falls back to 2222 so caches written before sshPort landed in the schema keep working. We do not import the qemu package's full state struct -- that would create a cycle since qemu imports cluster -- so the sidecar reader inlines a one-field anonymous struct against the same JSON shape pkg/provision/qemu/state.go writes. Tests cover the round-trip (state -> qemuRunning -> port), the missing-state fallback path, and field-name drift via TestReadQemuStateSSHPort which pins the "sshPort" JSON tag. Verified live against an appliance-gcp-build cluster running on port 2229: `y-cluster images load - --context=local` streams an OCI archive into containerd successfully. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Closes specs/y-cluster/FEATURE_REQUEST_IMAGES_LOAD_DIGEST_ALIAS.md. After `ctr image import` writes the `:tag` ref, `Load` now creates a digest-keyed alias via `ctr image tag <name:tag> <name>@sha256:<digest>`. Without this, deployments pinned in `name:tag@sha256:digest` form (the y-release-image-list-local shape, used by every checkit contain-built workload) fall through to a registry pull -- which fails on cluster-local because the build registry isn't reachable from kubelet outside the cluster. The alias is created via a snapshot diff: list refs before import, list again after, alias the new tag-form refs. We don't parse `ctr image import`'s stdout for the (ref, digest) tuple because that output abbreviates / reformats refs in ways that don't round-trip back to the stored ref name. The post-import `ctr image list` row IS authoritative. The parser accepts any whitespace as a column separator and locates the digest by sha256: prefix rather than column index, so the parse survives ctr column reorderings. Snapshot failures (RunCtr returning an error) surface a warning and skip the alias step rather than failing the whole import. stripTag handles the hostport edge case (`host:port/path:tag`) so refs from a registry running on a non-default port get the colon-separated tag stripped, not the port. Unit-tested. Verified live: a fresh import on the appliance-gcp-build cluster produces both refs in `ctr image list`. Re-importing the same archive logs "no new digest aliases needed" (idempotent). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
When `y-cluster serve ensure -c <dir>` returns `noop`, the
operator can't tell whether the running daemon is on the
expected config or on stale state from a previous invocation
without grepping the on-disk snapshot. Same for `serve logs`
which doesn't say which y-cluster build / which `-c` paths
the daemon was launched with.
Three small UX fixes:
- EnsureResult carries Digest (full sha256 of the running
daemon's normalized config). CLI prints a 12-char short
SHA after the action:
y-cluster serve noop on :8944 (sha abcd1234ef56)
Same config -> same SHA across runs; matching SHA confirms
the daemon really is on what the operator just typed.
- Daemon startup log line now includes version + pid +
configDirs + digest, so `serve logs` answers
"what version is this?" and "which -c paths is it on?"
without any extra subcommand.
- serve.DaemonVersion package variable lets cmd/y-cluster
surface its full versionString() (release tag + VCS rev)
to pkg/serve. The daemon process is a re-exec of the same
binary so main() runs again on the daemon side and the
assignment carries through.
This is the diagnostic gap that surfaced when an operator
suspected a real bug after seeing `noop` from a `serve ensure`
that they expected to switch y-kustomize bases. The actual
config was unchanged so noop was correct; the absent SHA in
the output made it impossible to verify that without inspecting
state files.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
because IfNotPresent seems to match against digest only when using tag+digest images