b1746c25af
gates / gates (push) Successful in 19s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
50 lines
2.5 KiB
Go
50 lines
2.5 KiB
Go
package osupdate
|
|
|
|
import (
|
|
"context"
|
|
"encoding/base64"
|
|
"encoding/json"
|
|
"errors"
|
|
"testing"
|
|
|
|
"gitea.dooplex.hu/admin/felhom-agent/internal/hub"
|
|
"gitea.dooplex.hu/admin/felhom-agent/internal/reconcile"
|
|
"gitea.dooplex.hu/admin/felhom-agent/internal/signedjobs"
|
|
)
|
|
|
|
// The executor hands the RAW signed bytes to the wrapper (which verifies them itself) and the exact signed package
|
|
// list. Red-proof: drop the `signed` field from the docker plan in runLayer and the plan check fails.
|
|
func TestDockerStepExecutor_PassesTheSignedEnvelope(t *testing.T) {
|
|
w := &fakeWrapper{t: t, applyRep: map[string]WrapperReport{LayerDocker: {
|
|
Upgraded: []Package{{Name: "docker-ce", Version: "5:29.8.2-1~debian.13~trixie"}}, DockerEngine: "29.8.2", Authority: "signed"}}}
|
|
l, h := newLeg(t, w, &hub.WireOSUpdate{Ring: 1, Enabled: true})
|
|
e := DockerStepExecutor{Leg: l, Guest: func(context.Context) (int, error) { return 9201, nil }}
|
|
params, _ := json.Marshal(DockerStepParams{ReleaseID: "os-docker-1", Packages: []Package{{Name: "docker-ce", Version: "5:29.8.2-1~debian.13~trixie", Origin: "Docker CE"}}})
|
|
ctx := signedjobs.WithSignedOp(context.Background(), &reconcile.SignedOp{Blob: []byte(`{"op":"os_docker_step"}`), Sig: []byte("SIG")})
|
|
if err := e.Execute(ctx, OpDockerStep, params); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
dp := w.plans[len(w.plans)-1]
|
|
sg, _ := dp["signed"].(map[string]any)
|
|
if dp["layer"] != "docker" || dp["lane"] != "slow" || dp["release_id"] != "os-docker-1" || sg == nil ||
|
|
sg["blob_b64"] != base64.StdEncoding.EncodeToString([]byte(`{"op":"os_docker_step"}`)) || sg["sig"] != "SIG" {
|
|
t.Fatalf("docker plan = %v", dp)
|
|
}
|
|
if calls(w) != "guest:live-restore-on,docker:apply" || len(h.reports) != 1 || h.reports[0].Trigger != "signed" {
|
|
t.Fatalf("calls=%s reports=%+v", calls(w), h.reports)
|
|
}
|
|
}
|
|
|
|
func TestDockerStepExecutor_RefusesWithoutEnvelopeAndPassesOtherOps(t *testing.T) {
|
|
w := &fakeWrapper{t: t}
|
|
l, _ := newLeg(t, w, &hub.WireOSUpdate{Ring: 1, Enabled: true})
|
|
e := DockerStepExecutor{Leg: l, Guest: func(context.Context) (int, error) { return 9201, nil }}
|
|
if err := e.Execute(context.Background(), "agent_update", nil); !errors.Is(err, signedjobs.ErrNoExecutor) {
|
|
t.Fatalf("another op must pass through the chain: %v", err)
|
|
}
|
|
params, _ := json.Marshal(DockerStepParams{Packages: []Package{{Name: "docker-ce", Version: "1"}}})
|
|
if err := e.Execute(context.Background(), OpDockerStep, params); err == nil || len(w.plans) != 0 {
|
|
t.Fatalf("no envelope must refuse before any wrapper call: err=%v calls=%s", err, calls(w))
|
|
}
|
|
}
|