Add support for OCI upload provider
Signed-off-by: Roy Golan <rgolan@redhat.com>
This commit is contained in:
parent
d9051c23e6
commit
bee932e222
18 changed files with 495 additions and 4 deletions
104
cmd/osbuild-upload-oci/main.go
Normal file
104
cmd/osbuild-upload-oci/main.go
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"github.com/osbuild/osbuild-composer/internal/upload/oci"
|
||||
"github.com/spf13/cobra"
|
||||
"io/ioutil"
|
||||
"math"
|
||||
"math/big"
|
||||
"os"
|
||||
)
|
||||
|
||||
var (
|
||||
tenancy string
|
||||
region string
|
||||
userID string
|
||||
privateKeyFile string
|
||||
fingerprint string
|
||||
bucketName string
|
||||
bucketNamespace string
|
||||
fileName string
|
||||
objectName string
|
||||
compartment string
|
||||
)
|
||||
|
||||
var uploadCmd = &cobra.Command{
|
||||
Example: "This tool uses the $HOME/.oci/config file to create the OCI client and can be\noverridden using CLI flags.",
|
||||
SilenceUsage: true,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
uploader, err := uploaderFromConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
file, err := os.Open(fileName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
imageID, err := uploader.Upload(objectName, bucketName, bucketNamespace, file, compartment, fileName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to upload the image: %v", err)
|
||||
}
|
||||
|
||||
fmt.Printf("Image %s was uploaded and created successfully\n", imageID)
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
func main() {
|
||||
i, _ := rand.Int(rand.Reader, big.NewInt(math.MaxInt64))
|
||||
uploadCmd.Flags().StringVarP(&tenancy, "tenancy", "t", "", "target tenancy")
|
||||
uploadCmd.Flags().StringVarP(®ion, "region", "r", "", "target region")
|
||||
uploadCmd.Flags().StringVarP(&userID, "user-id", "u", "", "user OCI ID")
|
||||
uploadCmd.Flags().StringVarP(&bucketName, "bucket-name", "b", "", "target OCI bucket name")
|
||||
uploadCmd.Flags().StringVarP(&bucketNamespace, "bucket-namespace", "", "", "target OCI bucket namespace")
|
||||
uploadCmd.Flags().StringVarP(&fileName, "filename", "f", "", "image file to upload")
|
||||
uploadCmd.Flags().StringVarP(&objectName, "object-name", "o", fmt.Sprintf("osbuild-upload-%v", i), "the target name of the uploaded object in the bucket")
|
||||
uploadCmd.Flags().StringVarP(&privateKeyFile, "private-key", "p", "", "private key for authenticating OCI API requests")
|
||||
uploadCmd.Flags().StringVarP(&fingerprint, "fingerprint", "", "", "the private key's fingerprint")
|
||||
uploadCmd.Flags().StringVarP(&compartment, "compartment-id", "c", "", "the compartment ID of the target image")
|
||||
_ = uploadCmd.MarkFlagRequired("bucket-name")
|
||||
_ = uploadCmd.MarkFlagRequired("bucket-namespace")
|
||||
_ = uploadCmd.MarkFlagRequired("compartment-id")
|
||||
_ = uploadCmd.MarkFlagRequired("filename")
|
||||
if err := uploadCmd.Execute(); err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func uploaderFromConfig() (oci.Uploader, error) {
|
||||
if privateKeyFile != "" {
|
||||
if tenancy == "" || region == "" || userID == "" || fingerprint == "" {
|
||||
return nil, fmt.Errorf("when suppling a private key the following args are mandatory as well:" +
|
||||
" fingerprint, tenancy, region, and user-id")
|
||||
}
|
||||
pk, err := ioutil.ReadFile(privateKeyFile)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read private key file %w", err)
|
||||
}
|
||||
uploader, err := oci.NewClient(
|
||||
&oci.ClientParams{
|
||||
Tenancy: tenancy,
|
||||
User: userID,
|
||||
Region: region,
|
||||
PrivateKey: string(pk),
|
||||
Fingerprint: fingerprint,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create an OCI client %w", err)
|
||||
}
|
||||
return uploader, nil
|
||||
}
|
||||
|
||||
fmt.Printf("Creating an uploader from default config\n")
|
||||
uploader, err := oci.NewClient(nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return uploader, nil
|
||||
}
|
||||
|
|
@ -2,12 +2,18 @@ package main
|
|||
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"math"
|
||||
"math/big"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/osbuild/osbuild-composer/internal/upload/oci"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
|
|
@ -517,6 +523,49 @@ func (impl *OSBuildJobImpl) Run(job worker.Job) error {
|
|||
ImageName: args.Targets[0].ImageName,
|
||||
}))
|
||||
|
||||
osbuildJobResult.Success = true
|
||||
osbuildJobResult.UploadStatus = "success"
|
||||
case *target.OCITargetOptions:
|
||||
// create an ociClient uploader with a valid storage client
|
||||
var ociClient oci.Client
|
||||
ociClient, err = oci.NewClient(&oci.ClientParams{
|
||||
User: options.User,
|
||||
Region: options.Region,
|
||||
Tenancy: options.Tenancy,
|
||||
Fingerprint: options.Fingerprint,
|
||||
PrivateKey: options.PrivateKey,
|
||||
})
|
||||
if err != nil {
|
||||
appendTargetError(osbuildJobResult, fmt.Errorf("failed to create an OCI uploder: %w", err))
|
||||
return nil
|
||||
}
|
||||
log.Print("[OCI] 🔑 Logged in OCI")
|
||||
log.Print("[OCI] ⬆ Uploading the image")
|
||||
file, err := os.Open(path.Join(outputDirectory, exportPath, options.FileName))
|
||||
if err != nil {
|
||||
appendTargetError(osbuildJobResult, fmt.Errorf("failed to create an OCI uploder: %w", err))
|
||||
return nil
|
||||
}
|
||||
defer file.Close()
|
||||
i, _ := rand.Int(rand.Reader, big.NewInt(math.MaxInt64))
|
||||
imageID, err := ociClient.Upload(
|
||||
fmt.Sprintf("osbuild-upload-%d", i),
|
||||
options.Bucket,
|
||||
options.Namespace,
|
||||
file,
|
||||
options.Compartment,
|
||||
args.Targets[0].ImageName,
|
||||
)
|
||||
if err != nil {
|
||||
appendTargetError(osbuildJobResult, fmt.Errorf("failed to upload the image: %w", err))
|
||||
return nil
|
||||
}
|
||||
log.Print("[OCI] 🎉 Image uploaded and registered!")
|
||||
|
||||
osbuildJobResult.TargetResults = append(
|
||||
osbuildJobResult.TargetResults,
|
||||
target.NewOCITargetResult(&target.OCITargetResultOptions{ImageID: imageID}),
|
||||
)
|
||||
osbuildJobResult.Success = true
|
||||
osbuildJobResult.UploadStatus = "success"
|
||||
default:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue