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{
|
worker.JobTypeContainerResolve: &ContainerResolveJobImpl{
|
||||||
AuthFilePath: containersAuthFilePath,
|
AuthFilePath: containersAuthFilePath,
|
||||||
},
|
},
|
||||||
|
worker.JobTypeOSTreeResolve: &OSTreeResolveJobImpl{},
|
||||||
worker.JobTypeAWSEC2Copy: &AWSEC2CopyJobImpl{
|
worker.JobTypeAWSEC2Copy: &AWSEC2CopyJobImpl{
|
||||||
AWSCreds: awsCredentials,
|
AWSCreds: awsCredentials,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,10 @@ const (
|
||||||
ErrorParsingJobArgs ClientErrorCode = 29
|
ErrorParsingJobArgs ClientErrorCode = 29
|
||||||
ErrorContainerResolution ClientErrorCode = 30
|
ErrorContainerResolution ClientErrorCode = 30
|
||||||
ErrorContainerDependency ClientErrorCode = 31
|
ErrorContainerDependency ClientErrorCode = 31
|
||||||
|
ErrorOSTreeRefInvalid ClientErrorCode = 32
|
||||||
|
ErrorOSTreeRefResolution ClientErrorCode = 33
|
||||||
|
ErrorOSTreeParamsInvalid ClientErrorCode = 34
|
||||||
|
ErrorOSTreeDependency ClientErrorCode = 35
|
||||||
)
|
)
|
||||||
|
|
||||||
type ClientErrorCode int
|
type ClientErrorCode int
|
||||||
|
|
@ -87,6 +91,8 @@ func GetStatusCode(err *Error) StatusCode {
|
||||||
return JobStatusUserInputError
|
return JobStatusUserInputError
|
||||||
case ErrorContainerResolution:
|
case ErrorContainerResolution:
|
||||||
return JobStatusUserInputError
|
return JobStatusUserInputError
|
||||||
|
case ErrorOSTreeDependency:
|
||||||
|
return JobStatusUserInputError
|
||||||
default:
|
default:
|
||||||
return JobStatusInternalError
|
return JobStatusInternalError
|
||||||
}
|
}
|
||||||
|
|
@ -97,6 +103,8 @@ func (e *Error) IsDependencyError() bool {
|
||||||
switch e.ID {
|
switch e.ID {
|
||||||
case ErrorContainerDependency:
|
case ErrorContainerDependency:
|
||||||
return true
|
return true
|
||||||
|
case ErrorOSTreeDependency:
|
||||||
|
return true
|
||||||
case ErrorDepsolveDependency:
|
case ErrorDepsolveDependency:
|
||||||
return true
|
return true
|
||||||
case ErrorManifestDependency:
|
case ErrorManifestDependency:
|
||||||
|
|
|
||||||
|
|
@ -256,6 +256,28 @@ type ContainerResolveJobResult struct {
|
||||||
JobResult
|
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 {
|
type AWSEC2ShareJob struct {
|
||||||
Ami string `json:"ami"`
|
Ami string `json:"ami"`
|
||||||
Region string `json:"region"`
|
Region string `json:"region"`
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ const (
|
||||||
JobTypeDepsolve string = "depsolve"
|
JobTypeDepsolve string = "depsolve"
|
||||||
JobTypeManifestIDOnly string = "manifest-id-only"
|
JobTypeManifestIDOnly string = "manifest-id-only"
|
||||||
JobTypeContainerResolve string = "container-resolve"
|
JobTypeContainerResolve string = "container-resolve"
|
||||||
|
JobTypeOSTreeResolve string = "ostree-resolve"
|
||||||
JobTypeAWSEC2Copy string = "aws-ec2-copy"
|
JobTypeAWSEC2Copy string = "aws-ec2-copy"
|
||||||
JobTypeAWSEC2Share string = "aws-ec2-share"
|
JobTypeAWSEC2Share string = "aws-ec2-share"
|
||||||
)
|
)
|
||||||
|
|
@ -160,6 +161,10 @@ func (s *Server) EnqueueContainerResolveJob(job *ContainerResolveJob, channel st
|
||||||
return s.enqueue(JobTypeContainerResolve, job, nil, channel)
|
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) {
|
func (s *Server) EnqueueAWSEC2CopyJob(job *AWSEC2CopyJob, parent uuid.UUID, channel string) (uuid.UUID, error) {
|
||||||
return s.enqueue(JobTypeAWSEC2Copy, job, []uuid.UUID{parent}, channel)
|
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
|
return nil, err
|
||||||
}
|
}
|
||||||
jobResult = &containerResolveJR.JobResult
|
jobResult = &containerResolveJR.JobResult
|
||||||
|
case JobTypeOSTreeResolve:
|
||||||
|
var ostreeResolveJR OSTreeResolveJobResult
|
||||||
|
jobInfo, err = s.OSTreeResolveJobInfo(id, &ostreeResolveJR)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
jobResult = &ostreeResolveJR.JobResult
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("unexpected job type: %s", jobType)
|
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
|
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) {
|
func (s *Server) AWSEC2CopyJobInfo(id uuid.UUID, result *AWSEC2CopyJobResult) (*JobInfo, error) {
|
||||||
jobInfo, err := s.jobInfo(id, result)
|
jobInfo, err := s.jobInfo(id, result)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -684,6 +709,13 @@ func (s *Server) FinishJob(token uuid.UUID, result json.RawMessage) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
jobResult = &containerResolveJR.JobResult
|
jobResult = &containerResolveJR.JobResult
|
||||||
|
case JobTypeOSTreeResolve:
|
||||||
|
var ostreeResolveJR OSTreeResolveJobResult
|
||||||
|
jobInfo, err = s.OSTreeResolveJobInfo(jobId, &ostreeResolveJR)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
jobResult = &ostreeResolveJR.JobResult
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("unexpected job type: %s", jobType)
|
return fmt.Errorf("unexpected job type: %s", jobType)
|
||||||
|
|
|
||||||
|
|
@ -790,6 +790,16 @@ func enqueueAndFinishTestJobDependencies(s *worker.Server, deps []testJob) ([]uu
|
||||||
return nil, err
|
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:
|
default:
|
||||||
return nil, fmt.Errorf("unexpected job type")
|
return nil, fmt.Errorf("unexpected job type")
|
||||||
}
|
}
|
||||||
|
|
@ -1467,6 +1477,71 @@ func TestJobDependencyChainErrors(t *testing.T) {
|
||||||
},
|
},
|
||||||
expectedError: nil,
|
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 {
|
for idx, c := range cases {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue