github.com/docker/cnab-to-oci@v0.3.0-beta4/cmd/cnab-to-oci/fixup.go (about) 1 package main 2 3 import ( 4 "context" 5 "fmt" 6 "io/ioutil" 7 "os" 8 9 "github.com/cnabio/cnab-go/bundle" 10 containerdRemotes "github.com/containerd/containerd/remotes" 11 "github.com/docker/cli/cli/config" 12 "github.com/docker/cnab-to-oci/remotes" 13 "github.com/docker/distribution/reference" 14 "github.com/docker/go/canonical/json" 15 "github.com/spf13/cobra" 16 ) 17 18 type fixupOptions struct { 19 input string 20 bundle string 21 relocationMap string 22 targetRef string 23 insecureRegistries []string 24 autoUpdateBundle bool 25 } 26 27 func fixupCmd() *cobra.Command { 28 var opts fixupOptions 29 cmd := &cobra.Command{ 30 Use: "fixup <bundle file> [options]", 31 Short: "Fixes the digest of an image", 32 Long: "The fixup command resolves all the digest references from a registry and patches the bundle.json with them.", 33 Args: cobra.ExactArgs(1), 34 RunE: func(cmd *cobra.Command, args []string) error { 35 opts.input = args[0] 36 return runFixup(opts) 37 }, 38 } 39 cmd.Flags().StringVar(&opts.bundle, "bundle", "fixed-bundle.json", "fixed bundle output file (- to print on standard output)") 40 cmd.Flags().StringVar(&opts.relocationMap, "relocation-map", "relocation-map.json", "relocation map output file (- to print on standard output)") 41 cmd.Flags().StringVarP(&opts.targetRef, "target", "t", "", "reference where the bundle will be pushed") 42 cmd.Flags().StringSliceVar(&opts.insecureRegistries, "insecure-registries", nil, "Use plain HTTP for those registries") 43 cmd.Flags().BoolVar(&opts.autoUpdateBundle, "auto-update-bundle", false, "Updates the bundle image properties with the one resolved on the registry") 44 return cmd 45 } 46 47 func runFixup(opts fixupOptions) error { 48 var b bundle.Bundle 49 bundleJSON, err := ioutil.ReadFile(opts.input) 50 if err != nil { 51 return err 52 } 53 if err := json.Unmarshal(bundleJSON, &b); err != nil { 54 return err 55 } 56 ref, err := reference.ParseNormalizedNamed(opts.targetRef) 57 if err != nil { 58 return err 59 } 60 61 fixupOptions := []remotes.FixupOption{ 62 remotes.WithEventCallback(displayEvent), 63 } 64 if opts.autoUpdateBundle { 65 fixupOptions = append(fixupOptions, remotes.WithAutoBundleUpdate()) 66 } 67 relocationMap, err := remotes.FixupBundle(context.Background(), &b, ref, createResolver(opts.insecureRegistries), fixupOptions...) 68 if err != nil { 69 return err 70 } 71 if err := writeOutput(opts.bundle, b); err != nil { 72 return err 73 } 74 return writeOutput(opts.relocationMap, relocationMap) 75 } 76 77 func displayEvent(ev remotes.FixupEvent) { 78 switch ev.EventType { 79 case remotes.FixupEventTypeCopyImageStart: 80 fmt.Fprintf(os.Stderr, "Starting to copy image %s...\n", ev.SourceImage) 81 case remotes.FixupEventTypeCopyImageEnd: 82 if ev.Error != nil { 83 fmt.Fprintf(os.Stderr, "Failed to copy image %s: %s\n", ev.SourceImage, ev.Error) 84 } else { 85 fmt.Fprintf(os.Stderr, "Completed image %s copy\n", ev.SourceImage) 86 } 87 } 88 } 89 90 func createResolver(insecureRegistries []string) containerdRemotes.Resolver { 91 return remotes.CreateResolver(config.LoadDefaultConfigFile(os.Stderr), insecureRegistries...) 92 }