osbuild-worker: add ostree resolve job
This job resolves an ostree ref. Similar to the depsolve and container resolve jobs, this should be a dependency of a manifest job.
This commit is contained in:
parent
b01792d9dd
commit
ebeb339f96
6 changed files with 217 additions and 0 deletions
79
cmd/osbuild-worker/jobimpl-ostree-resolve.go
Normal file
79
cmd/osbuild-worker/jobimpl-ostree-resolve.go
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/osbuild/osbuild-composer/internal/ostree"
|
||||
"github.com/osbuild/osbuild-composer/internal/worker"
|
||||
"github.com/osbuild/osbuild-composer/internal/worker/clienterrors"
|
||||
)
|
||||
|
||||
type OSTreeResolveJobImpl struct {
|
||||
}
|
||||
|
||||
func setError(err error, result *worker.OSTreeResolveJobResult) {
|
||||
switch err.(type) {
|
||||
case ostree.RefError:
|
||||
result.JobError = clienterrors.WorkerClientError(
|
||||
clienterrors.ErrorOSTreeRefInvalid,
|
||||
"Invalid OSTree ref",
|
||||
err,
|
||||
)
|
||||
case ostree.ResolveRefError:
|
||||
result.JobError = clienterrors.WorkerClientError(
|
||||
clienterrors.ErrorOSTreeRefResolution,
|
||||
"Error resolving OSTree ref",
|
||||
err,
|
||||
)
|
||||
default:
|
||||
result.JobError = clienterrors.WorkerClientError(
|
||||
clienterrors.ErrorOSTreeParamsInvalid,
|
||||
"Invalid OSTree parameters or parameter combination",
|
||||
err,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func (impl *OSTreeResolveJobImpl) Run(job worker.Job) error {
|
||||
logWithId := logrus.WithField("jobId", job.Id())
|
||||
var args worker.OSTreeResolveJob
|
||||
err := job.Args(&args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
result := worker.OSTreeResolveJobResult{
|
||||
Specs: make([]worker.OSTreeResolveResultSpec, len(args.Specs)),
|
||||
}
|
||||
|
||||
logWithId.Infof("Resolving (%d) ostree commits", len(args.Specs))
|
||||
|
||||
for _, s := range args.Specs {
|
||||
reqParams := ostree.RequestParams{
|
||||
URL: s.URL,
|
||||
Ref: s.Ref,
|
||||
Parent: s.Parent,
|
||||
}
|
||||
|
||||
ref, checksum, err := ostree.ResolveParams(reqParams)
|
||||
if err != nil {
|
||||
setError(err, &result)
|
||||
break
|
||||
}
|
||||
|
||||
result.Specs = append(result.Specs, worker.OSTreeResolveResultSpec{
|
||||
URL: s.URL,
|
||||
Ref: ref,
|
||||
Checksum: checksum,
|
||||
})
|
||||
}
|
||||
|
||||
err = job.Update(&result)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error reporting job result: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
@ -465,6 +465,7 @@ func main() {
|
|||
worker.JobTypeContainerResolve: &ContainerResolveJobImpl{
|
||||
AuthFilePath: containersAuthFilePath,
|
||||
},
|
||||
worker.JobTypeOSTreeResolve: &OSTreeResolveJobImpl{},
|
||||
worker.JobTypeAWSEC2Copy: &AWSEC2CopyJobImpl{
|
||||
AWSCreds: awsCredentials,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -32,6 +32,10 @@ const (
|
|||
ErrorParsingJobArgs ClientErrorCode = 29
|
||||
ErrorContainerResolution ClientErrorCode = 30
|
||||
ErrorContainerDependency ClientErrorCode = 31
|
||||
ErrorOSTreeRefInvalid ClientErrorCode = 32
|
||||
ErrorOSTreeRefResolution ClientErrorCode = 33
|
||||
ErrorOSTreeParamsInvalid ClientErrorCode = 34
|
||||
ErrorOSTreeDependency ClientErrorCode = 35
|
||||
)
|
||||
|
||||
type ClientErrorCode int
|
||||
|
|
@ -87,6 +91,8 @@ func GetStatusCode(err *Error) StatusCode {
|
|||
return JobStatusUserInputError
|
||||
case ErrorContainerResolution:
|
||||
return JobStatusUserInputError
|
||||
case ErrorOSTreeDependency:
|
||||
return JobStatusUserInputError
|
||||
default:
|
||||
return JobStatusInternalError
|
||||
}
|
||||
|
|
@ -97,6 +103,8 @@ func (e *Error) IsDependencyError() bool {
|
|||
switch e.ID {
|
||||
case ErrorContainerDependency:
|
||||
return true
|
||||
case ErrorOSTreeDependency:
|
||||
return true
|
||||
case ErrorDepsolveDependency:
|
||||
return true
|
||||
case ErrorManifestDependency:
|
||||
|
|
|
|||
|
|
@ -256,6 +256,28 @@ type ContainerResolveJobResult struct {
|
|||
JobResult
|
||||
}
|
||||
|
||||
type OSTreeResolveSpec struct {
|
||||
URL string `json:"url"`
|
||||
Ref string `json:"ref"`
|
||||
Parent string `json:"parent"`
|
||||
}
|
||||
|
||||
type OSTreeResolveJob struct {
|
||||
Specs []OSTreeResolveSpec `json:"ostree_resolve_specs"`
|
||||
}
|
||||
|
||||
type OSTreeResolveResultSpec struct {
|
||||
URL string `json:"url"`
|
||||
Ref string `json:"ref"`
|
||||
Checksum string `json:"checksum"`
|
||||
}
|
||||
|
||||
type OSTreeResolveJobResult struct {
|
||||
Specs []OSTreeResolveResultSpec `json:"ostree_resolve_result_specs"`
|
||||
|
||||
JobResult
|
||||
}
|
||||
|
||||
type AWSEC2ShareJob struct {
|
||||
Ami string `json:"ami"`
|
||||
Region string `json:"region"`
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ const (
|
|||
JobTypeDepsolve string = "depsolve"
|
||||
JobTypeManifestIDOnly string = "manifest-id-only"
|
||||
JobTypeContainerResolve string = "container-resolve"
|
||||
JobTypeOSTreeResolve string = "ostree-resolve"
|
||||
JobTypeAWSEC2Copy string = "aws-ec2-copy"
|
||||
JobTypeAWSEC2Share string = "aws-ec2-share"
|
||||
)
|
||||
|
|
@ -160,6 +161,10 @@ func (s *Server) EnqueueContainerResolveJob(job *ContainerResolveJob, channel st
|
|||
return s.enqueue(JobTypeContainerResolve, job, nil, channel)
|
||||
}
|
||||
|
||||
func (s *Server) EnqueueOSTreeResolveJob(job *OSTreeResolveJob, channel string) (uuid.UUID, error) {
|
||||
return s.enqueue(JobTypeOSTreeResolve, job, nil, channel)
|
||||
}
|
||||
|
||||
func (s *Server) EnqueueAWSEC2CopyJob(job *AWSEC2CopyJob, parent uuid.UUID, channel string) (uuid.UUID, error) {
|
||||
return s.enqueue(JobTypeAWSEC2Copy, job, []uuid.UUID{parent}, channel)
|
||||
}
|
||||
|
|
@ -231,6 +236,13 @@ func (s *Server) JobDependencyChainErrors(id uuid.UUID) (*clienterrors.Error, er
|
|||
return nil, err
|
||||
}
|
||||
jobResult = &containerResolveJR.JobResult
|
||||
case JobTypeOSTreeResolve:
|
||||
var ostreeResolveJR OSTreeResolveJobResult
|
||||
jobInfo, err = s.OSTreeResolveJobInfo(id, &ostreeResolveJR)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
jobResult = &ostreeResolveJR.JobResult
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("unexpected job type: %s", jobType)
|
||||
|
|
@ -370,6 +382,19 @@ func (s *Server) ContainerResolveJobInfo(id uuid.UUID, result *ContainerResolveJ
|
|||
return jobInfo, nil
|
||||
}
|
||||
|
||||
func (s *Server) OSTreeResolveJobInfo(id uuid.UUID, result *OSTreeResolveJobResult) (*JobInfo, error) {
|
||||
jobInfo, err := s.jobInfo(id, result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if jobInfo.JobType != JobTypeOSTreeResolve {
|
||||
return nil, fmt.Errorf("expected %q, found %q job instead", JobTypeOSTreeResolve, jobInfo.JobType)
|
||||
}
|
||||
|
||||
return jobInfo, nil
|
||||
}
|
||||
|
||||
func (s *Server) AWSEC2CopyJobInfo(id uuid.UUID, result *AWSEC2CopyJobResult) (*JobInfo, error) {
|
||||
jobInfo, err := s.jobInfo(id, result)
|
||||
if err != nil {
|
||||
|
|
@ -684,6 +709,13 @@ func (s *Server) FinishJob(token uuid.UUID, result json.RawMessage) error {
|
|||
return err
|
||||
}
|
||||
jobResult = &containerResolveJR.JobResult
|
||||
case JobTypeOSTreeResolve:
|
||||
var ostreeResolveJR OSTreeResolveJobResult
|
||||
jobInfo, err = s.OSTreeResolveJobInfo(jobId, &ostreeResolveJR)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
jobResult = &ostreeResolveJR.JobResult
|
||||
|
||||
default:
|
||||
return fmt.Errorf("unexpected job type: %s", jobType)
|
||||
|
|
|
|||
|
|
@ -790,6 +790,16 @@ func enqueueAndFinishTestJobDependencies(s *worker.Server, deps []testJob) ([]uu
|
|||
return nil, err
|
||||
}
|
||||
|
||||
case *worker.OSTreeResolveJob:
|
||||
job := dep.main.(*worker.OSTreeResolveJob)
|
||||
if len(depUUIDs) != 0 {
|
||||
return nil, fmt.Errorf("dependencies are not supported for OSTreeResolveJob, got: %d", len(depUUIDs))
|
||||
}
|
||||
id, err = s.EnqueueOSTreeResolveJob(job, "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("unexpected job type")
|
||||
}
|
||||
|
|
@ -1467,6 +1477,71 @@ func TestJobDependencyChainErrors(t *testing.T) {
|
|||
},
|
||||
expectedError: nil,
|
||||
},
|
||||
// osbuild + manifest + depsolve + ostree resolve
|
||||
// failed ostree resolve
|
||||
{
|
||||
job: testJob{
|
||||
main: &worker.OSBuildJob{},
|
||||
deps: []testJob{
|
||||
{
|
||||
main: &worker.KojiInitJob{},
|
||||
result: &worker.KojiInitJobResult{},
|
||||
},
|
||||
{
|
||||
main: &worker.ManifestJobByID{},
|
||||
deps: []testJob{
|
||||
{
|
||||
main: &worker.OSTreeResolveJob{},
|
||||
result: &worker.OSTreeResolveJobResult{
|
||||
JobResult: worker.JobResult{
|
||||
JobError: &clienterrors.Error{
|
||||
ID: clienterrors.ErrorOSTreeRefResolution,
|
||||
Reason: "remote ostree ref not found",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
main: &worker.DepsolveJob{},
|
||||
result: &worker.DepsolveJobResult{},
|
||||
},
|
||||
},
|
||||
result: &worker.ManifestJobByIDResult{
|
||||
JobResult: worker.JobResult{
|
||||
JobError: &clienterrors.Error{
|
||||
ID: clienterrors.ErrorOSTreeDependency,
|
||||
Reason: "ostree dependency job failed",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
result: &worker.OSBuildJobResult{
|
||||
JobResult: worker.JobResult{
|
||||
JobError: &clienterrors.Error{
|
||||
ID: clienterrors.ErrorManifestDependency,
|
||||
Reason: "manifest dependency job failed",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedError: &clienterrors.Error{
|
||||
ID: clienterrors.ErrorManifestDependency,
|
||||
Reason: "manifest dependency job failed",
|
||||
Details: []*clienterrors.Error{
|
||||
{
|
||||
ID: clienterrors.ErrorOSTreeDependency,
|
||||
Reason: "ostree dependency job failed",
|
||||
Details: []*clienterrors.Error{
|
||||
{
|
||||
ID: clienterrors.ErrorOSTreeRefResolution,
|
||||
Reason: "remote ostree ref not found",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for idx, c := range cases {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue