/* Copyright (c) Edgeless Systems GmbH SPDX-License-Identifier: AGPL-3.0-only */ package cmd import ( "fmt" "io" "os" "github.com/edgelesssys/constellation/v2/internal/logger" "github.com/edgelesssys/constellation/v2/internal/osimage" "github.com/edgelesssys/constellation/v2/internal/osimage/archive" gcpupload "github.com/edgelesssys/constellation/v2/internal/osimage/gcp" "github.com/spf13/cobra" ) // newGCPCommand returns the command that uploads an OS image to GCP. func newGCPCommand() *cobra.Command { cmd := &cobra.Command{ Use: "gcp", Short: "Upload OS image to GCP", Long: "Upload OS image to GCP.", Args: cobra.ExactArgs(0), RunE: runGCP, } cmd.Flags().String("gcp-project", "constellation-images", "GCP project to use") cmd.Flags().String("gcp-location", "europe-west3", "GCP location to use") cmd.Flags().String("gcp-bucket", "constellation-os-images", "GCP bucket to use") return cmd } func runGCP(cmd *cobra.Command, _ []string) error { workdir := os.Getenv("BUILD_WORKING_DIRECTORY") if len(workdir) > 0 { must(os.Chdir(workdir)) } flags, err := parseGCPFlags(cmd) if err != nil { return err } log := logger.New(logger.PlainLog, flags.logLevel) log.Debugf("Parsed flags: %+v", flags) archiveC, archiveCClose, err := archive.New(cmd.Context(), flags.region, flags.bucket, flags.distributionID, log) if err != nil { return err } defer func() { if err := archiveCClose(cmd.Context()); err != nil { log.Errorf("closing archive client: %v", err) } }() uploadC, err := gcpupload.New(cmd.Context(), flags.gcpProject, flags.gcpLocation, flags.gcpBucket, log) if err != nil { return fmt.Errorf("uploading image: %w", err) } file, err := os.Open(flags.rawImage) if err != nil { return fmt.Errorf("uploading image: opening image file %w", err) } defer file.Close() size, err := file.Seek(0, io.SeekEnd) if err != nil { return err } if _, err := file.Seek(0, io.SeekStart); err != nil { return err } out := cmd.OutOrStdout() if len(flags.out) > 0 { outF, err := os.Create(flags.out) if err != nil { return fmt.Errorf("uploading image: opening output file %w", err) } defer outF.Close() out = outF } uploadReq := &osimage.UploadRequest{ Provider: flags.provider, Version: flags.version, AttestationVariant: flags.attestationVariant, SecureBoot: flags.secureBoot, Size: size, Timestamp: flags.timestamp, Image: file, } if flags.secureBoot { sbDatabase, uefiVarStore, err := loadSecureBootKeys(flags.pki) if err != nil { return err } uploadReq.SBDatabase = sbDatabase uploadReq.UEFIVarStore = uefiVarStore } return uploadImage(cmd.Context(), archiveC, uploadC, uploadReq, out) }