...

Source file src/edge-infra.dev/pkg/f8n/warehouse/lift/cmd/flatten/flatten.go

Documentation: edge-infra.dev/pkg/f8n/warehouse/lift/cmd/flatten

     1  package flatten
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"log"
     7  
     8  	v1 "github.com/google/go-containerregistry/pkg/v1"
     9  
    10  	"edge-infra.dev/pkg/f8n/warehouse"
    11  	"edge-infra.dev/pkg/f8n/warehouse/lift"
    12  	"edge-infra.dev/pkg/f8n/warehouse/lift/cmd/internal"
    13  	"edge-infra.dev/pkg/f8n/warehouse/oci"
    14  	"edge-infra.dev/pkg/f8n/warehouse/oci/layout"
    15  	"edge-infra.dev/pkg/f8n/warehouse/oci/mutate"
    16  	"edge-infra.dev/pkg/f8n/warehouse/oci/name"
    17  	"edge-infra.dev/pkg/lib/cli/rags"
    18  	"edge-infra.dev/pkg/lib/cli/sink"
    19  )
    20  
    21  // TODO(aw185176): allow overriding tag?
    22  
    23  func New(cfg lift.Config) *sink.Command {
    24  	var (
    25  		packer = internal.NewPacker(cfg)
    26  		push   bool
    27  	)
    28  
    29  	cmd := &sink.Command{
    30  		Use:   "flatten [flags] <artifact>",
    31  		Short: "flatten a package by removing composite packages",
    32  		Flags: []*rags.Rag{
    33  			{
    34  				Name:  "push",
    35  				Usage: "push flattened pallet to configured Warehouse registry",
    36  				Value: &rags.Bool{Var: &push},
    37  				Short: "p",
    38  			},
    39  		},
    40  		Extensions: []sink.Extension{packer},
    41  		Exec: func(_ context.Context, r sink.Run) error {
    42  			switch len(r.Args()) {
    43  			case 0:
    44  				return fmt.Errorf("error: a package to flatten is required")
    45  			case 1:
    46  				// only valid number of r.Args()
    47  			default:
    48  				return fmt.Errorf("error: only one package can be provided")
    49  			}
    50  
    51  			if push && cfg.Repo == "" {
    52  				return fmt.Errorf("error: oci repo is required for pushing\n" +
    53  					"set one via the --warehouse-oci-repo flag or setting the " +
    54  					"WAREHOUSE_OCI_REPO environment variable")
    55  			}
    56  
    57  			artifact, err := internal.ResolveArtifact(packer, r.Args()[0])
    58  			if err != nil {
    59  				return err
    60  			}
    61  
    62  			if a, ok := artifact.(oci.Unwrapper); ok {
    63  				artifact = a.Unwrap()
    64  			}
    65  
    66  			mt, err := artifact.MediaType()
    67  			if err != nil {
    68  				return err
    69  			}
    70  			if mt.IsImage() {
    71  				log.Println("input is Image, which can't be flattened")
    72  				return nil
    73  			}
    74  
    75  			// TODO(aw185176): smooth out these APIs
    76  			idx, err := mutate.Flatten(artifact.(v1.ImageIndex))
    77  			if err != nil {
    78  				return err
    79  			}
    80  			annos, err := oci.Annotations(idx)
    81  			if err != nil {
    82  				return err
    83  			}
    84  
    85  			ref, err := name.Tag(fmt.Sprintf("%s:squashed", annos[warehouse.AnnotationName]))
    86  			if err != nil {
    87  				return fmt.Errorf("failed to parse reference for flattened index: %w", err)
    88  			}
    89  			l, err := layout.New(cfg.Cache)
    90  			if err != nil {
    91  				return err
    92  			}
    93  			if err := l.Append(ref, idx); err != nil {
    94  				return err
    95  			}
    96  			d, err := idx.Digest()
    97  			if err != nil {
    98  				return err
    99  			}
   100  
   101  			log.Printf("%s:squashed (%s)", annos[warehouse.AnnotationName], d)
   102  
   103  			return nil
   104  		},
   105  	}
   106  
   107  	return cmd
   108  }
   109  

View as plain text