github.com/docker/cnab-to-oci@v0.3.0-beta4/cmd/cnab-to-oci/push.go (about) 1 package main 2 3 import ( 4 "context" 5 "encoding/json" 6 "errors" 7 "fmt" 8 "io/ioutil" 9 "os" 10 11 "github.com/cnabio/cnab-go/bundle" 12 "github.com/docker/cnab-to-oci/remotes" 13 "github.com/docker/distribution/reference" 14 "github.com/docker/docker/client" 15 "github.com/spf13/cobra" 16 ) 17 18 type pushOptions struct { 19 input string 20 targetRef string 21 insecureRegistries []string 22 allowFallbacks bool 23 invocationPlatforms []string 24 componentPlatforms []string 25 autoUpdateBundle bool 26 pushImages bool 27 } 28 29 func pushCmd() *cobra.Command { 30 var opts pushOptions 31 cmd := &cobra.Command{ 32 Use: "push <bundle file> [options]", 33 Short: "Fixes and pushes the bundle to an registry", 34 Args: cobra.ExactArgs(1), 35 RunE: func(cmd *cobra.Command, args []string) error { 36 opts.input = args[0] 37 if opts.targetRef == "" { 38 return errors.New("--target flag must be set with a namespace ") 39 } 40 return runPush(opts) 41 }, 42 } 43 44 cmd.Flags().StringVarP(&opts.targetRef, "target", "t", "", "reference where the bundle will be pushed") 45 cmd.Flags().StringSliceVar(&opts.insecureRegistries, "insecure-registries", nil, "Use plain HTTP for those registries") 46 cmd.Flags().BoolVar(&opts.allowFallbacks, "allow-fallbacks", true, "Enable automatic compatibility fallbacks for registries without support for custom media type, or OCI manifests") 47 cmd.Flags().StringSliceVar(&opts.invocationPlatforms, "invocation-platforms", nil, "Platforms to push (for multi-arch invocation images)") 48 cmd.Flags().StringSliceVar(&opts.componentPlatforms, "component-platforms", nil, "Platforms to push (for multi-arch component images)") 49 cmd.Flags().BoolVar(&opts.autoUpdateBundle, "auto-update-bundle", false, "Updates the bundle image properties with the one resolved on the registry") 50 cmd.Flags().BoolVar(&opts.pushImages, "push-images", true, "Allow to push missing images in the registry that are available in the local docker daemon image store") 51 52 return cmd 53 } 54 55 func runPush(opts pushOptions) error { 56 var b bundle.Bundle 57 bundleJSON, err := ioutil.ReadFile(opts.input) 58 if err != nil { 59 return err 60 } 61 if err := json.Unmarshal(bundleJSON, &b); err != nil { 62 return err 63 } 64 resolver := createResolver(opts.insecureRegistries) 65 ref, err := reference.ParseNormalizedNamed(opts.targetRef) 66 if err != nil { 67 return err 68 } 69 70 fixupOptions := []remotes.FixupOption{ 71 remotes.WithEventCallback(displayEvent), 72 remotes.WithInvocationImagePlatforms(opts.invocationPlatforms), 73 remotes.WithComponentImagePlatforms(opts.componentPlatforms), 74 } 75 if opts.autoUpdateBundle { 76 fixupOptions = append(fixupOptions, remotes.WithAutoBundleUpdate()) 77 } 78 if opts.pushImages { 79 cli, err := client.NewClientWithOpts(client.FromEnv) 80 if err != nil { 81 return err 82 } 83 fixupOptions = append(fixupOptions, remotes.WithPushImages(cli, os.Stdout)) 84 } 85 relocationMap, err := remotes.FixupBundle(context.Background(), &b, ref, resolver, fixupOptions...) 86 if err != nil { 87 return err 88 } 89 d, err := remotes.Push(context.Background(), &b, relocationMap, ref, resolver, opts.allowFallbacks) 90 if err != nil { 91 return err 92 } 93 fmt.Printf("Pushed successfully, with digest %q\n", d.Digest) 94 return nil 95 }