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  }