github.com/buildpacks/pack@v0.33.3-0.20240516162812-884dd1837311/pkg/client/manifest_create.go (about)

     1  package client
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  
     7  	"github.com/buildpacks/imgutil"
     8  	"github.com/google/go-containerregistry/pkg/v1/types"
     9  
    10  	"github.com/buildpacks/pack/internal/style"
    11  )
    12  
    13  type CreateManifestOptions struct {
    14  	// Image index we want to create
    15  	IndexRepoName string
    16  
    17  	// Name of images we wish to add into the image index
    18  	RepoNames []string
    19  
    20  	// Media type of the index
    21  	Format types.MediaType
    22  
    23  	// true if we want to publish to an insecure registry
    24  	Insecure bool
    25  
    26  	// true if we want to push the index to a registry after creating
    27  	Publish bool
    28  }
    29  
    30  // CreateManifest implements commands.PackClient.
    31  func (c *Client) CreateManifest(ctx context.Context, opts CreateManifestOptions) (err error) {
    32  	ops := parseOptsToIndexOptions(opts)
    33  
    34  	if c.indexFactory.Exists(opts.IndexRepoName) {
    35  		return fmt.Errorf("manifest list '%s' already exists in local storage; use 'pack manifest remove' to "+
    36  			"remove it before creating a new manifest list with the same name", style.Symbol(opts.IndexRepoName))
    37  	}
    38  
    39  	index, err := c.indexFactory.CreateIndex(opts.IndexRepoName, ops...)
    40  	if err != nil {
    41  		return err
    42  	}
    43  
    44  	for _, repoName := range opts.RepoNames {
    45  		if err = c.addManifestToIndex(ctx, repoName, index); err != nil {
    46  			return err
    47  		}
    48  	}
    49  
    50  	if opts.Publish {
    51  		// push to a registry without saving a local copy
    52  		ops = append(ops, imgutil.WithPurge(true))
    53  		if err = index.Push(ops...); err != nil {
    54  			return err
    55  		}
    56  
    57  		c.logger.Infof("Successfully pushed manifest list %s to registry", style.Symbol(opts.IndexRepoName))
    58  		return nil
    59  	}
    60  
    61  	if err = index.SaveDir(); err != nil {
    62  		return fmt.Errorf("manifest list %s could not be saved to local storage: %w", style.Symbol(opts.IndexRepoName), err)
    63  	}
    64  
    65  	c.logger.Infof("Successfully created manifest list %s", style.Symbol(opts.IndexRepoName))
    66  	return nil
    67  }
    68  
    69  func parseOptsToIndexOptions(opts CreateManifestOptions) (idxOpts []imgutil.IndexOption) {
    70  	if opts.Insecure {
    71  		return []imgutil.IndexOption{
    72  			imgutil.WithMediaType(opts.Format),
    73  			imgutil.WithInsecure(),
    74  		}
    75  	}
    76  	if opts.Format == "" {
    77  		opts.Format = types.OCIImageIndex
    78  	}
    79  	return []imgutil.IndexOption{
    80  		imgutil.WithMediaType(opts.Format),
    81  	}
    82  }