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  }