436641782c
P02 — Traefik dynamic config generation + atomic reload protocol. Parser (internal/jobspec/markdown.go): - Extended WorkloadSpec with Health, Constraints, Affinity, Lifecycle fields. Parsed restart/update/service/health/lifecycle/affinity/ constraints blocks. HealthBlock, AffinityRule, LifecycleBlock types. Schema (internal/spec/schema/schema.go): - ServiceValidator: restart.mode enum (service/on-failure/never), update.strategy enum (rolling/canary/blue-green), health required, service.bind IP validation (R-007 loopback opt-in). 98.5% coverage. Traefik emitter (internal/emitter/traefik.go, REQ-077): - TraefikEmitter renders /etc/traefik/dynamic/orca-<name>.yaml with http.routers, http.services (servers = R-007 socket paths), TLS (certResolver=orca, trust domain), healthCheck. RenderDrain sets weight:0 per backend. RegisterTraefik wires process/podman/wasm. Atomic reload (internal/emitter/traefik_atomic.go, gate C-10): - WriteTraefikDynamic: write to path.tmp via WriteFileIdempotent, then mv -f path.tmp path (atomic POSIX rename, Traefik fsnotify observes IN_MOVED_TO). Traefik holds-last-good on malformed config. C-10 PASS. 22 packages pass, 20 bats pass, gofmt clean, verify-reqs 90 consistent. Coverage: emitter 96.5%, jobspec 88.8%, schema 98.5%, sshpush 93.0%. ---ci--- project: orca phase: P02 milestone: v0.9 status: execute ---/ci---
31 lines
1.1 KiB
Go
31 lines
1.1 KiB
Go
// Package sshpush_test contains compile-time assertions that *Transport
|
|
// satisfies the emitter.AtomicWriter interface (the Traefik C-10
|
|
// atomicity protocol — internal/emitter/traefik_atomic.go). The
|
|
// assertion lives here (not in internal/emitter) to avoid an import
|
|
// cycle: internal/emitter is imported by this package (fanout.go), so
|
|
// internal/emitter cannot import this package.
|
|
package sshpush_test
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
"git.cloudinit.dev/coreci/orca/internal/emitter"
|
|
"git.cloudinit.dev/coreci/orca/internal/sshpush"
|
|
)
|
|
|
|
// Compile-time assertion: *sshpush.Transport satisfies
|
|
// emitter.AtomicWriter. WriteTraefikDynamic relies on this so the
|
|
// Traefik dynamic-config file is written atomically (gate C-10).
|
|
var _ emitter.AtomicWriter = (*sshpush.Transport)(nil)
|
|
|
|
func TestTransportSatisfiesAtomicWriter(t *testing.T) {
|
|
// A trivial runtime check that the type conversion is valid; the
|
|
// compile-time assertion above is the real test, but this gives
|
|
// `go test` a function to run.
|
|
tr := sshpush.NewTransport("/nonexistent", "/nonexistent")
|
|
var w emitter.AtomicWriter = tr
|
|
_ = w
|
|
_ = context.Background()
|
|
}
|