carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1//go:build linux && rootrunner
2
3package host
4
5import (
6 "bytes"
7 "context"
8 "encoding/base64"
9 "encoding/json"
10 "os"
11 "path/filepath"
12 "testing"
13
14 "github.com/carlosframework/platform/internal/hostfloor"
15 "github.com/carlosframework/platform/internal/release"
16)
17
18// Fix round 1, I2, as real root: a box with a root participation census
19// (leo's kind) and an unarmed guard, updated from v1.3.0 to v1.4.0 by the
20// real apply on the census branch, then armed for guard-arm by
21// install-channel --policy on that same branch. The release before is
22// replaced, carlos.prev's record names the release, the identity is kept,
23// and the root moves floor's judgement ran over the new carlos.prev.
24func TestRootInstallChannelPolicyCensusBox(t *testing.T) {
25 scratch := generationRootRunnerDir(t)
26 t.Setenv("TMPDIR", scratch)
27 f := &channelFixture{applyFixture: newApplyFixture(t, "stable", "v1.3.0")}
28 for _, dir := range []string{f.a.optDir, f.a.dataDir, f.a.etcDir} {
29 for path := dir; path != scratch && path != "/" && path != filepath.Dir(scratch); path = filepath.Dir(path) {
30 if err := os.Chmod(path, 0755); err != nil {
31 t.Fatal(err)
32 }
33 }
34 }
35 t.Setenv("CARLOS_RELEASE_PUBKEY", base64.StdEncoding.EncodeToString(f.pub))
36 t.Setenv("CARLOS_DEPLOYMENT_BUCKET", "bucket")
37 id := rootFloorIdentity{Deployment: "bucket", Box: "box", Enrollment: "en"}
38 f.a.rootMoves = func() (rootFloorIdentity, bool, error) { return id, true, nil }
39 old := []byte("#!/bin/sh\necho carlos v1.3.0\n")
40 rootFloorSignRunnerBytes(t, f.a.optDir, systemBinaryPath(f.a.optDir), "v1.3.0", old, f.priv)
41 f.body = []byte("#!/bin/sh\necho carlos v1.4.0\n")
42 applyChannelUpdate(t, f, "v1.4.0", f.body, true)
43 if cur, prev := f.slots(t); !bytes.Equal(cur, f.body) || !bytes.Equal(prev, old) {
44 t.Fatalf("the census update left %q and %q", cur, prev)
45 }
46 f.in = channelInstall{a: f.a, bucket: "bucket", fetchTo: func(ctx context.Context, s release.Store, key, dst, sha string) error {
47 f.fetches++
48 return release.FetchToFile(ctx, s, key, dst, systemArtifactLimit, sha)
49 }, own: func(string) error { return nil }}
50 f.in.policy = signedPolicy(t, f.priv, "bucket", hostfloor.Floor{Min: 1, MinRelease: "v1.4.0"})
51 f.in.identity = f.identityOf(t, "v1.4.0")
52 got, err := f.in.run(context.Background())
53 if err != nil || !got.Replaced {
54 t.Fatalf("install-channel --policy on a census box: %+v %v", got, err)
55 }
56 if cur, prev := f.slots(t); !bytes.Equal(cur, f.body) || !bytes.Equal(prev, f.body) || !prevRecorded(f.a.optDir, "v1.4.0") || f.fetches != 0 {
57 t.Fatalf("slots %q %q", cur, prev)
58 }
59 key, _ := release.IdentityKey("v1.4.0")
60 published, _, err := f.store.Get(context.Background(), key)
61 if err != nil {
62 t.Fatal(err)
63 }
64 if held, err := os.ReadFile(channelIdentityPath(f.a.optDir)); err != nil || !bytes.Equal(held, published) {
65 t.Fatal("identity", err)
66 }
67 floors, err := openRootMovesFloors(f.a.optDir, id, false)
68 if err != nil {
69 t.Fatal("the census box's root floor state", err)
70 }
71 defer floors.close()
72 raw, err := floors.public.Read("prev.json")
73 if err != nil {
74 t.Fatal("the root moves floor did not judge the new carlos.prev", err)
75 }
76 var verdict rootFloorVerdict
77 if err := json.Unmarshal(raw, &verdict); err != nil || verdict.Identity != id || verdict.PrevAbsent || verdict.Prev.Version != "v1.4.0" || verdict.Prev.Digest != hostfloor.Digest(f.body) {
78 t.Fatalf("the judgement is not of the replaced carlos.prev (v1.4.0): %s %v", raw, err)
79 }
80 if again, err := f.in.run(context.Background()); err != nil || !again.Already {
81 t.Fatalf("rerun %+v %v", again, err)
82 }
83 t.Log("PASS install-channel --policy on a census box: root moves branch, mandatory record, identity kept")
84}
85