constellation/image/upload/internal/cmd/upload.go

75 lines
1.8 KiB
Go

/*
Copyright (c) Edgeless Systems GmbH
SPDX-License-Identifier: AGPL-3.0-only
*/
package cmd
import (
"context"
"encoding/json"
"fmt"
"io"
"strings"
"github.com/edgelesssys/constellation/v2/internal/api/versionsapi"
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
"github.com/edgelesssys/constellation/v2/internal/osimage"
)
func uploadImage(ctx context.Context, archiveC archivist, uploadC uploader, req *osimage.UploadRequest, out io.Writer) error {
// upload to S3 archive
imageReader, err := req.ImageReader()
if err != nil {
return err
}
defer imageReader.Close()
var archiveURL string
if needsArchival(req.Provider, req.Version) {
var err error
archiveURL, err = archiveC.Archive(ctx, req.Version, strings.ToLower(req.Provider.String()), req.AttestationVariant, imageReader)
if err != nil {
return err
}
}
// upload to CSP
imageReferences, err := uploadC.Upload(ctx, req)
if err != nil {
return err
}
if len(imageReferences) == 0 {
imageReferences = []versionsapi.ImageInfoEntry{
{
CSP: req.Provider.String(),
AttestationVariant: req.AttestationVariant,
Reference: archiveURL,
},
}
}
imageInfo := versionsapi.ImageInfo{
Ref: req.Version.Ref(),
Stream: req.Version.Stream(),
Version: req.Version.Version(),
List: imageReferences,
}
if err := json.NewEncoder(out).Encode(imageInfo); err != nil {
return fmt.Errorf("uploading image: marshaling output: %w", err)
}
return nil
}
func needsArchival(provider cloudprovider.Provider, version versionsapi.Version) bool {
switch provider {
case cloudprovider.OpenStack, cloudprovider.QEMU: // image upload for some CSPs only consists of this archival step
return true
}
return version.Stream() == "stable" || version.Ref() == "-"
}