github.com/redhat-appstudio/e2e-tests@v0.0.0-20240520140907-9709f6f59323/pkg/utils/build/image.go (about) 1 package build 2 3 import ( 4 "context" 5 "fmt" 6 "os" 7 "time" 8 9 "github.com/google/go-containerregistry/pkg/authn" 10 "github.com/google/go-containerregistry/pkg/name" 11 v1 "github.com/google/go-containerregistry/pkg/v1" 12 "github.com/google/go-containerregistry/pkg/v1/remote" 13 . "github.com/onsi/ginkgo/v2" 14 15 "github.com/openshift/library-go/pkg/image/reference" 16 "github.com/openshift/oc/pkg/cli/image/extract" 17 "github.com/openshift/oc/pkg/cli/image/imagesource" 18 imageInfo "github.com/openshift/oc/pkg/cli/image/info" 19 pipeline "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" 20 "k8s.io/cli-runtime/pkg/genericclioptions" 21 ) 22 23 func ExtractImage(image string) (string, error) { 24 dockerImageRef, err := reference.Parse(image) 25 if err != nil { 26 return "", fmt.Errorf("cannot parse docker pull spec (image) %s, error: %+v", image, err) 27 } 28 tmpDir, err := os.MkdirTemp(os.TempDir(), "eimage") 29 if err != nil { 30 return "", fmt.Errorf("error when creating a temp directory for extracting files: %+v", err) 31 } 32 GinkgoWriter.Printf("extracting contents of container image %s to dir: %s\n", image, tmpDir) 33 eMapping := extract.Mapping{ 34 ImageRef: imagesource.TypedImageReference{Type: "docker", Ref: dockerImageRef}, 35 To: tmpDir, 36 } 37 e := extract.NewExtractOptions(genericclioptions.IOStreams{Out: os.Stdout, ErrOut: os.Stderr}) 38 e.Mappings = []extract.Mapping{eMapping} 39 40 if err := e.Run(); err != nil { 41 return "", fmt.Errorf("error: %+v", err) 42 } 43 return tmpDir, nil 44 } 45 46 func ImageFromPipelineRun(pipelineRun *pipeline.PipelineRun) (*imageInfo.Image, error) { 47 var outputImage string 48 for _, parameter := range pipelineRun.Spec.Params { 49 if parameter.Name == "output-image" { 50 outputImage = parameter.Value.StringVal 51 } 52 } 53 if outputImage == "" { 54 return nil, fmt.Errorf("output-image in PipelineRun not found") 55 } 56 57 dockerImageRef, err := reference.Parse(outputImage) 58 if err != nil { 59 return nil, fmt.Errorf("error parsing outputImage to dockerImageRef, %w", err) 60 } 61 62 imageRetriever := imageInfo.ImageRetriever{} 63 64 ctx, cancel := context.WithTimeout(context.Background(), time.Minute) 65 defer cancel() 66 image, err := imageRetriever.Image(ctx, imagesource.TypedImageReference{Type: "docker", Ref: dockerImageRef}) 67 if err != nil { 68 return nil, fmt.Errorf("error getting image from imageRetriver, %w", err) 69 } 70 return image, nil 71 } 72 73 // FetchImageConfig fetches image config from remote registry. 74 // It uses the registry authentication credentials stored in default place ~/.docker/config.json 75 func FetchImageConfig(imagePullspec string) (*v1.ConfigFile, error) { 76 wrapErr := func(err error) error { 77 return fmt.Errorf("error while fetching image config %s: %w", imagePullspec, err) 78 } 79 ref, err := name.ParseReference(imagePullspec) 80 if err != nil { 81 return nil, wrapErr(err) 82 } 83 // Fetch the manifest using default credentials. 84 descriptor, err := remote.Get(ref, remote.WithAuthFromKeychain(authn.DefaultKeychain)) 85 if err != nil { 86 return nil, wrapErr(err) 87 } 88 89 image, err := descriptor.Image() 90 if err != nil { 91 return nil, wrapErr(err) 92 } 93 configFile, err := image.ConfigFile() 94 if err != nil { 95 return nil, wrapErr(err) 96 } 97 return configFile, nil 98 } 99 100 // FetchImageDigest fetches image manifest digest. 101 // Digest is returned as a hex string without sha256: prefix. 102 func FetchImageDigest(imagePullspec string) (string, error) { 103 ref, err := name.ParseReference(imagePullspec) 104 if err != nil { 105 return "", err 106 } 107 // Fetch the manifest using default credentials. 108 descriptor, err := remote.Get(ref, remote.WithAuthFromKeychain(authn.DefaultKeychain)) 109 if err != nil { 110 return "", err 111 } 112 return descriptor.Digest.Hex, nil 113 }