Uploads an OCI image to OCI object storage, and generates a pre-authenticated request for the object, which can be used to import it into custom images.
109 lines
3.5 KiB
Go
109 lines
3.5 KiB
Go
package main
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"fmt"
|
|
"math"
|
|
"math/big"
|
|
"os"
|
|
|
|
"github.com/osbuild/osbuild-composer/internal/upload/oci"
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
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()
|
|
|
|
err = uploader.Upload(objectName, bucketName, bucketNamespace, file)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to upload the image: %v", err)
|
|
}
|
|
|
|
imageID, err := uploader.CreateImage(objectName, bucketName, bucketNamespace, compartment, fileName)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to create the image from storage object: %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 := os.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
|
|
}
|