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 }