From 0ef89aa864423cc1bedc3ff26fd0d8e883ad9e71 Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Tue, 17 Dec 2019 13:55:45 +0100 Subject: [PATCH] store: fix compose state handling on restart When restarting composer, we were not handling the compose states correctly. This resolves that as follows: * any running composes are marked as failed, * any waiting composes are put back in the pending jobs queue As a consequence of needing the ability to reinitialize the job queue, we must include the depsolved pipeline in the compose object. This is the correct thing to do, as the semantics we currently adhere to is that pipelines are depsolved when the compose is started (and restarting composer should not affect this by for instance re-depsolve the pipeline). Resolves rhbz#1784062. Signed-off-by: Tom Gundersen --- internal/store/store.go | 29 ++++++++++++++++++++++++----- internal/weldr/api_test.go | 7 +++++++ 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/internal/store/store.go b/internal/store/store.go index 48a87089f..e7cca4db7 100644 --- a/internal/store/store.go +++ b/internal/store/store.go @@ -48,6 +48,7 @@ type Compose struct { QueueStatus string `json:"queue_status"` Blueprint *blueprint.Blueprint `json:"blueprint"` OutputType string `json:"output-type"` + Pipeline *pipeline.Pipeline `json:"pipeline"` Targets []*target.Target `json:"targets"` JobCreated time.Time `json:"job_created"` JobStarted time.Time `json:"job_started"` @@ -145,6 +146,10 @@ func New(stateDir *string, distro distro.Distro) *Store { }() } + s.pendingJobs = make(chan Job, 200) + s.distro = distro + s.stateDir = stateDir + if s.Blueprints == nil { s.Blueprints = make(map[string]blueprint.Blueprint) } @@ -152,8 +157,25 @@ func New(stateDir *string, distro distro.Distro) *Store { s.Workspace = make(map[string]blueprint.Blueprint) } if s.Composes == nil { - // TODO: push waiting/running composes to workers again s.Composes = make(map[uuid.UUID]Compose) + } else { + for composeID, compose := range s.Composes { + switch compose.QueueStatus { + case "RUNNING": + // We do not support resuming an in-flight build + compose.QueueStatus = "FAILED" + s.Composes[composeID] = compose + case "WAITING": + // Push waiting composes back into the pending jobs queue + s.pendingJobs <- Job{ + ComposeID: composeID, + Distro: s.distro.Name(), + Pipeline: compose.Pipeline, + Targets: compose.Targets, + OutputType: compose.OutputType, + } + } + } } if s.Sources == nil { s.Sources = make(map[string]SourceConfig) @@ -161,10 +183,6 @@ func New(stateDir *string, distro distro.Distro) *Store { if s.BlueprintsChanges == nil { s.BlueprintsChanges = make(map[string]map[string]blueprint.Change) } - s.pendingJobs = make(chan Job, 200) - - s.distro = distro - s.stateDir = stateDir return &s } @@ -444,6 +462,7 @@ func (s *Store) PushCompose(composeID uuid.UUID, bp *blueprint.Blueprint, checks s.Composes[composeID] = Compose{ QueueStatus: "WAITING", Blueprint: bp, + Pipeline: pipeline, OutputType: composeType, Targets: targets, JobCreated: time.Now(), diff --git a/internal/weldr/api_test.go b/internal/weldr/api_test.go index 99c784d81..e4e835183 100644 --- a/internal/weldr/api_test.go +++ b/internal/weldr/api_test.go @@ -345,6 +345,13 @@ func TestCompose(t *testing.T) { break } + if compose.Pipeline == nil { + t.Fatalf("%s: the compose in the store did not contain a blueprint", c.Path) + } else { + // TODO: find some (reasonable) way to verify the contents of the pipeline + compose.Pipeline = nil + } + if diff := cmp.Diff(compose, *c.ExpectedCompose, test.IgnoreDates(), test.IgnoreUuids(), test.Ignore("Targets.Options.Location")); diff != "" { t.Errorf("%s: compose in store isn't the same as expected, diff:\n%s", c.Path, diff) }