drop the Compose.Image field
Everything that this field contained can be computed in another way: - path: just lookup the local target and read the path from there - mime: can be derived from distribution and compose output type - size: can be derived from the path Therefore it imho doesn't make much sense to store these information multiple times.
This commit is contained in:
parent
a9633d29e9
commit
cc00e0cdc9
6 changed files with 68 additions and 66 deletions
|
|
@ -6,7 +6,6 @@ import (
|
|||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/osbuild/osbuild-composer/internal/compose"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
|
|
@ -55,9 +54,9 @@ func (c *ComposerClient) AddJob() (*jobqueue.Job, error) {
|
|||
return job, nil
|
||||
}
|
||||
|
||||
func (c *ComposerClient) UpdateJob(job *jobqueue.Job, status common.ImageBuildState, image *compose.Image, result *common.ComposeResult) error {
|
||||
func (c *ComposerClient) UpdateJob(job *jobqueue.Job, status common.ImageBuildState, result *common.ComposeResult) error {
|
||||
var b bytes.Buffer
|
||||
json.NewEncoder(&b).Encode(&jobqueue.JobStatus{status, job.ImageBuildID, image, result})
|
||||
json.NewEncoder(&b).Encode(&jobqueue.JobStatus{status, job.ImageBuildID, result})
|
||||
req, err := http.NewRequest("PATCH", "http://localhost/job-queue/v1/jobs/"+job.ID.String(), &b)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -84,19 +83,19 @@ func handleJob(client *ComposerClient) error {
|
|||
return err
|
||||
}
|
||||
|
||||
err = client.UpdateJob(job, common.IBRunning, nil, nil)
|
||||
err = client.UpdateJob(job, common.IBRunning, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("Running job %s\n", job.ID.String())
|
||||
image, result, err := job.Run()
|
||||
result, err := job.Run()
|
||||
if err != nil {
|
||||
log.Printf(" Job failed: %v", err)
|
||||
return client.UpdateJob(job, common.IBFailed, nil, result)
|
||||
return client.UpdateJob(job, common.IBFailed, result)
|
||||
}
|
||||
|
||||
return client.UpdateJob(job, common.IBFinished, image, result)
|
||||
return client.UpdateJob(job, common.IBFinished, result)
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
|
|
|||
|
|
@ -71,6 +71,16 @@ func (ib *ImageBuild) DeepCopy() ImageBuild {
|
|||
}
|
||||
}
|
||||
|
||||
func (ib *ImageBuild) GetLocalTarget() *target.LocalTargetOptions {
|
||||
for _, t := range ib.Targets {
|
||||
if localTarget, ok := t.Options.(*target.LocalTargetOptions); ok {
|
||||
return localTarget
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// A Compose represent the task of building a set of images from a single blueprint.
|
||||
// It contains all the information necessary to generate the inputs for the job, as
|
||||
// well as the job's state.
|
||||
|
|
|
|||
|
|
@ -94,12 +94,12 @@ func (api *API) addJobHandler(writer http.ResponseWriter, request *http.Request,
|
|||
writer.WriteHeader(http.StatusCreated)
|
||||
// FIXME: handle or comment this possible error
|
||||
_ = json.NewEncoder(writer).Encode(Job{
|
||||
ID: nextJob.ComposeID,
|
||||
ID: nextJob.ComposeID,
|
||||
ImageBuildID: nextJob.ImageBuildID,
|
||||
Distro: nextJob.Distro,
|
||||
Pipeline: nextJob.Pipeline,
|
||||
Targets: nextJob.Targets,
|
||||
OutputType: nextJob.ImageType,
|
||||
Distro: nextJob.Distro,
|
||||
Pipeline: nextJob.Pipeline,
|
||||
Targets: nextJob.Targets,
|
||||
OutputType: nextJob.ImageType,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -123,7 +123,7 @@ func (api *API) updateJobHandler(writer http.ResponseWriter, request *http.Reque
|
|||
return
|
||||
}
|
||||
|
||||
err = api.store.UpdateImageBuildInCompose(id, body.ImageBuildID, body.Status, body.Image, body.Result)
|
||||
err = api.store.UpdateImageBuildInCompose(id, body.ImageBuildID, body.Status, body.Result)
|
||||
if err != nil {
|
||||
switch err.(type) {
|
||||
case *store.NotFoundError:
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ package jobqueue
|
|||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/osbuild/osbuild-composer/internal/compose"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
|
|
@ -29,7 +28,6 @@ type Job struct {
|
|||
type JobStatus struct {
|
||||
Status common.ImageBuildState `json:"status"`
|
||||
ImageBuildID int `json:"image_build_id"`
|
||||
Image *compose.Image `json:"image"`
|
||||
Result *common.ComposeResult `json:"result"`
|
||||
}
|
||||
|
||||
|
|
@ -47,11 +45,11 @@ func (e *TargetsError) Error() string {
|
|||
return errString
|
||||
}
|
||||
|
||||
func (job *Job) Run() (*compose.Image, *common.ComposeResult, error) {
|
||||
func (job *Job) Run() (*common.ComposeResult, error) {
|
||||
distros := distro.NewRegistry([]string{"/etc/osbuild-composer", "/usr/share/osbuild-composer"})
|
||||
d := distros.GetDistro(job.Distro)
|
||||
if d == nil {
|
||||
return nil, nil, fmt.Errorf("unknown distro: %s", job.Distro)
|
||||
return nil, fmt.Errorf("unknown distro: %s", job.Distro)
|
||||
}
|
||||
|
||||
build := pipeline.Build{
|
||||
|
|
@ -60,19 +58,19 @@ func (job *Job) Run() (*compose.Image, *common.ComposeResult, error) {
|
|||
|
||||
buildFile, err := ioutil.TempFile("", "osbuild-worker-build-env-*")
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, err
|
||||
}
|
||||
// FIXME: how to handle errors in defer?
|
||||
defer os.Remove(buildFile.Name())
|
||||
|
||||
err = json.NewEncoder(buildFile).Encode(build)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error encoding build environment: %v", err)
|
||||
return nil, fmt.Errorf("error encoding build environment: %v", err)
|
||||
}
|
||||
|
||||
tmpStore, err := ioutil.TempDir("/var/tmp", "osbuild-store")
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error setting up osbuild store: %v", err)
|
||||
return nil, fmt.Errorf("error setting up osbuild store: %v", err)
|
||||
}
|
||||
// FIXME: how to handle errors in defer?
|
||||
defer os.RemoveAll(tmpStore)
|
||||
|
|
@ -87,22 +85,22 @@ func (job *Job) Run() (*compose.Image, *common.ComposeResult, error) {
|
|||
|
||||
stdin, err := cmd.StdinPipe()
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error setting up stdin for osbuild: %v", err)
|
||||
return nil, fmt.Errorf("error setting up stdin for osbuild: %v", err)
|
||||
}
|
||||
|
||||
stdout, err := cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error setting up stdout for osbuild: %v", err)
|
||||
return nil, fmt.Errorf("error setting up stdout for osbuild: %v", err)
|
||||
}
|
||||
|
||||
err = cmd.Start()
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error starting osbuild: %v", err)
|
||||
return nil, fmt.Errorf("error starting osbuild: %v", err)
|
||||
}
|
||||
|
||||
err = json.NewEncoder(stdin).Encode(job.Pipeline)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error encoding osbuild pipeline: %v", err)
|
||||
return nil, fmt.Errorf("error encoding osbuild pipeline: %v", err)
|
||||
}
|
||||
// FIXME: handle or comment this possible error
|
||||
_ = stdin.Close()
|
||||
|
|
@ -110,21 +108,14 @@ func (job *Job) Run() (*compose.Image, *common.ComposeResult, error) {
|
|||
var result common.ComposeResult
|
||||
err = json.NewDecoder(stdout).Decode(&result)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error decoding osbuild output: %#v", err)
|
||||
return nil, fmt.Errorf("error decoding osbuild output: %#v", err)
|
||||
}
|
||||
|
||||
err = cmd.Wait()
|
||||
if err != nil {
|
||||
return nil, &result, err
|
||||
return &result, err
|
||||
}
|
||||
|
||||
filename, mimeType, err := d.FilenameFromType(job.OutputType)
|
||||
if err != nil {
|
||||
return nil, &result, fmt.Errorf("cannot fetch information about output type %s: %v", job.OutputType, err)
|
||||
}
|
||||
|
||||
var image compose.Image
|
||||
|
||||
var r []error
|
||||
|
||||
for _, t := range job.Targets {
|
||||
|
|
@ -143,24 +134,6 @@ func (job *Job) Run() (*compose.Image, *common.ComposeResult, error) {
|
|||
continue
|
||||
}
|
||||
|
||||
imagePath := options.Location + "/" + filename
|
||||
file, err := os.Open(imagePath)
|
||||
if err != nil {
|
||||
r = append(r, err)
|
||||
continue
|
||||
}
|
||||
|
||||
fileStat, err := file.Stat()
|
||||
if err != nil {
|
||||
return nil, &result, err
|
||||
}
|
||||
|
||||
image = compose.Image{
|
||||
Path: imagePath,
|
||||
Mime: mimeType,
|
||||
Size: uint64(fileStat.Size()),
|
||||
}
|
||||
|
||||
case *target.AWSTargetOptions:
|
||||
|
||||
a, err := awsupload.New(options.Region, options.AccessKeyID, options.SecretAccessKey)
|
||||
|
|
@ -192,10 +165,10 @@ func (job *Job) Run() (*compose.Image, *common.ComposeResult, error) {
|
|||
}
|
||||
|
||||
if len(r) > 0 {
|
||||
return nil, &result, &TargetsError{r}
|
||||
return &result, &TargetsError{r}
|
||||
}
|
||||
|
||||
return &image, &result, nil
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func runCommand(command string, params ...string) error {
|
||||
|
|
|
|||
|
|
@ -683,7 +683,7 @@ func (s *Store) PopJob() Job {
|
|||
}
|
||||
|
||||
// UpdateImageBuildInCompose sets the status and optionally also the final image.
|
||||
func (s *Store) UpdateImageBuildInCompose(composeID uuid.UUID, imageBuildID int, status common.ImageBuildState, image *compose.Image, result *common.ComposeResult) error {
|
||||
func (s *Store) UpdateImageBuildInCompose(composeID uuid.UUID, imageBuildID int, status common.ImageBuildState, result *common.ComposeResult) error {
|
||||
return s.change(func() error {
|
||||
// Check that the compose exists
|
||||
currentCompose, exists := s.Composes[composeID]
|
||||
|
|
@ -717,9 +717,6 @@ func (s *Store) UpdateImageBuildInCompose(composeID uuid.UUID, imageBuildID int,
|
|||
// In case the image build is done, store the time and possibly also the image
|
||||
if status == common.IBFinished || status == common.IBFailed {
|
||||
currentCompose.ImageBuilds[imageBuildID].JobFinished = time.Now()
|
||||
if status == common.IBFinished {
|
||||
currentCompose.ImageBuilds[imageBuildID].Image = image
|
||||
}
|
||||
}
|
||||
|
||||
s.Composes[composeID] = currentCompose
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ import (
|
|||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
|
@ -1566,18 +1565,31 @@ func (api *API) composeImageHandler(writer http.ResponseWriter, request *http.Re
|
|||
return
|
||||
}
|
||||
|
||||
if compose.ImageBuilds[0].Image == nil {
|
||||
imageBuild := compose.ImageBuilds[0]
|
||||
localTarget := imageBuild.GetLocalTarget()
|
||||
|
||||
if localTarget == nil {
|
||||
errors := responseError{
|
||||
ID: "BuildMissingFile",
|
||||
Msg: fmt.Sprintf("Compose %s doesn't have an image assigned", uuidString),
|
||||
ID: "BadCompose",
|
||||
Msg: fmt.Sprintf("Compose %s is ill-formed: it doesn't contain LocalTarget", uuidString),
|
||||
}
|
||||
statusResponseError(writer, http.StatusBadRequest, errors)
|
||||
statusResponseError(writer, http.StatusInternalServerError, errors)
|
||||
return
|
||||
}
|
||||
|
||||
imageName := filepath.Base(compose.ImageBuilds[0].Image.Path)
|
||||
imageType, _ := imageBuild.ImageType.ToCompatString()
|
||||
imageName, imageMime, err := api.distro.FilenameFromType(imageType)
|
||||
|
||||
file, err := os.Open(compose.ImageBuilds[0].Image.Path)
|
||||
if err != nil {
|
||||
errors := responseError{
|
||||
ID: "BadCompose",
|
||||
Msg: fmt.Sprintf("Compose %s is ill-formed: output type %v is invalid for distro %s", uuidString, imageBuild.ImageType, api.distro.Name()),
|
||||
}
|
||||
statusResponseError(writer, http.StatusInternalServerError, errors)
|
||||
return
|
||||
}
|
||||
|
||||
file, err := os.Open(localTarget.Location + "/" + imageName)
|
||||
if err != nil {
|
||||
errors := responseError{
|
||||
ID: "BuildMissingFile",
|
||||
|
|
@ -1587,9 +1599,20 @@ func (api *API) composeImageHandler(writer http.ResponseWriter, request *http.Re
|
|||
return
|
||||
}
|
||||
|
||||
stat, err := file.Stat()
|
||||
|
||||
if err != nil {
|
||||
errors := responseError{
|
||||
ID: "BuildStatFailed",
|
||||
Msg: fmt.Sprintf("Cannot stat image for build %s!", uuidString),
|
||||
}
|
||||
statusResponseError(writer, http.StatusBadRequest, errors)
|
||||
return
|
||||
}
|
||||
|
||||
writer.Header().Set("Content-Disposition", "attachment; filename="+uuid.String()+"-"+imageName)
|
||||
writer.Header().Set("Content-Type", compose.ImageBuilds[0].Image.Mime)
|
||||
writer.Header().Set("Content-Length", fmt.Sprintf("%d", compose.ImageBuilds[0].Image.Size))
|
||||
writer.Header().Set("Content-Type", imageMime)
|
||||
writer.Header().Set("Content-Length", fmt.Sprintf("%d", stat.Size()))
|
||||
|
||||
io.Copy(writer, file)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue