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

     1  package index
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"path/filepath"
     7  
     8  	"github.com/buildpacks/imgutil"
     9  	"github.com/buildpacks/imgutil/layout"
    10  	"github.com/buildpacks/imgutil/remote"
    11  	"github.com/google/go-containerregistry/pkg/authn"
    12  	"github.com/pkg/errors"
    13  )
    14  
    15  type IndexFactory struct {
    16  	keychain authn.Keychain
    17  	path     string
    18  }
    19  
    20  func NewIndexFactory(keychain authn.Keychain, path string) *IndexFactory {
    21  	return &IndexFactory{
    22  		keychain: keychain,
    23  		path:     path,
    24  	}
    25  }
    26  
    27  func (f *IndexFactory) Exists(repoName string) bool {
    28  	return layoutImageExists(f.localPath(repoName))
    29  }
    30  
    31  func (f *IndexFactory) LoadIndex(repoName string, opts ...imgutil.IndexOption) (index imgutil.ImageIndex, err error) {
    32  	if !f.Exists(repoName) {
    33  		return nil, errors.New(fmt.Sprintf("Image: '%s' not found", repoName))
    34  	}
    35  	opts = appendOption(opts, imgutil.FromBaseIndex(f.localPath(repoName)))
    36  	return layout.NewIndex(repoName, appendDefaultOptions(opts, f.keychain, f.path)...)
    37  }
    38  
    39  func (f *IndexFactory) FetchIndex(name string, opts ...imgutil.IndexOption) (idx imgutil.ImageIndex, err error) {
    40  	return remote.NewIndex(name, appendDefaultOptions(opts, f.keychain, f.path)...)
    41  }
    42  
    43  func (f *IndexFactory) FindIndex(repoName string, opts ...imgutil.IndexOption) (idx imgutil.ImageIndex, err error) {
    44  	if f.Exists(repoName) {
    45  		return f.LoadIndex(repoName, opts...)
    46  	}
    47  	return f.FetchIndex(repoName, opts...)
    48  }
    49  
    50  func (f *IndexFactory) CreateIndex(repoName string, opts ...imgutil.IndexOption) (idx imgutil.ImageIndex, err error) {
    51  	return layout.NewIndex(repoName, appendDefaultOptions(opts, f.keychain, f.path)...)
    52  }
    53  
    54  func (f *IndexFactory) localPath(repoName string) string {
    55  	return filepath.Join(f.path, imgutil.MakeFileSafeName(repoName))
    56  }
    57  
    58  func layoutImageExists(path string) bool {
    59  	if !pathExists(path) {
    60  		return false
    61  	}
    62  	index := filepath.Join(path, "index.json")
    63  	if _, err := os.Stat(index); os.IsNotExist(err) {
    64  		return false
    65  	}
    66  	return true
    67  }
    68  
    69  func pathExists(path string) bool {
    70  	if path != "" {
    71  		if _, err := os.Stat(path); !os.IsNotExist(err) {
    72  			return true
    73  		}
    74  	}
    75  	return false
    76  }
    77  
    78  func appendOption(ops []imgutil.IndexOption, op imgutil.IndexOption) []imgutil.IndexOption {
    79  	return append(ops, op)
    80  }
    81  
    82  func appendDefaultOptions(ops []imgutil.IndexOption, keychain authn.Keychain, path string) []imgutil.IndexOption {
    83  	return append(ops, imgutil.WithKeychain(keychain), imgutil.WithXDGRuntimePath(path))
    84  }