cloudapi: support container embedding

Add support for embedding container images via the cloud API. For
this the container resolve job was plumbed into the cloud api's
handler and the API specification updated with a new `containers`
section that mimics the blueprint section with the same name.
This commit is contained in:
Christian Kellner 2022-07-27 15:52:24 +02:00 committed by Tomáš Hozza
parent 45850639a0
commit 388154d7f6
7 changed files with 341 additions and 119 deletions

View file

@ -173,6 +173,19 @@ func (h *apiHandlers) PostCompose(ctx echo.Context) error {
}
}
if request.Customizations != nil && request.Customizations.Containers != nil {
for _, c := range *request.Customizations.Containers {
bc := blueprint.Container{
Source: c.Source,
TLSVerify: c.TlsVerify,
}
if c.Name != nil {
bc.Name = *c.Name
}
bp.Containers = append(bp.Containers, bc)
}
}
if request.Customizations != nil && request.Customizations.Filesystem != nil {
var fsCustomizations []blueprint.FilesystemCustomization
for _, f := range *request.Customizations.Filesystem {

View file

@ -220,6 +220,16 @@ type ComposeStatusError struct {
// ComposeStatusValue defines model for ComposeStatusValue.
type ComposeStatusValue string
// Container defines model for Container.
type Container struct {
// Name to use for the container from the image
Name *string `json:"name,omitempty"`
Source string `json:"source"`
// Control TLS verifification
TlsVerify *bool `json:"tls_verify,omitempty"`
}
// ContainerUploadOptions defines model for ContainerUploadOptions.
type ContainerUploadOptions struct {
// Name for the created container image
@ -240,6 +250,7 @@ type ContainerUploadStatus struct {
// Customizations defines model for Customizations.
type Customizations struct {
Containers *[]Container `json:"containers,omitempty"`
Filesystem *[]Filesystem `json:"filesystem,omitempty"`
Packages *[]string `json:"packages,omitempty"`
@ -692,112 +703,114 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL
// Base64 encoded, gzipped, json marshaled Swagger object
var swaggerSpec = []string{
"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",
"R6B2l8FfAAA=",
}
// GetSwagger returns the content of the embedded swagger specification file

View file

@ -859,6 +859,11 @@ components:
Customizations:
type: object
properties:
containers:
type: array
items:
$ref: '#/components/schemas/Container'
description: Container images to embed into the final artfact
subscription:
$ref: '#/components/schemas/Subscription'
packages:
@ -902,6 +907,22 @@ components:
items:
type: string
example: "firewalld"
Container:
type: object
required:
- source
properties:
source:
type: string
desription: Reference to the container to embed
example: 'registry.example.com/image:tag'
name:
type: string
description: Name to use for the container from the image
tls_verify:
type: boolean
description: Control TLS verifification
example: true
Filesystem:
type: object
required:

View file

@ -19,6 +19,7 @@ import (
"github.com/osbuild/osbuild-composer/internal/blueprint"
"github.com/osbuild/osbuild-composer/internal/common"
"github.com/osbuild/osbuild-composer/internal/container"
"github.com/osbuild/osbuild-composer/internal/distro"
"github.com/osbuild/osbuild-composer/internal/distroregistry"
"github.com/osbuild/osbuild-composer/internal/prometheus"
@ -112,7 +113,33 @@ func (s *Server) enqueueCompose(distribution distro.Distro, bp blueprint.Bluepri
return id, HTTPErrorWithInternal(ErrorEnqueueingJob, err)
}
manifestJobID, err := s.workers.EnqueueManifestJobByID(&worker.ManifestJobByID{}, depsolveJobID, channel)
dependencies := []uuid.UUID{depsolveJobID}
var containerResolveJob uuid.UUID
if len(bp.Containers) > 0 {
job := worker.ContainerResolveJob{
Arch: ir.arch.Name(),
Specs: make([]worker.ContainerSpec, len(bp.Containers)),
}
for i, c := range bp.Containers {
job.Specs[i] = worker.ContainerSpec{
Source: c.Source,
Name: c.Name,
TLSVerify: c.TLSVerify,
}
}
jobId, err := s.workers.EnqueueContainerResolveJob(&job, channel)
if err != nil {
return id, HTTPErrorWithInternal(ErrorEnqueueingJob, err)
}
containerResolveJob = jobId
dependencies = append(dependencies, jobId)
}
manifestJobID, err := s.workers.EnqueueManifestJobByID(&worker.ManifestJobByID{}, dependencies, channel)
if err != nil {
return id, HTTPErrorWithInternal(ErrorEnqueueingJob, err)
}
@ -130,7 +157,7 @@ func (s *Server) enqueueCompose(distribution distro.Distro, bp blueprint.Bluepri
s.goroutinesGroup.Add(1)
go func() {
generateManifest(s.goroutinesCtx, s.workers, depsolveJobID, manifestJobID, ir.imageType, ir.repositories, ir.imageOptions, manifestSeed, bp.Customizations)
generateManifest(s.goroutinesCtx, s.workers, depsolveJobID, containerResolveJob, manifestJobID, ir.imageType, ir.repositories, ir.imageOptions, manifestSeed, bp.Customizations)
defer s.goroutinesGroup.Done()
}()
@ -164,7 +191,33 @@ func (s *Server) enqueueKojiCompose(taskID uint64, server, name, version, releas
return id, HTTPErrorWithInternal(ErrorEnqueueingJob, err)
}
manifestJobID, err := s.workers.EnqueueManifestJobByID(&worker.ManifestJobByID{}, depsolveJobID, channel)
var containerResolveJob uuid.UUID
dependencies := []uuid.UUID{depsolveJobID}
if len(bp.Containers) > 0 {
job := worker.ContainerResolveJob{
Arch: ir.arch.Name(),
Specs: make([]worker.ContainerSpec, len(bp.Containers)),
}
for i, c := range bp.Containers {
job.Specs[i] = worker.ContainerSpec{
Source: c.Source,
Name: c.Name,
TLSVerify: c.TLSVerify,
}
}
jobId, err := s.workers.EnqueueContainerResolveJob(&job, channel)
if err != nil {
return id, HTTPErrorWithInternal(ErrorEnqueueingJob, err)
}
containerResolveJob = jobId
dependencies = append(dependencies, jobId)
}
manifestJobID, err := s.workers.EnqueueManifestJobByID(&worker.ManifestJobByID{}, dependencies, channel)
if err != nil {
return id, HTTPErrorWithInternal(ErrorEnqueueingJob, err)
}
@ -208,7 +261,7 @@ func (s *Server) enqueueKojiCompose(taskID uint64, server, name, version, releas
// copy the image request while passing it into the goroutine to prevent data races
s.goroutinesGroup.Add(1)
go func(ir imageRequest) {
generateManifest(s.goroutinesCtx, s.workers, depsolveJobID, manifestJobID, ir.imageType, ir.repositories, ir.imageOptions, manifestSeed, bp.Customizations)
generateManifest(s.goroutinesCtx, s.workers, depsolveJobID, containerResolveJob, manifestJobID, ir.imageType, ir.repositories, ir.imageOptions, manifestSeed, bp.Customizations)
defer s.goroutinesGroup.Done()
}(ir)
}
@ -229,7 +282,7 @@ func (s *Server) enqueueKojiCompose(taskID uint64, server, name, version, releas
return id, nil
}
func generateManifest(ctx context.Context, workers *worker.Server, depsolveJobID uuid.UUID, manifestJobID uuid.UUID, imageType distro.ImageType, repos []rpmmd.RepoConfig, options distro.ImageOptions, seed int64, b *blueprint.Customizations) {
func generateManifest(ctx context.Context, workers *worker.Server, depsolveJobID, containerResolveJobID, manifestJobID uuid.UUID, imageType distro.ImageType, repos []rpmmd.RepoConfig, options distro.ImageOptions, seed int64, b *blueprint.Customizations) {
ctx, cancel := context.WithTimeout(ctx, time.Minute*5)
defer cancel()
@ -313,7 +366,36 @@ func generateManifest(ctx context.Context, workers *worker.Server, depsolveJobID
return
}
manifest, err := imageType.Manifest(b, options, repos, depsolveResults.PackageSpecs, nil, seed)
var containerSpecs []container.Spec
if len(dynArgs) == 2 {
// Container resolve job
var result worker.ContainerResolveJobResult
_, err := workers.ContainerResolveJobInfo(containerResolveJobID, &result)
if err != nil {
reason := "Error reading container resolve job status"
jobResult.JobError = clienterrors.WorkerClientError(clienterrors.ErrorReadingJobStatus, reason, nil)
return
}
if jobErr := result.JobError; jobErr != nil {
jobResult.JobError = clienterrors.WorkerClientError(clienterrors.ErrorContainerDependency, "Error in container resolve job dependency", nil)
return
}
containerSpecs = make([]container.Spec, len(result.Specs))
for i, s := range result.Specs {
containerSpecs[i].Source = s.Source
containerSpecs[i].Digest = s.Digest
containerSpecs[i].LocalName = s.Name
containerSpecs[i].TLSVerify = s.TLSVerify
containerSpecs[i].ImageID = s.ImageID
}
}
manifest, err := imageType.Manifest(b, options, repos, depsolveResults.PackageSpecs, containerSpecs, seed)
if err != nil {
reason := "Error generating manifest"
jobResult.JobError = clienterrors.WorkerClientError(clienterrors.ErrorManifestGeneration, reason, nil)

View file

@ -31,6 +31,7 @@ const (
ErrorTargetError ClientErrorCode = 28
ErrorParsingJobArgs ClientErrorCode = 29
ErrorContainerResolution ClientErrorCode = 30
ErrorContainerDependency ClientErrorCode = 31
)
type ClientErrorCode int
@ -94,6 +95,8 @@ func GetStatusCode(err *Error) StatusCode {
// IsDependencyError returns true if the error means that a dependency of a job failed
func (e *Error) IsDependencyError() bool {
switch e.ID {
case ErrorContainerDependency:
return true
case ErrorDepsolveDependency:
return true
case ErrorManifestDependency:

View file

@ -146,8 +146,11 @@ func (s *Server) EnqueueDepsolve(job *DepsolveJob, channel string) (uuid.UUID, e
return s.enqueue(JobTypeDepsolve, job, nil, channel)
}
func (s *Server) EnqueueManifestJobByID(job *ManifestJobByID, parent uuid.UUID, channel string) (uuid.UUID, error) {
return s.enqueue(JobTypeManifestIDOnly, job, []uuid.UUID{parent}, channel)
func (s *Server) EnqueueManifestJobByID(job *ManifestJobByID, dependencies []uuid.UUID, channel string) (uuid.UUID, error) {
if len(dependencies) == 0 {
panic("EnqueueManifestJobByID has no dependencies, expected at least a depsolve job")
}
return s.enqueue(JobTypeManifestIDOnly, job, dependencies, channel)
}
func (s *Server) EnqueueContainerResolveJob(job *ContainerResolveJob, channel string) (uuid.UUID, error) {
@ -622,6 +625,14 @@ func (s *Server) FinishJob(token uuid.UUID, result json.RawMessage) error {
}
jobResult = &kojiFinalizeJR.JobResult
case JobTypeContainerResolve:
var containerResolveJR ContainerResolveJobResult
jobInfo, err = s.ContainerResolveJobInfo(jobId, &containerResolveJR)
if err != nil {
return err
}
jobResult = &containerResolveJR.JobResult
default:
return fmt.Errorf("unexpected job type: %s", jobType)
}

View file

@ -372,7 +372,7 @@ func TestRequestJobById(t *testing.T) {
depsolveJobId, err := server.EnqueueDepsolve(&worker.DepsolveJob{}, "")
require.NoError(t, err)
jobId, err := server.EnqueueManifestJobByID(&worker.ManifestJobByID{}, depsolveJobId, "")
jobId, err := server.EnqueueManifestJobByID(&worker.ManifestJobByID{}, []uuid.UUID{depsolveJobId}, "")
require.NoError(t, err)
test.TestRoute(t, server.Handler(), false, "POST", "/api/worker/v1/jobs", fmt.Sprintf(`{"arch":"arch","types":["%s"]}`, worker.JobTypeManifestIDOnly), http.StatusBadRequest,
@ -742,10 +742,10 @@ func enqueueAndFinishTestJobDependencies(s *worker.Server, deps []testJob) ([]uu
case *worker.ManifestJobByID:
job := dep.main.(*worker.ManifestJobByID)
if len(depUUIDs) != 1 {
return nil, fmt.Errorf("exactly one dependency is expected for ManifestJobByID, got: %d", len(depUUIDs))
if len(depUUIDs) < 1 {
return nil, fmt.Errorf("at least one dependency is expected for ManifestJobByID, got: %d", len(depUUIDs))
}
id, err = s.EnqueueManifestJobByID(job, depUUIDs[0], "")
id, err = s.EnqueueManifestJobByID(job, depUUIDs, "")
if err != nil {
return nil, err
}
@ -780,6 +780,16 @@ func enqueueAndFinishTestJobDependencies(s *worker.Server, deps []testJob) ([]uu
return nil, err
}
case *worker.ContainerResolveJob:
job := dep.main.(*worker.ContainerResolveJob)
if len(depUUIDs) != 0 {
return nil, fmt.Errorf("dependencies are not supported for ContainerResolveJob, got: %d", len(depUUIDs))
}
id, err = s.EnqueueContainerResolveJob(job, "")
if err != nil {
return nil, err
}
default:
return nil, fmt.Errorf("unexpected job type")
}
@ -942,6 +952,71 @@ func TestJobDependencyChainErrors(t *testing.T) {
Reason: "empty manifest received",
},
},
// osbuild + manifest + depsolve + container resolve
// failed container resolve
{
job: testJob{
main: &worker.OSBuildJob{},
deps: []testJob{
{
main: &worker.KojiInitJob{},
result: &worker.KojiInitJobResult{},
},
{
main: &worker.ManifestJobByID{},
deps: []testJob{
{
main: &worker.ContainerResolveJob{},
result: &worker.ContainerResolveJobResult{
JobResult: worker.JobResult{
JobError: &clienterrors.Error{
ID: clienterrors.ErrorContainerResolution,
Reason: "remote container not found",
},
},
},
},
{
main: &worker.DepsolveJob{},
result: &worker.DepsolveJobResult{},
},
},
result: &worker.ManifestJobByIDResult{
JobResult: worker.JobResult{
JobError: &clienterrors.Error{
ID: clienterrors.ErrorContainerDependency,
Reason: "container 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.ErrorContainerDependency,
Reason: "container dependency job failed",
Details: []*clienterrors.Error{
{
ID: clienterrors.ErrorContainerResolution,
Reason: "remote container not found",
},
},
},
},
},
},
// koji-init + osbuild + manifest + depsolve
// failed depsolve
{
@ -1325,7 +1400,7 @@ func TestJobDependencyChainErrors(t *testing.T) {
Reason: "koji-finalize failed",
},
},
// koji-init + (osbuild + manifest + depsolve) + (osbuild + manifest + depsolve) + koji-finalize
// koji-init + (osbuild + manifest + depsolve + container resolve) + (osbuild + manifest + depsolve) + koji-finalize
// all passed
{
job: testJob{
@ -1346,6 +1421,10 @@ func TestJobDependencyChainErrors(t *testing.T) {
{
main: &worker.ManifestJobByID{},
deps: []testJob{
{
main: &worker.ContainerResolveJob{},
result: &worker.ContainerResolveJobResult{},
},
{
main: &worker.DepsolveJob{},
result: &worker.DepsolveJobResult{},