weldr: keep composes in the store

This means they are serialised and restarted in case composer is
crashed/restarted. We also need this in the future to track their
state, and allow them to be listed in the UI.

Signed-off-by: Tom Gundersen <teg@jklm.no>
This commit is contained in:
Tom Gundersen 2019-09-27 01:35:03 +02:00
parent 0dc30d7f1b
commit cad89c6650
2 changed files with 54 additions and 21 deletions

View file

@ -13,12 +13,10 @@ import (
"osbuild-composer/internal/job"
"osbuild-composer/internal/rpmmd"
"osbuild-composer/internal/target"
)
type API struct {
store *store
pendingJobs chan<- job.Job
store *store
repo rpmmd.RepoConfig
packages rpmmd.PackageList
@ -31,11 +29,10 @@ func New(repo rpmmd.RepoConfig, packages rpmmd.PackageList, logger *log.Logger,
// This needs to be shared with the worker API so that they can communicate with each other
// builds := make(chan queue.Build, 200)
api := &API{
store: newStore(initialState, stateChannel),
pendingJobs: jobs,
repo: repo,
packages: packages,
logger: logger,
store: newStore(initialState, stateChannel, jobs),
repo: repo,
packages: packages,
logger: logger,
}
// sample blueprint on first run
@ -630,16 +627,7 @@ func (api *API) composeHandler(writer http.ResponseWriter, httpRequest *http.Req
found := api.store.getBlueprint(cr.BlueprintName, &bp, &changed) // TODO: what to do with changed?
if found {
api.pendingJobs <- job.Job{
ComposeID: reply.BuildID,
Pipeline: bp.translateToPipeline(cr.ComposeType),
Targets: []target.Target{{
Name: "org.osbuild.local",
Options: target.LocalOptions{
Location: "/var/lib/osbuild-composer/" + reply.BuildID.String(),
}},
},
}
api.store.addCompose(reply.BuildID, bp, cr.ComposeType)
} else {
statusResponseError(writer, http.StatusBadRequest, "blueprint does not exist")
return

View file

@ -3,16 +3,22 @@ package weldr
import (
"encoding/json"
"log"
"osbuild-composer/internal/job"
"osbuild-composer/internal/pipeline"
"osbuild-composer/internal/target"
"sort"
"sync"
"github.com/google/uuid"
)
type store struct {
Blueprints map[string]blueprint `json:"blueprints"`
Workspace map[string]blueprint `json:"workspace"`
Blueprints map[string]blueprint `json:"blueprints"`
Workspace map[string]blueprint `json:"workspace"`
Composes map[uuid.UUID]compose `json:"composes"`
mu sync.RWMutex // protects all fields
pendingJobs chan<- job.Job
stateChannel chan<- []byte
}
@ -29,7 +35,13 @@ type blueprintPackage struct {
Version string `json:"version,omitempty"`
}
func newStore(initialState []byte, stateChannel chan<- []byte) *store {
type compose struct {
State string `json:"state"`
Pipeline pipeline.Pipeline `json:"pipeline"`
Targets []target.Target `json:"targets"`
}
func newStore(initialState []byte, stateChannel chan<- []byte, pendingJobs chan<- job.Job) *store {
var s store
if initialState != nil {
@ -45,7 +57,12 @@ func newStore(initialState []byte, stateChannel chan<- []byte) *store {
if s.Workspace == nil {
s.Workspace = make(map[string]blueprint)
}
if s.Composes == nil {
// TODO: push pending/running composes to workers again
s.Composes = make(map[uuid.UUID]compose)
}
s.stateChannel = stateChannel
s.pendingJobs = pendingJobs
return &s
}
@ -156,6 +173,34 @@ func (s *store) deleteBlueprintFromWorkspace(name string) {
})
}
func (s *store) addCompose(composeID uuid.UUID, bp blueprint, composeType string) {
pipeline := bp.translateToPipeline(composeType)
targets := []target.Target{{
Name: "org.osbuild.local",
Options: target.LocalOptions{
Location: "/var/lib/osbuild-composer/" + composeID.String(),
},
}}
s.change(func() {
s.Composes[composeID] = compose{"pending", pipeline, targets}
})
s.pendingJobs <- job.Job{
ComposeID: composeID,
Pipeline: pipeline,
Targets: targets,
}
}
func (s *store) updateCompose(composeID uuid.UUID, state string) {
s.change(func() {
compose, exists := s.Composes[composeID]
if !exists {
return
}
compose.State = state
})
}
func (b *blueprint) translateToPipeline(outputFormat string) pipeline.Pipeline {
return pipeline.Pipeline{
Assembler: pipeline.Assembler{