Recreate a container when the content of a file it reads at creation changes
The host decided whether a container was still the one declared by a digest of its declaration, and the declaration names an env-file's path and a mount's path — never what is in them. So when the store was given a new port, the host rewrote the forge's and the analytics service's environment files, correctly, and left both containers running with the old port in their environment: a container reads its env-file when it is CREATED, and `docker restart` hands it the same environment again. Both looked healthy until they answered 502. What a running container takes in at creation is now part of its spec, by content: every env-file, a file bind-mounted into it, and every file this host wrote at or under a directory bind-mounted into it — the secrets, bindings and configs under a module's state directories. The digest is the one the store already records for a file the host wrote (`wrote`), read from the state as it stands when the container is reached, so a file rewritten earlier in the same apply is already the new one; a file the host has no record of — an env-file a predecessor left, the superuser secret genesis writes before any declaration names it — is read from disk, which is what keeps adopting a running store in place a reconcile and not a recreate. Deliberately not part of it: what else is in a bind-mounted directory, which is the service's own data and changes while it runs; a named volume; a seed created once, which digests as the seed the host wrote and not as what has grown in it; and a step — a run-once or scheduled container reads its files when it runs and runs fresh each time. On an adopted node a held container is held before any of this is looked at. The host records what each container was created reading, per file, so the recreate can say which file changed — "recreated: <file> changed" in the report and, now with its detail, in the log. A container made before this record existed is recreated once and says so. novox/hq 04-ISSUES/103
This commit is contained in:
@@ -69,7 +69,7 @@ func TestARunOnceStepIsRunToCompletionNotLeftRunning(t *testing.T) {
|
||||
if !ok {
|
||||
t.Fatal("a completed run-once step was not recorded")
|
||||
}
|
||||
if applied.Wrote != containerSpec(d.Resources[0].(*declaration.Container), nil) {
|
||||
if applied.Wrote != containerSpec(d.Resources[0].(*declaration.Container), inputs{}) {
|
||||
t.Errorf("the run-once record is not the declaration's digest: %q", applied.Wrote)
|
||||
}
|
||||
}
|
||||
@@ -155,7 +155,7 @@ func TestARunOnceStepAlreadyCompletedIsNotReRun(t *testing.T) {
|
||||
d := parseTrusted(t, `{"declaration":1,"resources":[
|
||||
{"id":"seed","type":"container","name":"seed","image":"`+pinned+`","run-once":true}
|
||||
]}`)
|
||||
want := containerSpec(d.Resources[0].(*declaration.Container), nil)
|
||||
want := containerSpec(d.Resources[0].(*declaration.Container), inputs{})
|
||||
|
||||
var ran bool
|
||||
run := func(ctx context.Context, name string, args ...string) (string, error) {
|
||||
@@ -232,7 +232,7 @@ func TestARunOnceStepRunsAgainWhenWhatItReadsChanged(t *testing.T) {
|
||||
was := map[string]string{"env": declaredDigest(&declaration.File{Content: "ACME_ROOTS=https://10.0.0.1/roots.pem\n"})}
|
||||
known := store.State{}
|
||||
known.Record(store.Applied{ID: "trust", Type: "container", Origin: store.OriginCarried, Target: "trust",
|
||||
Wrote: containerSpec(d.Resources[1].(*declaration.Container), was)})
|
||||
Wrote: containerSpec(d.Resources[1].(*declaration.Container), inputs{declares: was})})
|
||||
|
||||
var ran bool
|
||||
run := func(ctx context.Context, name string, args ...string) (string, error) {
|
||||
@@ -262,7 +262,7 @@ func TestARunOnceStepRunsAgainWhenWhatItReadsChanged(t *testing.T) {
|
||||
settled := store.State{}
|
||||
settled.Record(store.Applied{ID: "env", Type: "file", Origin: store.OriginCarried, Target: env, Wrote: now["env"]})
|
||||
settled.Record(store.Applied{ID: "trust", Type: "container", Origin: store.OriginCarried, Target: "trust",
|
||||
Wrote: containerSpec(d.Resources[1].(*declaration.Container), now)})
|
||||
Wrote: containerSpec(d.Resources[1].(*declaration.Container), inputs{declares: now})})
|
||||
if _, _, err := Apply(context.Background(), archHost(t), d, settled, store.OriginCarried, run, nil, nil); err != nil {
|
||||
t.Fatalf("re-apply failed: %v", err)
|
||||
}
|
||||
@@ -280,7 +280,7 @@ func TestAContainerNamingARunOnceStepIsRecreatedWhenItRan(t *testing.T) {
|
||||
{"id":"server","type":"container","name":"server","image":"`+pinned+`","restart-on":["trust"]}
|
||||
]}`)
|
||||
declares := map[string]string{"trust": declaredDigest(d.Resources[0].(*declaration.Container))}
|
||||
spec := containerSpec(d.Resources[1].(*declaration.Container), declares)
|
||||
spec := containerSpec(d.Resources[1].(*declaration.Container), inputs{declares: declares})
|
||||
|
||||
var removed, created bool
|
||||
run := func(ctx context.Context, name string, args ...string) (string, error) {
|
||||
|
||||
Reference in New Issue
Block a user