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

     1  package client
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"fmt"
     7  
     8  	"github.com/buildpacks/imgutil"
     9  	"github.com/google/go-containerregistry/pkg/name"
    10  
    11  	"github.com/buildpacks/pack/internal/builder"
    12  	"github.com/buildpacks/pack/internal/config"
    13  	"github.com/buildpacks/pack/internal/registry"
    14  	"github.com/buildpacks/pack/internal/style"
    15  	"github.com/buildpacks/pack/pkg/image"
    16  	"github.com/buildpacks/pack/pkg/logging"
    17  )
    18  
    19  func (c *Client) addManifestToIndex(ctx context.Context, repoName string, index imgutil.ImageIndex) error {
    20  	imageRef, err := name.ParseReference(repoName, name.WeakValidation)
    21  	if err != nil {
    22  		return fmt.Errorf("'%s' is not a valid manifest reference: %s", style.Symbol(repoName), err)
    23  	}
    24  
    25  	imageToAdd, err := c.imageFetcher.Fetch(ctx, imageRef.Name(), image.FetchOptions{Daemon: false})
    26  	if err != nil {
    27  		return err
    28  	}
    29  
    30  	index.AddManifest(imageToAdd.UnderlyingImage())
    31  	return nil
    32  }
    33  
    34  func (c *Client) parseTagReference(imageName string) (name.Reference, error) {
    35  	if imageName == "" {
    36  		return nil, errors.New("image is a required parameter")
    37  	}
    38  	if _, err := name.ParseReference(imageName, name.WeakValidation); err != nil {
    39  		return nil, fmt.Errorf("'%s' is not a valid tag reference: %s", imageName, err)
    40  	}
    41  	ref, err := name.NewTag(imageName, name.WeakValidation)
    42  	if err != nil {
    43  		return nil, fmt.Errorf("'%s' is not a tag reference", imageName)
    44  	}
    45  
    46  	return ref, nil
    47  }
    48  
    49  func (c *Client) resolveRunImage(runImage, imgRegistry, bldrRegistry string, runImageMetadata builder.RunImageMetadata, additionalMirrors map[string][]string, publish bool, options image.FetchOptions) string {
    50  	if runImage != "" {
    51  		c.logger.Debugf("Using provided run-image %s", style.Symbol(runImage))
    52  		return runImage
    53  	}
    54  
    55  	preferredRegistry := bldrRegistry
    56  	if publish || bldrRegistry == "" {
    57  		preferredRegistry = imgRegistry
    58  	}
    59  
    60  	runImageName := getBestRunMirror(
    61  		preferredRegistry,
    62  		runImageMetadata.Image,
    63  		runImageMetadata.Mirrors,
    64  		additionalMirrors[runImageMetadata.Image],
    65  		c.imageFetcher,
    66  		options,
    67  	)
    68  
    69  	switch {
    70  	case runImageName == runImageMetadata.Image:
    71  		c.logger.Debugf("Selected run image %s", style.Symbol(runImageName))
    72  	case contains(runImageMetadata.Mirrors, runImageName):
    73  		c.logger.Debugf("Selected run image mirror %s", style.Symbol(runImageName))
    74  	default:
    75  		c.logger.Debugf("Selected run image mirror %s from local config", style.Symbol(runImageName))
    76  	}
    77  	return runImageName
    78  }
    79  
    80  func getRegistry(logger logging.Logger, registryName string) (registry.Cache, error) {
    81  	home, err := config.PackHome()
    82  	if err != nil {
    83  		return registry.Cache{}, err
    84  	}
    85  
    86  	if err := config.MkdirAll(home); err != nil {
    87  		return registry.Cache{}, err
    88  	}
    89  
    90  	cfg, err := getConfig()
    91  	if err != nil {
    92  		return registry.Cache{}, err
    93  	}
    94  
    95  	if registryName == "" {
    96  		return registry.NewDefaultRegistryCache(logger, home)
    97  	}
    98  
    99  	for _, reg := range config.GetRegistries(cfg) {
   100  		if reg.Name == registryName {
   101  			return registry.NewRegistryCache(logger, home, reg.URL)
   102  		}
   103  	}
   104  
   105  	return registry.Cache{}, fmt.Errorf("registry %s is not defined in your config file", style.Symbol(registryName))
   106  }
   107  
   108  func getConfig() (config.Config, error) {
   109  	path, err := config.DefaultConfigPath()
   110  	if err != nil {
   111  		return config.Config{}, err
   112  	}
   113  
   114  	cfg, err := config.Read(path)
   115  	if err != nil {
   116  		return config.Config{}, err
   117  	}
   118  	return cfg, nil
   119  }
   120  
   121  func contains(slc []string, v string) bool {
   122  	for _, s := range slc {
   123  		if s == v {
   124  			return true
   125  		}
   126  	}
   127  	return false
   128  }
   129  
   130  func getBestRunMirror(registry string, runImage string, mirrors []string, preferredMirrors []string, fetcher ImageFetcher, options image.FetchOptions) string {
   131  	runImageList := filterImageList(append(append(append([]string{}, preferredMirrors...), runImage), mirrors...), fetcher, options)
   132  	for _, img := range runImageList {
   133  		ref, err := name.ParseReference(img, name.WeakValidation)
   134  		if err != nil {
   135  			continue
   136  		}
   137  		if reg := ref.Context().RegistryStr(); reg == registry {
   138  			return img
   139  		}
   140  	}
   141  
   142  	if len(runImageList) > 0 {
   143  		return runImageList[0]
   144  	}
   145  
   146  	return runImage
   147  }
   148  
   149  func filterImageList(imageList []string, fetcher ImageFetcher, options image.FetchOptions) []string {
   150  	var accessibleImages []string
   151  
   152  	for i, img := range imageList {
   153  		if fetcher.CheckReadAccess(img, options) {
   154  			accessibleImages = append(accessibleImages, imageList[i])
   155  		}
   156  	}
   157  
   158  	return accessibleImages
   159  }