From 67b1bda8cc848977751e24a0b199c59b2a8edc72 Mon Sep 17 00:00:00 2001 From: Pramod Bindal Date: Mon, 7 Oct 2024 16:11:00 +0530 Subject: [PATCH 1/3] Enable Goole WIF Support for Tecton-Caches SRVKP-6522 - Enable Google WIF Support SRVKP-6522 - Fix Lint --- dev/google-wif.sh | 62 +++++++++++++++++ dev/install.sh | 24 ++++++- dev/kind/kind-config.yaml | 7 ++ dev/pipeline/pipeline-wif.yaml | 107 ++++++++++++++++++++++++++++++ dev/pr/gcs-wif-pipelinerun.yaml | 34 ++++++++++ dev/step-action/cache-upload.yaml | 2 +- internal/fetch/fetch.go | 11 +-- internal/provider/gcs/common.go | 41 ------------ internal/provider/gcs/fetcher.go | 69 +++++++++---------- internal/provider/gcs/upload.go | 66 ++++++++---------- internal/upload/upload.go | 9 +-- 11 files changed, 302 insertions(+), 130 deletions(-) create mode 100755 dev/google-wif.sh mode change 100644 => 100755 dev/install.sh create mode 100644 dev/kind/kind-config.yaml create mode 100644 dev/pipeline/pipeline-wif.yaml create mode 100644 dev/pr/gcs-wif-pipelinerun.yaml delete mode 100644 internal/provider/gcs/common.go diff --git a/dev/google-wif.sh b/dev/google-wif.sh new file mode 100755 index 000000000..518e0e43c --- /dev/null +++ b/dev/google-wif.sh @@ -0,0 +1,62 @@ +#!/usr/bin/env bash +set -x +#Step 0 - Define Common Variables + + POOL_ID=openshift-pool + PROVIDER_ID=opeshift-wif + NAMESPACE=default + SERVICE_ACCOUNT=default + PROJECT_ID=pipelines-qe + PROJECT_NUMBER=272779626560 + MAPPED_SUBJECT=system:serviceaccount:$NAMESPACE:$SERVICE_ACCOUNT + +#Step 1 - Enable IAM APIs on Google Cloud + +# Step 2 - Define an attribute mapping and condition + MAPPINGS=google.subject=assertion.sub + + +#Step 3 - Create workload identity pool and provider + ISSUER=$(kubectl get --raw /.well-known/openid-configuration | jq -r .issuer) + + +# Download the cluster's JSON Web Key Set (JWKS): + kubectl get --raw /openid/v1/jwks > cluster-jwks.json + + +# Create a new workload identity pool: + gcloud iam workload-identity-pools create $POOL_ID \ + --location="global" \ + --description="DESCRIPTION" \ + --display-name="DISPLAY_NAME" + + +# Add the Kubernetes cluster as a workload identity pool provider and upload the cluster's JWKS: + + gcloud iam workload-identity-pools providers create-oidc $PROVIDER_ID \ + --location="global" \ + --workload-identity-pool=$POOL_ID \ + --issuer-uri=$ISSUER \ + --attribute-mapping=$MAPPINGS \ + --jwk-json-path="cluster-jwks.json" + + +# Create Service Account or use default one + +# kubectl create serviceaccount $KSA_NAME --namespace $NAMESPACE + +# Grant IAM access to the Kubernetes ServiceAccount for a Google Cloud resource. + gcloud projects add-iam-policy-binding projects/$PROJECT_ID \ + --role=roles/owner \ + --member=principal://iam.googleapis.com/projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/$POOL_ID/subject/$MAPPED_SUBJECT \ + --condition=None + + gcloud iam workload-identity-pools create-cred-config \ + projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/$POOL_ID/providers/$PROVIDER_ID \ + --credential-source-file=/workspace/token/token \ + --credential-source-type=text \ + --output-file=credential-configuration.json + + + + kubectl -n $NAMESPACE create secret generic gcs-cred --from-file=credential-configuration.json \ No newline at end of file diff --git a/dev/install.sh b/dev/install.sh old mode 100644 new mode 100755 index 868e4881d..6661f00bc --- a/dev/install.sh +++ b/dev/install.sh @@ -1,9 +1,29 @@ #!/usr/bin/env bash +# Create a Kind Cluster if dont have sone +#kind create cluster --name tekton-caches --config kind/kind-config.yaml + +# Install Pipelines if not already installed. +#kubectl apply --filename https://storage.googleapis.com/tekton-releases/pipeline/latest/release.yaml + +#Enable Step Actions Feature kubectl patch configmap -n tekton-pipelines --type merge -p '{"data":{"enable-step-actions": "true"}}' feature-flags -kubectl create secret generic regcred \ - --from-file=config.json=${HOME}/.docker/config.json +# Create Docker creds secret Specifc to OCI Images +#kubectl create secret generic regcred --from-file=config.json=${HOME}/.docker/config.json + +# Create Secret for AWS S3 +#kubectl create secret generic aws-cred --from-file=${HOME}/.aws/config --from-file=${HOME}/.aws/credentials + +#Deploy Step Actions +ko apply -BRf ./step-action + +# Deploy Pipelines +kubectl apply -f ./pipeline + +#Create PipelineRuns using this command +kubectl create -f ./pr + diff --git a/dev/kind/kind-config.yaml b/dev/kind/kind-config.yaml new file mode 100644 index 000000000..35467ef85 --- /dev/null +++ b/dev/kind/kind-config.yaml @@ -0,0 +1,7 @@ +kind: Cluster +apiVersion: kind.x-k8s.io/v1alpha4 +nodes: +- role: control-plane +- role: worker +- role: worker +- role: worker \ No newline at end of file diff --git a/dev/pipeline/pipeline-wif.yaml b/dev/pipeline/pipeline-wif.yaml new file mode 100644 index 000000000..cb1ec1e1a --- /dev/null +++ b/dev/pipeline/pipeline-wif.yaml @@ -0,0 +1,107 @@ +--- +apiVersion: tekton.dev/v1 +kind: Pipeline +metadata: + name: pipeline-wif +spec: + params: + - name: repo_url + type: string + - name: revision + type: string + - name: registry + type: string + - name: buildCommand + type: string + default: go build -v . + - name: cachePatterns + type: array + default: [ "**go.mod", "**go.sum" ] + - name: image + type: string + default: golang:latest + - name: force-cache-upload + type: string + default: "false" + workspaces: + - name: source + - name: cred + - name: token + tasks: + - displayName: Build go application + name: build-task + workspaces: + - name: source + - name: cred + - name: token + taskSpec: + params: + - name: buildCommand + default: $(params.buildCommand) + - name: cachePatterns + default: $(params.cachePatterns) + - name: image + default: $(params.image) + steps: + - name: create-repo + image: $(params.image) + script: | + mkdir -p $(workspaces.source.path)/repo + chmod 777 $(workspaces.source.path)/repo + - name: fetch-repo + ref: + resolver: http + params: + - name: url + value: https://raw.githubusercontent.com/tektoncd/catalog/main/stepaction/git-clone/0.1/git-clone.yaml + params: + - name: output-path + value: $(workspaces.source.path)/repo + - name: url + value: $(params.repo_url) + - name: revision + value: $(params.revision) + - name: cache-fetch + ref: + name: cache-fetch + params: + - name: patterns + value: $(params.cachePatterns) + - name: source + value: $(params.registry)/cache-go:{{hash}} + - name: cachePath + value: $(workspaces.source.path)/cache + - name: workingdir + value: $(workspaces.source.path)/repo + - name: googleCredentialsPath + value: $(workspaces.cred.path)/credential-configuration.json + + - name: run-go-build + workingDir: $(workspaces.source.path)/repo + image: $(params.image) + env: + - name: GOCACHE + value: $(workspaces.source.path)/cache/gocache + - name: GOMODCACHE + value: $(workspaces.source.path)/cache/gomodcache + script: | + set -x + git config --global --add safe.directory $(workspaces.source.path)/repo + $(params.buildCommand) + echo "Cache size is $(du -sh $(workspaces.source.path)/cache)" + - name: cache-upload + ref: + name: cache-upload + params: + - name: patterns + value: $(params.cachePatterns) + - name: target + value: $(params.registry)/cache-go:{{hash}} + - name: cachePath + value: $(workspaces.source.path)/cache + - name: workingdir + value: $(workspaces.source.path)/repo + - name: googleCredentialsPath + value: $(workspaces.cred.path)/credential-configuration.json + - name: force-cache-upload + value: $(params.force-cache-upload) diff --git a/dev/pr/gcs-wif-pipelinerun.yaml b/dev/pr/gcs-wif-pipelinerun.yaml new file mode 100644 index 000000000..6c23e9a1e --- /dev/null +++ b/dev/pr/gcs-wif-pipelinerun.yaml @@ -0,0 +1,34 @@ +--- +apiVersion: tekton.dev/v1 +kind: PipelineRun +metadata: + generateName: pipelinerun-gcs- +spec: + pipelineRef: + name: pipeline-wif + params: + - name: repo_url + value: https://github.com/chmouel/go-helloworld + - name: revision + value: main + # This uses GCS bucket to upload Caches + - name: registry + value: gs://tekton-caches + - name: buildCommand + value: go build -v ./ + - name: image + value: golang:1.21 + workspaces: + - name: source + emptyDir: { } + - name: cred + secret: + secretName: gcs-cred + - name: token + projected: + sources: + - serviceAccountToken: + audience: https://iam.googleapis.com/projects/272779626560/locations/global/workloadIdentityPools/openshift-pool/providers/opeshift-wif + expirationSeconds: 3600 + path: token + diff --git a/dev/step-action/cache-upload.yaml b/dev/step-action/cache-upload.yaml index e4330bdc8..cf10d495b 100644 --- a/dev/step-action/cache-upload.yaml +++ b/dev/step-action/cache-upload.yaml @@ -70,12 +70,12 @@ spec: value: $(params.googleCredentialsPath) - name: CRED_STORE value: $(params.cred-store) - # FIXME: use a released version once something is released :) image: ko://github.com/openshift-pipelines/tekton-caches/cmd/cache args: ["$(params.patterns[*])"] script: | #!/usr/bin/env sh set -x + if [[ ${PARAM_FORCE_CACHE_UPLOAD} == "false" && ${RESULT_CACHE_FETCHED} == "true" ]]; then echo "no need to upload cache" exit 0 diff --git a/internal/fetch/fetch.go b/internal/fetch/fetch.go index 87631938c..5c97439d2 100644 --- a/internal/fetch/fetch.go +++ b/internal/fetch/fetch.go @@ -7,12 +7,10 @@ import ( "os" "strings" - "github.com/openshift-pipelines/tekton-caches/internal/tar" - - "github.com/openshift-pipelines/tekton-caches/internal/provider/s3" - "github.com/openshift-pipelines/tekton-caches/internal/provider/gcs" "github.com/openshift-pipelines/tekton-caches/internal/provider/oci" + "github.com/openshift-pipelines/tekton-caches/internal/provider/s3" + "github.com/openshift-pipelines/tekton-caches/internal/tar" ) func Fetch(ctx context.Context, hash, target, folder string, insecure bool) error { @@ -39,7 +37,10 @@ func Fetch(ctx context.Context, hash, target, folder string, insecure bool) erro } return tar.Untar(ctx, file, folder) case "gs": - return gcs.Fetch(ctx, hash, source, folder) + if err := gcs.Fetch(ctx, source, file.Name()); err != nil { + return err + } + return tar.Untar(ctx, file, folder) default: return fmt.Errorf("unknown schema: %s", target) } diff --git a/internal/provider/gcs/common.go b/internal/provider/gcs/common.go deleted file mode 100644 index 979f3b2d6..000000000 --- a/internal/provider/gcs/common.go +++ /dev/null @@ -1,41 +0,0 @@ -package gcs - -import ( - "context" - "io" - "os" - "path/filepath" - - "cloud.google.com/go/storage" -) - -// realGCS is a wrapper over the GCS client functions. -type realGCS struct { - client *storage.Client - manifestObject string -} - -func (gp realGCS) NewWriter(ctx context.Context, bucket, object string) io.WriteCloser { - if object != gp.manifestObject { - object = filepath.Join(".cache", object) - } - return gp.client.Bucket(bucket).Object(object). - If(storage.Conditions{DoesNotExist: true}). // Skip upload if already exists. - NewWriter(ctx) -} - -func (gp realGCS) NewReader(ctx context.Context, bucket, object string) (io.ReadCloser, error) { - return gp.client.Bucket(bucket).Object(object).NewReader(ctx) -} - -// realOS merely wraps the os package implementations. -type realOS struct{} - -func (realOS) EvalSymlinks(path string) (string, error) { return filepath.EvalSymlinks(path) } -func (realOS) Stat(path string) (os.FileInfo, error) { return os.Stat(path) } -func (realOS) Rename(oldpath, newpath string) error { return os.Rename(oldpath, newpath) } -func (realOS) Chmod(name string, mode os.FileMode) error { return os.Chmod(name, mode) } -func (realOS) Create(name string) (*os.File, error) { return os.Create(name) } -func (realOS) MkdirAll(path string, perm os.FileMode) error { return os.MkdirAll(path, perm) } -func (realOS) Open(name string) (*os.File, error) { return os.Open(name) } -func (realOS) RemoveAll(path string) error { return os.RemoveAll(path) } diff --git a/internal/provider/gcs/fetcher.go b/internal/provider/gcs/fetcher.go index 2453dd667..e114fb12e 100644 --- a/internal/provider/gcs/fetcher.go +++ b/internal/provider/gcs/fetcher.go @@ -3,56 +3,51 @@ package gcs import ( "context" "fmt" + "io" + "log" "os" - "path/filepath" - "strings" "time" "cloud.google.com/go/storage" - "github.com/GoogleCloudPlatform/cloud-builders/gcs-fetcher/pkg/common" - "github.com/GoogleCloudPlatform/cloud-builders/gcs-fetcher/pkg/fetcher" - "google.golang.org/api/option" -) -const ( - sourceType = "Manifest" - stagingFolder = ".download/" - backoff = 100 * time.Millisecond - retries = 0 + "github.com/GoogleCloudPlatform/cloud-builders/gcs-fetcher/pkg/common" ) -func Fetch(ctx context.Context, hash, target, folder string) error { - location := "gs://" + target + hash + ".json" - bucket, object, generation, err := common.ParseBucketObject(location) +func Fetch(ctx context.Context, source, destFileName string) error { + location := "gs://" + source + bucket, object, _, err := common.ParseBucketObject(location) if err != nil { return fmt.Errorf("parsing location from %q failed: %w", location, err) } - client, err := storage.NewClient(ctx, option.WithUserAgent(userAgent)) + + client, err := storage.NewClient(ctx) + if err != nil { + return fmt.Errorf("storage.NewClient: %w", err) + } + defer client.Close() + + ctx, cancel := context.WithTimeout(ctx, time.Second*50) + defer cancel() + + f, err := os.Create(destFileName) + if err != nil { + return fmt.Errorf("os.Create: %w", err) + } + + rc, err := client.Bucket(bucket).Object(object).NewReader(ctx) if err != nil { - return fmt.Errorf("failed to create a new gcs client: %w", err) + return fmt.Errorf("Object(%q).NewReader: %w", object, err) } - gcs := &fetcher.Fetcher{ - GCS: realGCS{client, object}, - OS: realOS{}, - DestDir: folder, - StagingDir: filepath.Join(folder, stagingFolder), - CreatedDirs: map[string]bool{}, - Bucket: bucket, - Object: object, - Generation: generation, - TimeoutGCS: true, - WorkerCount: workerCount, - Retries: retries, - Backoff: backoff, - SourceType: sourceType, - KeepSource: false, - Verbose: false, - Stdout: os.Stdout, - Stderr: os.Stderr, + defer rc.Close() + + if _, err := io.Copy(f, rc); err != nil { + return fmt.Errorf("io.Copy: %w", err) } - err = gcs.Fetch(ctx) - if err != nil && !strings.Contains(err.Error(), "storage: object doesn't exist") { - return fmt.Errorf("failed to fetch: %w", err) + + if err = f.Close(); err != nil { + return fmt.Errorf("f.Close: %w", err) } + log.Printf("Blob %v downloaded to local file %v\n", object, destFileName) + return nil } diff --git a/internal/provider/gcs/upload.go b/internal/provider/gcs/upload.go index 551bb1f50..e1095dff6 100644 --- a/internal/provider/gcs/upload.go +++ b/internal/provider/gcs/upload.go @@ -4,29 +4,35 @@ import ( "context" "errors" "fmt" + "io" + "log" "os" - "path/filepath" + "time" "cloud.google.com/go/storage" "github.com/GoogleCloudPlatform/cloud-builders/gcs-fetcher/pkg/common" - "github.com/GoogleCloudPlatform/cloud-builders/gcs-fetcher/pkg/uploader" - "google.golang.org/api/option" -) - -const ( - userAgent = "tekton-caches" - // The number of files to upload in parallel. - workerCount = 200 ) // gcs-uploader -dir examples/ -location gs://tekton-caches-tests/test +func Upload(ctx context.Context, target, file string) error { + client, err := storage.NewClient(ctx) + if err != nil { + return fmt.Errorf("storage.NewClient: %w", err) + } + defer client.Close() -func Upload(ctx context.Context, hash, target, folder string) error { - location := "gs://" + target + hash + ".json" - client, err := storage.NewClient(ctx, option.WithUserAgent(userAgent)) + // Open local file. + f, err := os.Open(file) if err != nil { - return fmt.Errorf("failed to create a new gcs client: %w", err) + return fmt.Errorf("os.Open: %w", err) } + defer f.Close() + + ctx, cancel := context.WithTimeout(ctx, time.Second*50) + defer cancel() + + location := "gs://" + target + log.Printf("Uploading %s to %s\n", file, location) bucket, object, generation, err := common.ParseBucketObject(location) if err != nil { return fmt.Errorf("parsing location from %q failed: %w", location, err) @@ -34,35 +40,15 @@ func Upload(ctx context.Context, hash, target, folder string) error { if generation != 0 { return errors.New("cannot specify manifest file generation") } - _, err = client.Bucket(bucket).Object(object).NewReader(ctx) - if err != nil && !errors.Is(err, storage.ErrObjectNotExist) { - return fmt.Errorf("failed to fetch the object: %w", err) - } - // if !errors.Is(err, storage.ErrObjectNotExist) { - // // Delete if the object already exists… - // // It's a workaround to not have the precondition failure… - // if err := client.Bucket(bucket).Object(object).Delete(ctx); err != nil { - // return err - // } - // } - - u := uploader.New(ctx, realGCS{client, object}, realOS{}, bucket, object, workerCount) + o := client.Bucket(bucket).Object(object) - if err := filepath.Walk(folder, func(path string, info os.FileInfo, err error) error { - if err != nil { - return err - } - if info.IsDir() { - return nil - } - - return u.Do(ctx, path, info) - }); err != nil { - return fmt.Errorf("failed to walk the path: %w", err) + wc := o.NewWriter(ctx) + if _, err = io.Copy(wc, f); err != nil { + return fmt.Errorf("io.Copy: %w", err) } - - if err := u.Done(ctx); err != nil { - return fmt.Errorf("failed to upload: %w", err) + if err := wc.Close(); err != nil { + return fmt.Errorf("Writer.Close: %w", err) } + log.Printf("Blob %v uploaded.\n", object) return nil } diff --git a/internal/upload/upload.go b/internal/upload/upload.go index 67ff7e9ff..5b21806a6 100644 --- a/internal/upload/upload.go +++ b/internal/upload/upload.go @@ -27,17 +27,18 @@ func Upload(ctx context.Context, hash, target, folder string, insecure bool) err if err != nil { log.Fatal(err) } - if err := tar.Tarit(folder, tarFile.Name()); err != nil { + tarName := tarFile.Name() + if err := tar.Tarit(folder, tarName); err != nil { return err } - defer os.Remove(tarFile.Name()) + defer os.Remove(tarName) switch u.Scheme { case "oci": return oci.Upload(ctx, hash, newTarget, folder, insecure) case "s3": - return s3.Upload(ctx, newTarget, tarFile.Name()) + return s3.Upload(ctx, newTarget, tarName) case "gs": - return gcs.Upload(ctx, hash, newTarget, folder) + return gcs.Upload(ctx, newTarget, tarName) default: return fmt.Errorf("unknown schema: %s", target) } From 63be17b5e8dfd7402a54eaa2df8c8bf073e374cf Mon Sep 17 00:00:00 2001 From: Pramod Bindal Date: Thu, 10 Oct 2024 11:46:37 +0530 Subject: [PATCH 2/3] Google WIF - updated Audience to openshift. --- dev/google-wif.sh | 5 +++-- dev/install.sh | 13 ++++++------- dev/pr/gcs-wif-pipelinerun.yaml | 2 +- dev/step-action/cache-fetch.yaml | 8 ++++++-- 4 files changed, 16 insertions(+), 12 deletions(-) diff --git a/dev/google-wif.sh b/dev/google-wif.sh index 518e0e43c..b0784d842 100755 --- a/dev/google-wif.sh +++ b/dev/google-wif.sh @@ -27,8 +27,8 @@ set -x # Create a new workload identity pool: gcloud iam workload-identity-pools create $POOL_ID \ --location="global" \ - --description="DESCRIPTION" \ - --display-name="DISPLAY_NAME" + --description=$POOL_ID \ + --display-name=$POOL_ID # Add the Kubernetes cluster as a workload identity pool provider and upload the cluster's JWKS: @@ -37,6 +37,7 @@ set -x --location="global" \ --workload-identity-pool=$POOL_ID \ --issuer-uri=$ISSUER \ + --allowed-audiences=openshift \ --attribute-mapping=$MAPPINGS \ --jwk-json-path="cluster-jwks.json" diff --git a/dev/install.sh b/dev/install.sh index 6661f00bc..e9c0fe4bc 100755 --- a/dev/install.sh +++ b/dev/install.sh @@ -1,7 +1,10 @@ #!/usr/bin/env bash + +SCRIPT_DIR="$(dirname "$(readlink -f "$0")")" + # Create a Kind Cluster if dont have sone -#kind create cluster --name tekton-caches --config kind/kind-config.yaml +kind create cluster --name tekton-caches --config $SCRIPT_DIR/kind/kind-config.yaml # Install Pipelines if not already installed. @@ -17,13 +20,9 @@ kubectl patch configmap -n tekton-pipelines --type merge -p '{"data":{"enable-st #kubectl create secret generic aws-cred --from-file=${HOME}/.aws/config --from-file=${HOME}/.aws/credentials #Deploy Step Actions -ko apply -BRf ./step-action +ko apply -BRf $SCRIPT_DIR/step-action # Deploy Pipelines -kubectl apply -f ./pipeline - -#Create PipelineRuns using this command -kubectl create -f ./pr - +kubectl apply -f $SCRIPT_DIR/pipeline diff --git a/dev/pr/gcs-wif-pipelinerun.yaml b/dev/pr/gcs-wif-pipelinerun.yaml index 6c23e9a1e..13b4513a3 100644 --- a/dev/pr/gcs-wif-pipelinerun.yaml +++ b/dev/pr/gcs-wif-pipelinerun.yaml @@ -28,7 +28,7 @@ spec: projected: sources: - serviceAccountToken: - audience: https://iam.googleapis.com/projects/272779626560/locations/global/workloadIdentityPools/openshift-pool/providers/opeshift-wif + audience: openshift expirationSeconds: 3600 path: token diff --git a/dev/step-action/cache-fetch.yaml b/dev/step-action/cache-fetch.yaml index 3d3d27b2f..88fc68f46 100644 --- a/dev/step-action/cache-fetch.yaml +++ b/dev/step-action/cache-fetch.yaml @@ -48,8 +48,12 @@ spec: The path to find the aws credentials file. If left empty, it is ignored. type: string default: "" - - name: BLOB_QUERY_PARAMS - value: $(params.blobQueryParams) + - name: blobQueryParams + type: string + default: "" + - name: cred-store + type: string + default: "" results: # Any result to "publish" ? - name: fetched description: | From 86be9dba35aedb46abe7c96a2a8687311bdea585 Mon Sep 17 00:00:00 2001 From: Pramod Bindal Date: Thu, 10 Oct 2024 16:17:59 +0530 Subject: [PATCH 3/3] Add Dockerfile for konflux adoption --- openshift/dockerfiles/cache.Dockerfile | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 openshift/dockerfiles/cache.Dockerfile diff --git a/openshift/dockerfiles/cache.Dockerfile b/openshift/dockerfiles/cache.Dockerfile new file mode 100644 index 000000000..64c37dee8 --- /dev/null +++ b/openshift/dockerfiles/cache.Dockerfile @@ -0,0 +1,25 @@ +ARG GO_BUILDER=brew.registry.redhat.io/rh-osbs/openshift-golang-builder:v1.22 +ARG RUNTIME=registry.access.redhat.com/ubi9/ubi-minimal:latest@sha256:c0e70387664f30cd9cf2795b547e4a9a51002c44a4a86aa9335ab030134bf392 + +FROM $GO_BUILDER AS builder + +WORKDIR /go/src/github.com/openshift-pipelines/tekton-caches +COPY . . + +RUN go build -v -o /tmp/cache ./cmd/cache + +FROM $RUNTIME +ARG VERSION=tekton-caches-main + +COPY --from=builder /tmp/cache /ko-app/cache +LABEL \ + com.redhat.component="openshift-pipelines-tekton-caches" \ + name="openshift-pipelines/pipelines-tekton-caches-rhel8" \ + version=$VERSION \ + summary="Red Hat OpenShift Pipelines Tekton Caches" \ + maintainer="pipelines-extcomm@redhat.com" \ + description="Red Hat OpenShift Pipelines Tekton Caches" \ + io.k8s.display-name="Red Hat OpenShift Pipelines Tekton Caches" \ + io.k8s.description="Red Hat OpenShift Pipelines Tekton Caches" \ + io.openshift.tags="pipelines,tekton,openshift,tekton-caches" +