From 36792f731a5bc5ee66b8ce6e2bdbf05b99f942b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20St=C3=A4bler?= Date: Wed, 22 Apr 2026 13:12:21 +0200 Subject: [PATCH 1/7] feat: add commit label to function images Detect the git commit SHA of the function source directory using go-git and add it as a "commit" OCI image label. The short SHA is suffixed with "-dirty" if the working tree has uncommitted changes. If the function is not in a git repo, the label is omitted. Integrated into all three builders (pack, s2i, oci) and the func-util scaffold/s2i-generate pipeline. --- cmd/func-util/s2i_generate.go | 6 +++ pkg/buildpacks/builder.go | 18 +++++++- pkg/functions/function_labels.go | 1 + pkg/functions/git_commit.go | 41 +++++++++++++++++++ pkg/oci/builder.go | 19 +++++++++ pkg/pipelines/tekton/task-buildpack.yaml.tmpl | 10 +++++ pkg/pipelines/tekton/task-s2i.yaml.tmpl | 5 +++ pkg/pipelines/tekton/templates.go | 6 +++ pkg/pipelines/tekton/templates_pack.go | 8 ++++ pkg/pipelines/tekton/templates_s2i.go | 8 ++++ pkg/s2i/builder.go | 14 ++++++- 11 files changed, 132 insertions(+), 4 deletions(-) create mode 100644 pkg/functions/git_commit.go diff --git a/cmd/func-util/s2i_generate.go b/cmd/func-util/s2i_generate.go index 36f51cc598..0293716841 100644 --- a/cmd/func-util/s2i_generate.go +++ b/cmd/func-util/s2i_generate.go @@ -36,6 +36,7 @@ type genConfig struct { imageScriptUrl string logLevel string middlewareVersion string + commit string envVars []string } @@ -64,6 +65,7 @@ func newS2IGenerateCmd() *cobra.Command { genCmd.Flags().StringVar(&config.imageScriptUrl, "image-script-url", "image:///usr/libexec/s2i", "") genCmd.Flags().StringVar(&config.logLevel, "log-level", "0", "") genCmd.Flags().StringVar(&config.middlewareVersion, "middleware-version", "", "") + genCmd.Flags().StringVar(&config.commit, "commit", "", "") return genCmd } @@ -142,6 +144,10 @@ func runS2IGenerate(ctx context.Context, c genConfig) error { }, } + if c.commit != "" { + s2iConfig.Labels[fn.CommitLabelKey] = c.commit + } + builder, _, err := strategies.Strategy(nil, &s2iConfig, build.Overrides{}) if err != nil { return fmt.Errorf("cannot create builder: %w", err) diff --git a/pkg/buildpacks/builder.go b/pkg/buildpacks/builder.go index 1a3fb44f26..b806a02cd1 100644 --- a/pkg/buildpacks/builder.go +++ b/pkg/buildpacks/builder.go @@ -201,13 +201,27 @@ func (b *Builder) Build(ctx context.Context, f fn.Function, platforms []fn.Platf opts.Env["BP_GO_WORKDIR"] = filepath.Join(fn.RunDataDir, fn.BuildDir) } - // Get middleware version and set as image label via BP_IMAGE_LABELS + // Set image labels via BP_IMAGE_LABELS + var imageLabels []string + middlewareVersion, err := scaffolding.MiddlewareVersion(f.Root, f.Runtime, f.Invoke, fn.EmbeddedTemplatesFS) if err != nil { return fmt.Errorf("cannot get middleware version: %w", err) } if middlewareVersion != "" { - opts.Env["BP_IMAGE_LABELS"] = fmt.Sprintf("%s=%s", fn.MiddlewareVersionLabelKey, middlewareVersion) + imageLabels = append(imageLabels, fmt.Sprintf("%s=%s", fn.MiddlewareVersionLabelKey, middlewareVersion)) + } + + commit, err := fn.GitCommit(f.Root) + if err != nil { + return fmt.Errorf("cannot get git commit: %w", err) + } + if commit != "" { + imageLabels = append(imageLabels, fmt.Sprintf("%s=%s", fn.CommitLabelKey, commit)) + } + + if len(imageLabels) > 0 { + opts.Env["BP_IMAGE_LABELS"] = strings.Join(imageLabels, " ") } var bindings = make([]string, 0, len(f.Build.Mounts)) diff --git a/pkg/functions/function_labels.go b/pkg/functions/function_labels.go index 1602c06cd4..bce77491ec 100644 --- a/pkg/functions/function_labels.go +++ b/pkg/functions/function_labels.go @@ -10,6 +10,7 @@ import ( const ( MiddlewareVersionLabelKey = "middleware-version" + CommitLabelKey = "commit" ) type Label struct { diff --git a/pkg/functions/git_commit.go b/pkg/functions/git_commit.go new file mode 100644 index 0000000000..d4ecdb351d --- /dev/null +++ b/pkg/functions/git_commit.go @@ -0,0 +1,41 @@ +package functions + +import ( + "github.com/go-git/go-git/v5" +) + +// GitCommit returns the short commit SHA of the git repository containing +// the given directory. Returns "-dirty" if the working tree has +// uncommitted changes. Returns an empty string if the directory is not +// inside a git repository. +func GitCommit(dir string) (string, error) { + repo, err := git.PlainOpenWithOptions(dir, &git.PlainOpenOptions{ + DetectDotGit: true, + }) + if err != nil { + return "", nil + } + + head, err := repo.Head() + if err != nil { + return "", nil + } + + sha := head.Hash().String()[:7] + + wt, err := repo.Worktree() + if err != nil { + return sha, nil + } + + status, err := wt.Status() + if err != nil { + return sha, nil + } + + if !status.IsClean() { + sha += "-dirty" + } + + return sha, nil +} diff --git a/pkg/oci/builder.go b/pkg/oci/builder.go index 20dd15b7b1..be06fd3423 100644 --- a/pkg/oci/builder.go +++ b/pkg/oci/builder.go @@ -114,6 +114,10 @@ func (b *Builder) Build(ctx context.Context, f fn.Function, pp []fn.Platform) (e return } + if err = fetchCommitLabel(&job); err != nil { + return + } + if err = containerize(job); err != nil { // write image to .func/build return } @@ -200,6 +204,21 @@ func fetchMiddlewareLabels(job *buildJob) (err error) { return nil } +// fetchCommitLabel retrieves git commit SHA for image labels +func fetchCommitLabel(job *buildJob) error { + commit, err := fn.GitCommit(job.function.Root) + if err != nil { + return fmt.Errorf("unable to get git commit: %w", err) + } + if commit != "" { + if job.labels == nil { + job.labels = make(map[string]string) + } + job.labels[fn.CommitLabelKey] = commit + } + return nil +} + // containerize the full service which consists of the scaffolded Function, // Function implementation, base image, data layers etc. // This container is stored on disk for later upload to the registry via diff --git a/pkg/pipelines/tekton/task-buildpack.yaml.tmpl b/pkg/pipelines/tekton/task-buildpack.yaml.tmpl index a9bea7d83d..d71644ebfe 100644 --- a/pkg/pipelines/tekton/task-buildpack.yaml.tmpl +++ b/pkg/pipelines/tekton/task-buildpack.yaml.tmpl @@ -64,6 +64,9 @@ spec: - name: INSECURE_REGISTRIES description: Registries to access without TLS verification default: "" + - name: COMMIT + description: Git commit SHA of the function source + default: "" stepTemplate: env: - name: CNB_PLATFORM_API @@ -156,6 +159,13 @@ spec: echo "No middleware-version file ($middleware_version_file) found" fi + # Add commit label + commit="$(params.COMMIT)" + if [ -n "$commit" ]; then + echo "--> Adding commit label: $commit" + echo -n " commit=$commit" >> "${ENV_DIR}/BP_IMAGE_LABELS" + fi + ############################################ ##### Added part for Knative Functions ##### ############################################ diff --git a/pkg/pipelines/tekton/task-s2i.yaml.tmpl b/pkg/pipelines/tekton/task-s2i.yaml.tmpl index b79c86d239..c739a45a1f 100644 --- a/pkg/pipelines/tekton/task-s2i.yaml.tmpl +++ b/pkg/pipelines/tekton/task-s2i.yaml.tmpl @@ -42,6 +42,9 @@ spec: - name: S2I_IMAGE_SCRIPTS_URL description: The URL containing the default assemble and run scripts for the builder image. default: "image:///usr/libexec/s2i" + - name: COMMIT + description: Git commit SHA of the function source + default: "" workspaces: - name: source - name: cache @@ -96,6 +99,8 @@ spec: - $(params.S2I_IMAGE_SCRIPTS_URL) - "--log-level" - $(params.LOGLEVEL) + - "--commit" + - $(params.COMMIT) - $(params.ENV_VARS[*]) volumeMounts: - mountPath: /gen-source diff --git a/pkg/pipelines/tekton/templates.go b/pkg/pipelines/tekton/templates.go index 79873f96c3..b853194bcf 100644 --- a/pkg/pipelines/tekton/templates.go +++ b/pkg/pipelines/tekton/templates.go @@ -90,6 +90,9 @@ type templateData struct { // TLS verification for registry operations TlsVerify string + + // Git commit SHA of the function source + Commit string } // createPipelineTemplatePAC creates a Pipeline template used for PAC on-cluster build @@ -386,6 +389,8 @@ func createAndApplyPipelineRunTemplate(f fn.Function, namespace string, labels m tlsVerify = "false" } + commit, _ := fn.GitCommit(f.Root) + data := templateData{ FunctionName: f.Name, Annotations: f.Deploy.Annotations, @@ -403,6 +408,7 @@ func createAndApplyPipelineRunTemplate(f fn.Function, namespace string, labels m S2iImageScriptsUrl: s2iImageScriptsUrl, TlsVerify: tlsVerify, + Commit: commit, RepoUrl: f.Build.Git.URL, Revision: pipelinesTargetBranch, diff --git a/pkg/pipelines/tekton/templates_pack.go b/pkg/pipelines/tekton/templates_pack.go index 7b5dcd02d9..d4e73dc4b7 100644 --- a/pkg/pipelines/tekton/templates_pack.go +++ b/pkg/pipelines/tekton/templates_pack.go @@ -40,6 +40,10 @@ spec: - description: Environment variables to set during build time name: buildEnvs type: array + - description: Git commit SHA of the function source + name: commit + default: '' + type: string tasks: - name: build params: @@ -58,6 +62,8 @@ spec: - name: ENV_VARS value: - '$(params.buildEnvs[*])' + - name: COMMIT + value: $(params.commit) {{- if eq .TlsVerify "false"}} - name: INSECURE_REGISTRIES value: $(params.registry) @@ -115,6 +121,8 @@ spec: {{range .BuildEnvs -}} - {{.}} {{end}} + - name: commit + value: "{{.Commit}}" pipelineRef: name: {{.PipelineName}} workspaces: diff --git a/pkg/pipelines/tekton/templates_s2i.go b/pkg/pipelines/tekton/templates_s2i.go index 9441a9c5c6..8eb5ccd7a0 100644 --- a/pkg/pipelines/tekton/templates_s2i.go +++ b/pkg/pipelines/tekton/templates_s2i.go @@ -48,6 +48,10 @@ spec: name: tlsVerify type: string default: 'true' + - description: Git commit SHA of the function source + name: commit + default: '' + type: string tasks: - name: build params: @@ -70,6 +74,8 @@ spec: value: $(params.s2iImageScriptsUrl) - name: TLSVERIFY value: $(params.tlsVerify) + - name: COMMIT + value: $(params.commit) {{.FuncS2iTaskRef}} workspaces: - name: source @@ -126,6 +132,8 @@ spec: value: {{.S2iImageScriptsUrl}} - name: tlsVerify value: {{.TlsVerify}} + - name: commit + value: "{{.Commit}}" pipelineRef: name: {{.PipelineName}} workspaces: diff --git a/pkg/s2i/builder.go b/pkg/s2i/builder.go index b2d939ede6..842518e87b 100644 --- a/pkg/s2i/builder.go +++ b/pkg/s2i/builder.go @@ -184,13 +184,23 @@ func (b *Builder) Build(ctx context.Context, f fn.Function, platforms []fn.Platf cfg.ScriptsURL = "file://" + f.Root + "/" + fn.RunDataDir + "/" + fn.BuildDir + "/bin" } - // Set middleware version label + // Set image labels + cfg.Labels = make(map[string]string) + middlewareVersion, err := scaffolding.MiddlewareVersion(f.Root, f.Runtime, f.Invoke, fn.EmbeddedTemplatesFS) if err != nil { return fmt.Errorf("cannot get middleware version: %w", err) } if middlewareVersion != "" { - cfg.Labels = map[string]string{fn.MiddlewareVersionLabelKey: middlewareVersion} + cfg.Labels[fn.MiddlewareVersionLabelKey] = middlewareVersion + } + + commit, err := fn.GitCommit(f.Root) + if err != nil { + return fmt.Errorf("cannot get git commit: %w", err) + } + if commit != "" { + cfg.Labels[fn.CommitLabelKey] = commit } // Environment variables From 1e010b0cdd68cc8f378544e1419f2b4da716e4fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20St=C3=A4bler?= Date: Wed, 22 Apr 2026 13:28:43 +0200 Subject: [PATCH 2/7] feat: show commit label in func describe Add ImageCommit() to read the commit label from a deployed function image. Integrate into all three describers (knative, k8s, keda) and expose via the Instance struct so it appears in JSON/YAML output of func describe. --- pkg/functions/client.go | 1 + pkg/functions/image_commit.go | 36 +++++++++++++++++++++++++++++++++++ pkg/k8s/describer.go | 7 ++++++- pkg/keda/describer.go | 7 ++++++- pkg/knative/describer.go | 5 ++++- 5 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 pkg/functions/image_commit.go diff --git a/pkg/functions/client.go b/pkg/functions/client.go index bf06f3f2ce..979368a0e0 100644 --- a/pkg/functions/client.go +++ b/pkg/functions/client.go @@ -188,6 +188,7 @@ type Instance struct { Subscriptions []Subscription `json:"subscriptions" yaml:"subscriptions"` Labels map[string]string `json:"labels" yaml:"labels" xml:"-"` Middleware Middleware `json:"middleware,omitempty" yaml:"middleware,omitempty"` + Commit string `json:"commit,omitempty" yaml:"commit,omitempty"` Generation int64 `json:"generation,omitempty" yaml:"generation,omitempty"` Ready string `json:"ready,omitempty" yaml:"ready,omitempty"` } diff --git a/pkg/functions/image_commit.go b/pkg/functions/image_commit.go new file mode 100644 index 0000000000..11ad036c21 --- /dev/null +++ b/pkg/functions/image_commit.go @@ -0,0 +1,36 @@ +package functions + +import ( + "github.com/google/go-containerregistry/pkg/name" + "github.com/google/go-containerregistry/pkg/v1/remote" +) + +// ImageCommit gets the commit SHA label from a function image. +// Returns an empty string and no error if the image was built without this label. +func ImageCommit(image string) (string, error) { + ref, err := name.ParseReference(image) + if err != nil { + return "", err + } + + desc, err := remote.Get(ref) + if err != nil { + return "", err + } + + img, err := desc.Image() + if err != nil { + return "", err + } + + cfg, err := img.ConfigFile() + if err != nil { + return "", err + } + + if cfg.Config.Labels == nil { + return "", nil + } + + return cfg.Config.Labels[CommitLabelKey], nil +} diff --git a/pkg/k8s/describer.go b/pkg/k8s/describer.go index 0646023f0f..6b6dfee28b 100644 --- a/pkg/k8s/describer.go +++ b/pkg/k8s/describer.go @@ -77,12 +77,16 @@ func (d *Describer) Describe(ctx context.Context, name, namespace string) (fn.In } middlewareVersion := "" + commit := "" if image != "" { v, err := fn.MiddlewareVersion(image) if err == nil { - // don't fail on errors middlewareVersion = v } + c, err := fn.ImageCommit(image) + if err == nil { + commit = c + } } description := fn.Instance{ @@ -96,6 +100,7 @@ func (d *Describer) Describe(ctx context.Context, name, namespace string) (fn.In Middleware: fn.Middleware{ Version: middlewareVersion, }, + Commit: commit, Generation: deployment.Generation, Ready: strings.ToLower(string(ready)), } diff --git a/pkg/keda/describer.go b/pkg/keda/describer.go index 4c8fd6b212..659de82a20 100644 --- a/pkg/keda/describer.go +++ b/pkg/keda/describer.go @@ -96,12 +96,16 @@ func (d *Describer) Describe(ctx context.Context, name, namespace string) (fn.In } middlewareVersion := "" + commit := "" if image != "" { v, err := fn.MiddlewareVersion(image) if err == nil { - // don't fail on errors middlewareVersion = v } + c, err := fn.ImageCommit(image) + if err == nil { + commit = c + } } description := fn.Instance{ @@ -115,6 +119,7 @@ func (d *Describer) Describe(ctx context.Context, name, namespace string) (fn.In Middleware: fn.Middleware{ Version: middlewareVersion, }, + Commit: commit, Generation: deployment.Generation, Ready: strings.ToLower(string(ready)), } diff --git a/pkg/knative/describer.go b/pkg/knative/describer.go index e0a6ddca33..df2b3032bd 100644 --- a/pkg/knative/describer.go +++ b/pkg/knative/describer.go @@ -130,11 +130,14 @@ func (d *Describer) Describe(ctx context.Context, name, namespace string) (fn.In if description.Image != "" { v, err := fn.MiddlewareVersion(description.Image) if err == nil { - // don't fail on errors description.Middleware = fn.Middleware{ Version: v, } } + c, err := fn.ImageCommit(description.Image) + if err == nil { + description.Commit = c + } } triggers, err := eventingClient.ListTriggers(ctx) From 9d879cffd25295823cc94c5fe5b70d2e982fd09b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20St=C3=A4bler?= Date: Fri, 24 Apr 2026 14:21:00 +0200 Subject: [PATCH 3/7] refactor: use ImageInspector with custom transport for image label fetching --- cmd/client.go | 8 ++- cmd/deploy.go | 3 +- pkg/functions/image_commit.go | 36 ------------ pkg/functions/image_inspector.go | 65 ++++++++++++++++++++++ pkg/functions/middleware.go | 33 ----------- pkg/k8s/describer.go | 14 +++-- pkg/keda/describer.go | 14 +++-- pkg/knative/describer.go | 14 +++-- pkg/pipelines/tekton/pipelines_provider.go | 13 ++++- 9 files changed, 106 insertions(+), 94 deletions(-) delete mode 100644 pkg/functions/image_commit.go create mode 100644 pkg/functions/image_inspector.go diff --git a/cmd/client.go b/cmd/client.go index 3c3a1761a6..faff12ba99 100644 --- a/cmd/client.go +++ b/cmd/client.go @@ -62,7 +62,8 @@ func NewClient(cfg ClientConfig, options ...fn.Option) (*fn.Client, func()) { t = newTransport(cfg.InsecureSkipVerify) // may provide a custom impl which proxies c = newCredentialsProvider(config.Dir(), t, "") // for accessing registries d = newKnativeDeployer(cfg.Verbose) // default deployer (can be overridden via options) - pp = newTektonPipelinesProvider(c, cfg.Verbose) + ii = fn.NewImageInspector(t) + pp = newTektonPipelinesProvider(c, cfg.Verbose, ii) o = []fn.Option{ // standard (shared) options for all commands fn.WithVerbose(cfg.Verbose), fn.WithTransport(t), @@ -70,7 +71,7 @@ func NewClient(cfg ClientConfig, options ...fn.Option) (*fn.Client, func()) { fn.WithScaffolder(buildpacks.NewScaffolder(cfg.Verbose)), fn.WithBuilder(buildpacks.NewBuilder(buildpacks.WithVerbose(cfg.Verbose))), fn.WithRemovers(knative.NewRemover(cfg.Verbose), k8s.NewRemover(cfg.Verbose), keda.NewRemover(cfg.Verbose)), - fn.WithDescribers(knative.NewDescriber(cfg.Verbose), k8s.NewDescriber(cfg.Verbose), keda.NewDescriber(cfg.Verbose)), + fn.WithDescribers(knative.NewDescriber(cfg.Verbose, ii), k8s.NewDescriber(cfg.Verbose, ii), keda.NewDescriber(cfg.Verbose, ii)), fn.WithListers(knative.NewLister(cfg.Verbose), k8s.NewLister(cfg.Verbose), keda.NewLister(cfg.Verbose)), fn.WithDeployer(d), fn.WithPipelinesProvider(pp), @@ -143,11 +144,12 @@ func newCredentialsProvider(configPath string, t http.RoundTripper, authFilePath return creds.NewCredentialsProvider(configPath, options...) } -func newTektonPipelinesProvider(creds oci.CredentialsProvider, verbose bool) *tekton.PipelinesProvider { +func newTektonPipelinesProvider(creds oci.CredentialsProvider, verbose bool, ii *fn.ImageInspector) *tekton.PipelinesProvider { options := []tekton.Opt{ tekton.WithCredentialsProvider(creds), tekton.WithVerbose(verbose), tekton.WithPipelineDecorator(deployDecorator{}), + tekton.WithImageInspector(ii), } return tekton.NewPipelinesProvider(options...) diff --git a/cmd/deploy.go b/cmd/deploy.go index b4c8b32411..69fcb4f6cb 100644 --- a/cmd/deploy.go +++ b/cmd/deploy.go @@ -782,7 +782,8 @@ func (c deployConfig) clientOptions() ([]fn.Option, error) { // Override the pipelines provider to use custom credentials // This is needed for remote builds (deploy --remote) - o = append(o, fn.WithPipelinesProvider(newTektonPipelinesProvider(creds, c.Verbose))) + ii := fn.NewImageInspector(t) + o = append(o, fn.WithPipelinesProvider(newTektonPipelinesProvider(creds, c.Verbose, ii))) // Add the appropriate deployer based on deploy type deployer := c.Deployer diff --git a/pkg/functions/image_commit.go b/pkg/functions/image_commit.go deleted file mode 100644 index 11ad036c21..0000000000 --- a/pkg/functions/image_commit.go +++ /dev/null @@ -1,36 +0,0 @@ -package functions - -import ( - "github.com/google/go-containerregistry/pkg/name" - "github.com/google/go-containerregistry/pkg/v1/remote" -) - -// ImageCommit gets the commit SHA label from a function image. -// Returns an empty string and no error if the image was built without this label. -func ImageCommit(image string) (string, error) { - ref, err := name.ParseReference(image) - if err != nil { - return "", err - } - - desc, err := remote.Get(ref) - if err != nil { - return "", err - } - - img, err := desc.Image() - if err != nil { - return "", err - } - - cfg, err := img.ConfigFile() - if err != nil { - return "", err - } - - if cfg.Config.Labels == nil { - return "", nil - } - - return cfg.Config.Labels[CommitLabelKey], nil -} diff --git a/pkg/functions/image_inspector.go b/pkg/functions/image_inspector.go new file mode 100644 index 0000000000..0fe65c3336 --- /dev/null +++ b/pkg/functions/image_inspector.go @@ -0,0 +1,65 @@ +package functions + +import ( + "net/http" + + "github.com/google/go-containerregistry/pkg/name" + "github.com/google/go-containerregistry/pkg/v1/remote" +) + +type ImageInspector struct { + transport http.RoundTripper +} + +func NewImageInspector(transport http.RoundTripper) *ImageInspector { + if transport == nil { + transport = http.DefaultTransport + } + return &ImageInspector{transport: transport} +} + +func (i *ImageInspector) Labels(image string) (map[string]string, error) { + ref, err := name.ParseReference(image) + if err != nil { + return nil, err + } + + desc, err := remote.Get(ref, remote.WithTransport(i.transport)) + if err != nil { + return nil, err + } + + img, err := desc.Image() + if err != nil { + return nil, err + } + + cfg, err := img.ConfigFile() + if err != nil { + return nil, err + } + + return cfg.Config.Labels, nil +} + +func (i *ImageInspector) MiddlewareVersion(image string) (string, error) { + labels, err := i.Labels(image) + if err != nil { + return "", err + } + if labels == nil { + return "", nil + } + return labels[MiddlewareVersionLabelKey], nil +} + +func (i *ImageInspector) Commit(image string) (string, error) { + labels, err := i.Labels(image) + if err != nil { + return "", err + } + if labels == nil { + return "", nil + } + return labels[CommitLabelKey], nil +} diff --git a/pkg/functions/middleware.go b/pkg/functions/middleware.go index 4d13799175..46211a916f 100644 --- a/pkg/functions/middleware.go +++ b/pkg/functions/middleware.go @@ -1,42 +1,9 @@ package functions import ( - "github.com/google/go-containerregistry/pkg/name" - "github.com/google/go-containerregistry/pkg/v1/remote" "knative.dev/func/pkg/scaffolding" ) -// MiddlewareVersion gets the used middleware version of a function image. -// Returns an empty string and no error in case the function image was built -// without this information. -func MiddlewareVersion(image string) (string, error) { - ref, err := name.ParseReference(image) - if err != nil { - return "", err - } - - desc, err := remote.Get(ref) - if err != nil { - return "", err - } - - img, err := desc.Image() - if err != nil { - return "", err - } - - cfg, err := img.ConfigFile() - if err != nil { - return "", err - } - - if cfg.Config.Labels == nil { - return "", nil - } - - return cfg.Config.Labels[MiddlewareVersionLabelKey], nil -} - func LatestMiddlewareVersions() (map[string]map[string]string, error) { return scaffolding.MiddlewareVersions(EmbeddedTemplatesFS) } diff --git a/pkg/k8s/describer.go b/pkg/k8s/describer.go index 6b6dfee28b..3fea5fb385 100644 --- a/pkg/k8s/describer.go +++ b/pkg/k8s/describer.go @@ -13,12 +13,14 @@ import ( ) type Describer struct { - verbose bool + verbose bool + imageInspector *fn.ImageInspector } -func NewDescriber(verbose bool) *Describer { +func NewDescriber(verbose bool, imageInspector *fn.ImageInspector) *Describer { return &Describer{ - verbose: verbose, + verbose: verbose, + imageInspector: imageInspector, } } @@ -78,12 +80,12 @@ func (d *Describer) Describe(ctx context.Context, name, namespace string) (fn.In middlewareVersion := "" commit := "" - if image != "" { - v, err := fn.MiddlewareVersion(image) + if image != "" && d.imageInspector != nil { + v, err := d.imageInspector.MiddlewareVersion(image) if err == nil { middlewareVersion = v } - c, err := fn.ImageCommit(image) + c, err := d.imageInspector.Commit(image) if err == nil { commit = c } diff --git a/pkg/keda/describer.go b/pkg/keda/describer.go index 659de82a20..f0a2e5dd18 100644 --- a/pkg/keda/describer.go +++ b/pkg/keda/describer.go @@ -15,12 +15,14 @@ import ( ) type Describer struct { - verbose bool + verbose bool + imageInspector *fn.ImageInspector } -func NewDescriber(verbose bool) *Describer { +func NewDescriber(verbose bool, imageInspector *fn.ImageInspector) *Describer { return &Describer{ - verbose: verbose, + verbose: verbose, + imageInspector: imageInspector, } } @@ -97,12 +99,12 @@ func (d *Describer) Describe(ctx context.Context, name, namespace string) (fn.In middlewareVersion := "" commit := "" - if image != "" { - v, err := fn.MiddlewareVersion(image) + if image != "" && d.imageInspector != nil { + v, err := d.imageInspector.MiddlewareVersion(image) if err == nil { middlewareVersion = v } - c, err := fn.ImageCommit(image) + c, err := d.imageInspector.Commit(image) if err == nil { commit = c } diff --git a/pkg/knative/describer.go b/pkg/knative/describer.go index df2b3032bd..bc2e54631b 100644 --- a/pkg/knative/describer.go +++ b/pkg/knative/describer.go @@ -16,12 +16,14 @@ import ( ) type Describer struct { - verbose bool + verbose bool + imageInspector *fn.ImageInspector } -func NewDescriber(verbose bool) *Describer { +func NewDescriber(verbose bool, imageInspector *fn.ImageInspector) *Describer { return &Describer{ - verbose: verbose, + verbose: verbose, + imageInspector: imageInspector, } } @@ -127,14 +129,14 @@ func (d *Describer) Describe(ctx context.Context, name, namespace string) (fn.In } } - if description.Image != "" { - v, err := fn.MiddlewareVersion(description.Image) + if description.Image != "" && d.imageInspector != nil { + v, err := d.imageInspector.MiddlewareVersion(description.Image) if err == nil { description.Middleware = fn.Middleware{ Version: v, } } - c, err := fn.ImageCommit(description.Image) + c, err := d.imageInspector.Commit(description.Image) if err == nil { description.Commit = c } diff --git a/pkg/pipelines/tekton/pipelines_provider.go b/pkg/pipelines/tekton/pipelines_provider.go index d50801cc22..c2d590ee96 100644 --- a/pkg/pipelines/tekton/pipelines_provider.go +++ b/pkg/pipelines/tekton/pipelines_provider.go @@ -56,6 +56,7 @@ type PipelinesProvider struct { getPacURL pacURLCallback credentialsProvider oci.CredentialsProvider decorator PipelineDecorator + imageInspector *fn.ImageInspector } func WithCredentialsProvider(credentialsProvider oci.CredentialsProvider) Opt { @@ -76,6 +77,12 @@ func WithPipelineDecorator(decorator PipelineDecorator) Opt { } } +func WithImageInspector(ii *fn.ImageInspector) Opt { + return func(pp *PipelinesProvider) { + pp.imageInspector = ii + } +} + func WithPacURLCallback(getPacURL pacURLCallback) Opt { return func(pp *PipelinesProvider) { pp.getPacURL = getPacURL @@ -245,12 +252,12 @@ func (pp *PipelinesProvider) Run(ctx context.Context, f fn.Function) (string, fn var describer fn.Describer switch f.Deploy.Deployer { case k8s.KubernetesDeployerName: - describer = k8s.NewDescriber(false) + describer = k8s.NewDescriber(false, pp.imageInspector) case keda.KedaDeployerName: - describer = keda.NewDescriber(false) + describer = keda.NewDescriber(false, pp.imageInspector) default: // default to knative - describer = knative.NewDescriber(false) + describer = knative.NewDescriber(false, pp.imageInspector) } obj, err := describer.Describe(ctx, f.Name, f.Namespace) From bf1ec951bd0e40d9616ee22f654b6ba073e86abc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20St=C3=A4bler?= Date: Fri, 24 Apr 2026 14:56:50 +0200 Subject: [PATCH 4/7] fix: update NewDescriber calls in integration tests --- pkg/functions/client_int_test.go | 4 ++-- pkg/k8s/deployer_int_test.go | 12 ++++++------ pkg/k8s/describer_int_test.go | 2 +- pkg/k8s/lister_int_test.go | 2 +- pkg/k8s/remover_int_test.go | 2 +- pkg/keda/deployer_int_test.go | 12 ++++++------ pkg/keda/describer_int_test.go | 2 +- pkg/keda/lister_int_test.go | 2 +- pkg/keda/remover_int_test.go | 2 +- pkg/knative/deployer_int_test.go | 12 ++++++------ pkg/knative/describer_int_test.go | 2 +- pkg/knative/lister_int_test.go | 2 +- pkg/knative/remover_int_test.go | 2 +- pkg/pipelines/tekton/pipelines_int_test.go | 2 +- 14 files changed, 30 insertions(+), 30 deletions(-) diff --git a/pkg/functions/client_int_test.go b/pkg/functions/client_int_test.go index f4b6fcda22..37ded6ed68 100644 --- a/pkg/functions/client_int_test.go +++ b/pkg/functions/client_int_test.go @@ -674,7 +674,7 @@ func newClient(verbose bool) *fn.Client { fn.WithBuilder(oci.NewBuilder("", verbose)), fn.WithPusher(oci.NewPusher(true, true, verbose)), fn.WithDeployer(knative.NewDeployer(knative.WithDeployerVerbose(verbose))), - fn.WithDescribers(knative.NewDescriber(verbose), k8s.NewDescriber(verbose)), + fn.WithDescribers(knative.NewDescriber(verbose, nil), k8s.NewDescriber(verbose, nil)), fn.WithRemovers(knative.NewRemover(verbose), k8s.NewRemover(verbose)), fn.WithListers(knative.NewLister(verbose), k8s.NewLister(verbose)), fn.WithVerbose(verbose), @@ -690,7 +690,7 @@ func newClientWithS2i(verbose bool) *fn.Client { fn.WithBuilder(s2i.NewBuilder(s2i.WithVerbose(verbose))), fn.WithPusher(docker.NewPusher(docker.WithVerbose(verbose))), fn.WithDeployer(knative.NewDeployer(knative.WithDeployerVerbose(verbose))), - fn.WithDescribers(knative.NewDescriber(verbose), k8s.NewDescriber(verbose)), + fn.WithDescribers(knative.NewDescriber(verbose, nil), k8s.NewDescriber(verbose, nil)), fn.WithRemovers(knative.NewRemover(verbose), k8s.NewRemover(verbose)), fn.WithListers(knative.NewLister(verbose), k8s.NewLister(verbose)), ) diff --git a/pkg/k8s/deployer_int_test.go b/pkg/k8s/deployer_int_test.go index fdc4d6ab8f..1f5389f2f8 100644 --- a/pkg/k8s/deployer_int_test.go +++ b/pkg/k8s/deployer_int_test.go @@ -14,7 +14,7 @@ func TestInt_FullPath(t *testing.T) { k8s.NewDeployer(k8s.WithDeployerVerbose(false)), k8s.NewRemover(false), k8s.NewLister(false), - k8s.NewDescriber(false), + k8s.NewDescriber(false, nil), k8s.KubernetesDeployerName) } @@ -22,7 +22,7 @@ func TestInt_Deploy(t *testing.T) { deployertesting.TestInt_Deploy(t, k8s.NewDeployer(k8s.WithDeployerVerbose(false)), k8s.NewRemover(false), - k8s.NewDescriber(false), + k8s.NewDescriber(false, nil), k8s.KubernetesDeployerName) } @@ -30,7 +30,7 @@ func TestInt_Metadata(t *testing.T) { deployertesting.TestInt_Metadata(t, k8s.NewDeployer(k8s.WithDeployerVerbose(false)), k8s.NewRemover(false), - k8s.NewDescriber(false), + k8s.NewDescriber(false, nil), k8s.KubernetesDeployerName) } @@ -40,7 +40,7 @@ func TestInt_Events(t *testing.T) { deployertesting.TestInt_Events(t, k8s.NewDeployer(k8s.WithDeployerVerbose(false)), k8s.NewRemover(false), - k8s.NewDescriber(false), + k8s.NewDescriber(false, nil), k8s.KubernetesDeployerName) } @@ -48,7 +48,7 @@ func TestInt_Scale(t *testing.T) { deployertesting.TestInt_Scale(t, k8s.NewDeployer(k8s.WithDeployerVerbose(false)), k8s.NewRemover(false), - k8s.NewDescriber(false), + k8s.NewDescriber(false, nil), k8s.KubernetesDeployerName) } @@ -56,6 +56,6 @@ func TestInt_EnvsUpdate(t *testing.T) { deployertesting.TestInt_EnvsUpdate(t, k8s.NewDeployer(k8s.WithDeployerVerbose(false)), k8s.NewRemover(false), - k8s.NewDescriber(false), + k8s.NewDescriber(false, nil), k8s.KubernetesDeployerName) } diff --git a/pkg/k8s/describer_int_test.go b/pkg/k8s/describer_int_test.go index 2643b41359..48c8e2094c 100644 --- a/pkg/k8s/describer_int_test.go +++ b/pkg/k8s/describer_int_test.go @@ -11,7 +11,7 @@ import ( func TestInt_Describe(t *testing.T) { describertesting.TestInt_Describe(t, - k8s.NewDescriber(true), + k8s.NewDescriber(true, nil), k8s.NewDeployer(k8s.WithDeployerVerbose(true)), k8s.NewRemover(true), k8s.KubernetesDeployerName) diff --git a/pkg/k8s/lister_int_test.go b/pkg/k8s/lister_int_test.go index 10feed5a48..abef8d077d 100644 --- a/pkg/k8s/lister_int_test.go +++ b/pkg/k8s/lister_int_test.go @@ -13,7 +13,7 @@ func TestInt_List(t *testing.T) { listertesting.TestInt_List(t, k8s.NewLister(true), k8s.NewDeployer(k8s.WithDeployerVerbose(true)), - k8s.NewDescriber(true), + k8s.NewDescriber(true, nil), k8s.NewRemover(true), k8s.KubernetesDeployerName) } diff --git a/pkg/k8s/remover_int_test.go b/pkg/k8s/remover_int_test.go index 28c86237b4..05bf09849e 100644 --- a/pkg/k8s/remover_int_test.go +++ b/pkg/k8s/remover_int_test.go @@ -13,7 +13,7 @@ func TestInt_Remove(t *testing.T) { removertesting.TestInt_Remove(t, k8s.NewRemover(true), k8s.NewDeployer(k8s.WithDeployerVerbose(true)), - k8s.NewDescriber(true), + k8s.NewDescriber(true, nil), k8s.NewLister(true), k8s.KubernetesDeployerName) } diff --git a/pkg/keda/deployer_int_test.go b/pkg/keda/deployer_int_test.go index b21f191612..dcfd4d9d35 100644 --- a/pkg/keda/deployer_int_test.go +++ b/pkg/keda/deployer_int_test.go @@ -14,7 +14,7 @@ func TestInt_FullPath(t *testing.T) { keda.NewDeployer(keda.WithDeployerVerbose(false)), keda.NewRemover(false), keda.NewLister(false), - keda.NewDescriber(false), + keda.NewDescriber(false, nil), keda.KedaDeployerName) } @@ -22,7 +22,7 @@ func TestInt_Deploy(t *testing.T) { deployertesting.TestInt_Deploy(t, keda.NewDeployer(keda.WithDeployerVerbose(false)), keda.NewRemover(false), - keda.NewDescriber(false), + keda.NewDescriber(false, nil), keda.KedaDeployerName) } @@ -30,7 +30,7 @@ func TestInt_Metadata(t *testing.T) { deployertesting.TestInt_Metadata(t, keda.NewDeployer(keda.WithDeployerVerbose(false)), keda.NewRemover(false), - keda.NewDescriber(false), + keda.NewDescriber(false, nil), keda.KedaDeployerName) } @@ -40,7 +40,7 @@ func TestInt_Events(t *testing.T) { deployertesting.TestInt_Events(t, keda.NewDeployer(keda.WithDeployerVerbose(false)), keda.NewRemover(false), - keda.NewDescriber(false), + keda.NewDescriber(false, nil), keda.KedaDeployerName) } @@ -48,7 +48,7 @@ func TestInt_Scale(t *testing.T) { deployertesting.TestInt_Scale(t, keda.NewDeployer(keda.WithDeployerVerbose(false)), keda.NewRemover(false), - keda.NewDescriber(false), + keda.NewDescriber(false, nil), keda.KedaDeployerName) } @@ -56,6 +56,6 @@ func TestInt_EnvsUpdate(t *testing.T) { deployertesting.TestInt_EnvsUpdate(t, keda.NewDeployer(keda.WithDeployerVerbose(false)), keda.NewRemover(false), - keda.NewDescriber(false), + keda.NewDescriber(false, nil), keda.KedaDeployerName) } diff --git a/pkg/keda/describer_int_test.go b/pkg/keda/describer_int_test.go index bc32ccdd70..c09bddfc12 100644 --- a/pkg/keda/describer_int_test.go +++ b/pkg/keda/describer_int_test.go @@ -11,7 +11,7 @@ import ( func TestInt_Describe(t *testing.T) { describertesting.TestInt_Describe(t, - keda.NewDescriber(true), + keda.NewDescriber(true, nil), keda.NewDeployer(keda.WithDeployerVerbose(true)), keda.NewRemover(true), keda.KedaDeployerName) diff --git a/pkg/keda/lister_int_test.go b/pkg/keda/lister_int_test.go index 8160086893..753beb6366 100644 --- a/pkg/keda/lister_int_test.go +++ b/pkg/keda/lister_int_test.go @@ -13,7 +13,7 @@ func TestInt_List(t *testing.T) { listertesting.TestInt_List(t, keda.NewLister(true), keda.NewDeployer(keda.WithDeployerVerbose(true)), - keda.NewDescriber(true), + keda.NewDescriber(true, nil), keda.NewRemover(true), keda.KedaDeployerName) } diff --git a/pkg/keda/remover_int_test.go b/pkg/keda/remover_int_test.go index 4dfa6e630c..416fe87d01 100644 --- a/pkg/keda/remover_int_test.go +++ b/pkg/keda/remover_int_test.go @@ -13,7 +13,7 @@ func TestInt_Remove(t *testing.T) { removertesting.TestInt_Remove(t, keda.NewRemover(true), keda.NewDeployer(keda.WithDeployerVerbose(true)), - keda.NewDescriber(true), + keda.NewDescriber(true, nil), keda.NewLister(true), keda.KedaDeployerName) } diff --git a/pkg/knative/deployer_int_test.go b/pkg/knative/deployer_int_test.go index 97895a9459..bba5f3ff9f 100644 --- a/pkg/knative/deployer_int_test.go +++ b/pkg/knative/deployer_int_test.go @@ -14,7 +14,7 @@ func TestInt_FullPath(t *testing.T) { knative.NewDeployer(knative.WithDeployerVerbose(true)), knative.NewRemover(true), knative.NewLister(true), - knative.NewDescriber(true), + knative.NewDescriber(true, nil), knative.KnativeDeployerName) } @@ -22,7 +22,7 @@ func TestInt_Deploy(t *testing.T) { deployertesting.TestInt_Deploy(t, knative.NewDeployer(knative.WithDeployerVerbose(true)), knative.NewRemover(false), - knative.NewDescriber(false), + knative.NewDescriber(false, nil), knative.KnativeDeployerName) } @@ -30,7 +30,7 @@ func TestInt_Metadata(t *testing.T) { deployertesting.TestInt_Metadata(t, knative.NewDeployer(knative.WithDeployerVerbose(true)), knative.NewRemover(false), - knative.NewDescriber(false), + knative.NewDescriber(false, nil), knative.KnativeDeployerName) } @@ -38,7 +38,7 @@ func TestInt_Events(t *testing.T) { deployertesting.TestInt_Events(t, knative.NewDeployer(knative.WithDeployerVerbose(true)), knative.NewRemover(false), - knative.NewDescriber(false), + knative.NewDescriber(false, nil), knative.KnativeDeployerName) } @@ -46,7 +46,7 @@ func TestInt_Scale(t *testing.T) { deployertesting.TestInt_Scale(t, knative.NewDeployer(knative.WithDeployerVerbose(true)), knative.NewRemover(false), - knative.NewDescriber(false), + knative.NewDescriber(false, nil), knative.KnativeDeployerName) } @@ -54,6 +54,6 @@ func TestInt_EnvsUpdate(t *testing.T) { deployertesting.TestInt_EnvsUpdate(t, knative.NewDeployer(knative.WithDeployerVerbose(true)), knative.NewRemover(false), - knative.NewDescriber(false), + knative.NewDescriber(false, nil), knative.KnativeDeployerName) } diff --git a/pkg/knative/describer_int_test.go b/pkg/knative/describer_int_test.go index 4ddc036488..1b3c142add 100644 --- a/pkg/knative/describer_int_test.go +++ b/pkg/knative/describer_int_test.go @@ -11,7 +11,7 @@ import ( func TestInt_Describe(t *testing.T) { describertesting.TestInt_Describe(t, - knative.NewDescriber(true), + knative.NewDescriber(true, nil), knative.NewDeployer(knative.WithDeployerVerbose(true)), knative.NewRemover(true), knative.KnativeDeployerName) diff --git a/pkg/knative/lister_int_test.go b/pkg/knative/lister_int_test.go index a316c55613..1c5d188c3e 100644 --- a/pkg/knative/lister_int_test.go +++ b/pkg/knative/lister_int_test.go @@ -13,7 +13,7 @@ func TestInt_List(t *testing.T) { listertesting.TestInt_List(t, knative.NewLister(true), knative.NewDeployer(knative.WithDeployerVerbose(true)), - knative.NewDescriber(true), + knative.NewDescriber(true, nil), knative.NewRemover(true), knative.KnativeDeployerName) } diff --git a/pkg/knative/remover_int_test.go b/pkg/knative/remover_int_test.go index 6107e96a27..2bf9a8ef86 100644 --- a/pkg/knative/remover_int_test.go +++ b/pkg/knative/remover_int_test.go @@ -13,7 +13,7 @@ func TestInt_Remove(t *testing.T) { removertesting.TestInt_Remove(t, knative.NewRemover(true), knative.NewDeployer(knative.WithDeployerVerbose(true)), - knative.NewDescriber(true), + knative.NewDescriber(true, nil), knative.NewLister(true), knative.KnativeDeployerName) } diff --git a/pkg/pipelines/tekton/pipelines_int_test.go b/pkg/pipelines/tekton/pipelines_int_test.go index c0ecf5e87b..4f7b4c908f 100644 --- a/pkg/pipelines/tekton/pipelines_int_test.go +++ b/pkg/pipelines/tekton/pipelines_int_test.go @@ -48,7 +48,7 @@ func newRemoteTestClient(verbose bool, deployer string, opts ...fn.Option) *fn.C baseOpts := []fn.Option{ fn.WithBuilder(buildpacks.NewBuilder(buildpacks.WithVerbose(verbose))), fn.WithPusher(docker.NewPusher(docker.WithCredentialsProvider(testCP))), - fn.WithDescribers(knative.NewDescriber(verbose), k8s.NewDescriber(verbose), keda.NewDescriber(verbose)), + fn.WithDescribers(knative.NewDescriber(verbose, nil), k8s.NewDescriber(verbose, nil), keda.NewDescriber(verbose, nil)), fn.WithListers(knative.NewLister(verbose), k8s.NewLister(verbose), keda.NewLister(verbose)), fn.WithRemovers(knative.NewRemover(verbose), k8s.NewRemover(verbose), keda.NewRemover(verbose)), fn.WithPipelinesProvider(tekton.NewPipelinesProvider(tekton.WithCredentialsProvider(testCP), tekton.WithVerbose(verbose))), From 2e8f9af5bda15db79d7d6dac252b4008789d9f9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20St=C3=A4bler?= Date: Mon, 27 Apr 2026 09:49:37 +0200 Subject: [PATCH 5/7] refactor: pass transport to describers via functional options Replace ImageInspector struct with ImageLabels helper in function_labels.go. Describers now accept transport via WithDescriberTransport option, keeping the transport internal and removing nil arguments from callers. --- cmd/client.go | 13 +++-- cmd/deploy.go | 3 +- pkg/functions/client_int_test.go | 4 +- pkg/functions/function_labels.go | 27 +++++++++ pkg/functions/image_inspector.go | 65 ---------------------- pkg/k8s/deployer_int_test.go | 12 ++-- pkg/k8s/describer.go | 33 ++++++----- pkg/k8s/describer_int_test.go | 2 +- pkg/k8s/lister_int_test.go | 2 +- pkg/k8s/remover_int_test.go | 2 +- pkg/keda/deployer_int_test.go | 12 ++-- pkg/keda/describer.go | 33 ++++++----- pkg/keda/describer_int_test.go | 2 +- pkg/keda/lister_int_test.go | 2 +- pkg/keda/remover_int_test.go | 2 +- pkg/knative/deployer_int_test.go | 12 ++-- pkg/knative/describer.go | 33 ++++++----- pkg/knative/describer_int_test.go | 2 +- pkg/knative/lister_int_test.go | 2 +- pkg/knative/remover_int_test.go | 2 +- pkg/pipelines/tekton/pipelines_int_test.go | 2 +- pkg/pipelines/tekton/pipelines_provider.go | 13 +++-- 22 files changed, 133 insertions(+), 147 deletions(-) delete mode 100644 pkg/functions/image_inspector.go diff --git a/cmd/client.go b/cmd/client.go index faff12ba99..b83b3fd4fa 100644 --- a/cmd/client.go +++ b/cmd/client.go @@ -62,8 +62,7 @@ func NewClient(cfg ClientConfig, options ...fn.Option) (*fn.Client, func()) { t = newTransport(cfg.InsecureSkipVerify) // may provide a custom impl which proxies c = newCredentialsProvider(config.Dir(), t, "") // for accessing registries d = newKnativeDeployer(cfg.Verbose) // default deployer (can be overridden via options) - ii = fn.NewImageInspector(t) - pp = newTektonPipelinesProvider(c, cfg.Verbose, ii) + pp = newTektonPipelinesProvider(c, cfg.Verbose, t) o = []fn.Option{ // standard (shared) options for all commands fn.WithVerbose(cfg.Verbose), fn.WithTransport(t), @@ -71,7 +70,11 @@ func NewClient(cfg ClientConfig, options ...fn.Option) (*fn.Client, func()) { fn.WithScaffolder(buildpacks.NewScaffolder(cfg.Verbose)), fn.WithBuilder(buildpacks.NewBuilder(buildpacks.WithVerbose(cfg.Verbose))), fn.WithRemovers(knative.NewRemover(cfg.Verbose), k8s.NewRemover(cfg.Verbose), keda.NewRemover(cfg.Verbose)), - fn.WithDescribers(knative.NewDescriber(cfg.Verbose, ii), k8s.NewDescriber(cfg.Verbose, ii), keda.NewDescriber(cfg.Verbose, ii)), + fn.WithDescribers( + knative.NewDescriber(cfg.Verbose, knative.WithDescriberTransport(t)), + k8s.NewDescriber(cfg.Verbose, k8s.WithDescriberTransport(t)), + keda.NewDescriber(cfg.Verbose, keda.WithDescriberTransport(t)), + ), fn.WithListers(knative.NewLister(cfg.Verbose), k8s.NewLister(cfg.Verbose), keda.NewLister(cfg.Verbose)), fn.WithDeployer(d), fn.WithPipelinesProvider(pp), @@ -144,12 +147,12 @@ func newCredentialsProvider(configPath string, t http.RoundTripper, authFilePath return creds.NewCredentialsProvider(configPath, options...) } -func newTektonPipelinesProvider(creds oci.CredentialsProvider, verbose bool, ii *fn.ImageInspector) *tekton.PipelinesProvider { +func newTektonPipelinesProvider(creds oci.CredentialsProvider, verbose bool, transport http.RoundTripper) *tekton.PipelinesProvider { options := []tekton.Opt{ tekton.WithCredentialsProvider(creds), tekton.WithVerbose(verbose), tekton.WithPipelineDecorator(deployDecorator{}), - tekton.WithImageInspector(ii), + tekton.WithTransport(transport), } return tekton.NewPipelinesProvider(options...) diff --git a/cmd/deploy.go b/cmd/deploy.go index 69fcb4f6cb..c12fdf88ed 100644 --- a/cmd/deploy.go +++ b/cmd/deploy.go @@ -782,8 +782,7 @@ func (c deployConfig) clientOptions() ([]fn.Option, error) { // Override the pipelines provider to use custom credentials // This is needed for remote builds (deploy --remote) - ii := fn.NewImageInspector(t) - o = append(o, fn.WithPipelinesProvider(newTektonPipelinesProvider(creds, c.Verbose, ii))) + o = append(o, fn.WithPipelinesProvider(newTektonPipelinesProvider(creds, c.Verbose, t))) // Add the appropriate deployer based on deploy type deployer := c.Deployer diff --git a/pkg/functions/client_int_test.go b/pkg/functions/client_int_test.go index 37ded6ed68..f4b6fcda22 100644 --- a/pkg/functions/client_int_test.go +++ b/pkg/functions/client_int_test.go @@ -674,7 +674,7 @@ func newClient(verbose bool) *fn.Client { fn.WithBuilder(oci.NewBuilder("", verbose)), fn.WithPusher(oci.NewPusher(true, true, verbose)), fn.WithDeployer(knative.NewDeployer(knative.WithDeployerVerbose(verbose))), - fn.WithDescribers(knative.NewDescriber(verbose, nil), k8s.NewDescriber(verbose, nil)), + fn.WithDescribers(knative.NewDescriber(verbose), k8s.NewDescriber(verbose)), fn.WithRemovers(knative.NewRemover(verbose), k8s.NewRemover(verbose)), fn.WithListers(knative.NewLister(verbose), k8s.NewLister(verbose)), fn.WithVerbose(verbose), @@ -690,7 +690,7 @@ func newClientWithS2i(verbose bool) *fn.Client { fn.WithBuilder(s2i.NewBuilder(s2i.WithVerbose(verbose))), fn.WithPusher(docker.NewPusher(docker.WithVerbose(verbose))), fn.WithDeployer(knative.NewDeployer(knative.WithDeployerVerbose(verbose))), - fn.WithDescribers(knative.NewDescriber(verbose, nil), k8s.NewDescriber(verbose, nil)), + fn.WithDescribers(knative.NewDescriber(verbose), k8s.NewDescriber(verbose)), fn.WithRemovers(knative.NewRemover(verbose), k8s.NewRemover(verbose)), fn.WithListers(knative.NewLister(verbose), k8s.NewLister(verbose)), ) diff --git a/pkg/functions/function_labels.go b/pkg/functions/function_labels.go index bce77491ec..0232b7a70d 100644 --- a/pkg/functions/function_labels.go +++ b/pkg/functions/function_labels.go @@ -2,9 +2,12 @@ package functions import ( "fmt" + "net/http" "os" "strings" + "github.com/google/go-containerregistry/pkg/name" + "github.com/google/go-containerregistry/pkg/v1/remote" "knative.dev/func/pkg/utils" ) @@ -78,3 +81,27 @@ func ValidateLabels(labels []Label) (errors []string) { return } + +func ImageLabels(image string, transport http.RoundTripper) (map[string]string, error) { + ref, err := name.ParseReference(image) + if err != nil { + return nil, err + } + + desc, err := remote.Get(ref, remote.WithTransport(transport)) + if err != nil { + return nil, err + } + + img, err := desc.Image() + if err != nil { + return nil, err + } + + cfg, err := img.ConfigFile() + if err != nil { + return nil, err + } + + return cfg.Config.Labels, nil +} diff --git a/pkg/functions/image_inspector.go b/pkg/functions/image_inspector.go deleted file mode 100644 index 0fe65c3336..0000000000 --- a/pkg/functions/image_inspector.go +++ /dev/null @@ -1,65 +0,0 @@ -package functions - -import ( - "net/http" - - "github.com/google/go-containerregistry/pkg/name" - "github.com/google/go-containerregistry/pkg/v1/remote" -) - -type ImageInspector struct { - transport http.RoundTripper -} - -func NewImageInspector(transport http.RoundTripper) *ImageInspector { - if transport == nil { - transport = http.DefaultTransport - } - return &ImageInspector{transport: transport} -} - -func (i *ImageInspector) Labels(image string) (map[string]string, error) { - ref, err := name.ParseReference(image) - if err != nil { - return nil, err - } - - desc, err := remote.Get(ref, remote.WithTransport(i.transport)) - if err != nil { - return nil, err - } - - img, err := desc.Image() - if err != nil { - return nil, err - } - - cfg, err := img.ConfigFile() - if err != nil { - return nil, err - } - - return cfg.Config.Labels, nil -} - -func (i *ImageInspector) MiddlewareVersion(image string) (string, error) { - labels, err := i.Labels(image) - if err != nil { - return "", err - } - if labels == nil { - return "", nil - } - return labels[MiddlewareVersionLabelKey], nil -} - -func (i *ImageInspector) Commit(image string) (string, error) { - labels, err := i.Labels(image) - if err != nil { - return "", err - } - if labels == nil { - return "", nil - } - return labels[CommitLabelKey], nil -} diff --git a/pkg/k8s/deployer_int_test.go b/pkg/k8s/deployer_int_test.go index 1f5389f2f8..fdc4d6ab8f 100644 --- a/pkg/k8s/deployer_int_test.go +++ b/pkg/k8s/deployer_int_test.go @@ -14,7 +14,7 @@ func TestInt_FullPath(t *testing.T) { k8s.NewDeployer(k8s.WithDeployerVerbose(false)), k8s.NewRemover(false), k8s.NewLister(false), - k8s.NewDescriber(false, nil), + k8s.NewDescriber(false), k8s.KubernetesDeployerName) } @@ -22,7 +22,7 @@ func TestInt_Deploy(t *testing.T) { deployertesting.TestInt_Deploy(t, k8s.NewDeployer(k8s.WithDeployerVerbose(false)), k8s.NewRemover(false), - k8s.NewDescriber(false, nil), + k8s.NewDescriber(false), k8s.KubernetesDeployerName) } @@ -30,7 +30,7 @@ func TestInt_Metadata(t *testing.T) { deployertesting.TestInt_Metadata(t, k8s.NewDeployer(k8s.WithDeployerVerbose(false)), k8s.NewRemover(false), - k8s.NewDescriber(false, nil), + k8s.NewDescriber(false), k8s.KubernetesDeployerName) } @@ -40,7 +40,7 @@ func TestInt_Events(t *testing.T) { deployertesting.TestInt_Events(t, k8s.NewDeployer(k8s.WithDeployerVerbose(false)), k8s.NewRemover(false), - k8s.NewDescriber(false, nil), + k8s.NewDescriber(false), k8s.KubernetesDeployerName) } @@ -48,7 +48,7 @@ func TestInt_Scale(t *testing.T) { deployertesting.TestInt_Scale(t, k8s.NewDeployer(k8s.WithDeployerVerbose(false)), k8s.NewRemover(false), - k8s.NewDescriber(false, nil), + k8s.NewDescriber(false), k8s.KubernetesDeployerName) } @@ -56,6 +56,6 @@ func TestInt_EnvsUpdate(t *testing.T) { deployertesting.TestInt_EnvsUpdate(t, k8s.NewDeployer(k8s.WithDeployerVerbose(false)), k8s.NewRemover(false), - k8s.NewDescriber(false, nil), + k8s.NewDescriber(false), k8s.KubernetesDeployerName) } diff --git a/pkg/k8s/describer.go b/pkg/k8s/describer.go index 3fea5fb385..56ffc9c88e 100644 --- a/pkg/k8s/describer.go +++ b/pkg/k8s/describer.go @@ -3,6 +3,7 @@ package k8s import ( "context" "fmt" + "net/http" "strings" v1 "k8s.io/api/apps/v1" @@ -13,15 +14,24 @@ import ( ) type Describer struct { - verbose bool - imageInspector *fn.ImageInspector + verbose bool + transport http.RoundTripper } -func NewDescriber(verbose bool, imageInspector *fn.ImageInspector) *Describer { - return &Describer{ - verbose: verbose, - imageInspector: imageInspector, +type DescriberOpt func(*Describer) + +func WithDescriberTransport(transport http.RoundTripper) DescriberOpt { + return func(d *Describer) { + d.transport = transport + } +} + +func NewDescriber(verbose bool, opts ...DescriberOpt) *Describer { + d := &Describer{verbose: verbose} + for _, o := range opts { + o(d) } + return d } // Describe a function by name. @@ -80,14 +90,11 @@ func (d *Describer) Describe(ctx context.Context, name, namespace string) (fn.In middlewareVersion := "" commit := "" - if image != "" && d.imageInspector != nil { - v, err := d.imageInspector.MiddlewareVersion(image) - if err == nil { - middlewareVersion = v - } - c, err := d.imageInspector.Commit(image) + if image != "" && d.transport != nil { + labels, err := fn.ImageLabels(image, d.transport) if err == nil { - commit = c + middlewareVersion = labels[fn.MiddlewareVersionLabelKey] + commit = labels[fn.CommitLabelKey] } } diff --git a/pkg/k8s/describer_int_test.go b/pkg/k8s/describer_int_test.go index 48c8e2094c..2643b41359 100644 --- a/pkg/k8s/describer_int_test.go +++ b/pkg/k8s/describer_int_test.go @@ -11,7 +11,7 @@ import ( func TestInt_Describe(t *testing.T) { describertesting.TestInt_Describe(t, - k8s.NewDescriber(true, nil), + k8s.NewDescriber(true), k8s.NewDeployer(k8s.WithDeployerVerbose(true)), k8s.NewRemover(true), k8s.KubernetesDeployerName) diff --git a/pkg/k8s/lister_int_test.go b/pkg/k8s/lister_int_test.go index abef8d077d..10feed5a48 100644 --- a/pkg/k8s/lister_int_test.go +++ b/pkg/k8s/lister_int_test.go @@ -13,7 +13,7 @@ func TestInt_List(t *testing.T) { listertesting.TestInt_List(t, k8s.NewLister(true), k8s.NewDeployer(k8s.WithDeployerVerbose(true)), - k8s.NewDescriber(true, nil), + k8s.NewDescriber(true), k8s.NewRemover(true), k8s.KubernetesDeployerName) } diff --git a/pkg/k8s/remover_int_test.go b/pkg/k8s/remover_int_test.go index 05bf09849e..28c86237b4 100644 --- a/pkg/k8s/remover_int_test.go +++ b/pkg/k8s/remover_int_test.go @@ -13,7 +13,7 @@ func TestInt_Remove(t *testing.T) { removertesting.TestInt_Remove(t, k8s.NewRemover(true), k8s.NewDeployer(k8s.WithDeployerVerbose(true)), - k8s.NewDescriber(true, nil), + k8s.NewDescriber(true), k8s.NewLister(true), k8s.KubernetesDeployerName) } diff --git a/pkg/keda/deployer_int_test.go b/pkg/keda/deployer_int_test.go index dcfd4d9d35..b21f191612 100644 --- a/pkg/keda/deployer_int_test.go +++ b/pkg/keda/deployer_int_test.go @@ -14,7 +14,7 @@ func TestInt_FullPath(t *testing.T) { keda.NewDeployer(keda.WithDeployerVerbose(false)), keda.NewRemover(false), keda.NewLister(false), - keda.NewDescriber(false, nil), + keda.NewDescriber(false), keda.KedaDeployerName) } @@ -22,7 +22,7 @@ func TestInt_Deploy(t *testing.T) { deployertesting.TestInt_Deploy(t, keda.NewDeployer(keda.WithDeployerVerbose(false)), keda.NewRemover(false), - keda.NewDescriber(false, nil), + keda.NewDescriber(false), keda.KedaDeployerName) } @@ -30,7 +30,7 @@ func TestInt_Metadata(t *testing.T) { deployertesting.TestInt_Metadata(t, keda.NewDeployer(keda.WithDeployerVerbose(false)), keda.NewRemover(false), - keda.NewDescriber(false, nil), + keda.NewDescriber(false), keda.KedaDeployerName) } @@ -40,7 +40,7 @@ func TestInt_Events(t *testing.T) { deployertesting.TestInt_Events(t, keda.NewDeployer(keda.WithDeployerVerbose(false)), keda.NewRemover(false), - keda.NewDescriber(false, nil), + keda.NewDescriber(false), keda.KedaDeployerName) } @@ -48,7 +48,7 @@ func TestInt_Scale(t *testing.T) { deployertesting.TestInt_Scale(t, keda.NewDeployer(keda.WithDeployerVerbose(false)), keda.NewRemover(false), - keda.NewDescriber(false, nil), + keda.NewDescriber(false), keda.KedaDeployerName) } @@ -56,6 +56,6 @@ func TestInt_EnvsUpdate(t *testing.T) { deployertesting.TestInt_EnvsUpdate(t, keda.NewDeployer(keda.WithDeployerVerbose(false)), keda.NewRemover(false), - keda.NewDescriber(false, nil), + keda.NewDescriber(false), keda.KedaDeployerName) } diff --git a/pkg/keda/describer.go b/pkg/keda/describer.go index f0a2e5dd18..5f06777842 100644 --- a/pkg/keda/describer.go +++ b/pkg/keda/describer.go @@ -3,6 +3,7 @@ package keda import ( "context" "fmt" + "net/http" "strings" "github.com/kedacore/http-add-on/operator/apis/http/v1alpha1" @@ -15,15 +16,24 @@ import ( ) type Describer struct { - verbose bool - imageInspector *fn.ImageInspector + verbose bool + transport http.RoundTripper } -func NewDescriber(verbose bool, imageInspector *fn.ImageInspector) *Describer { - return &Describer{ - verbose: verbose, - imageInspector: imageInspector, +type DescriberOpt func(*Describer) + +func WithDescriberTransport(transport http.RoundTripper) DescriberOpt { + return func(d *Describer) { + d.transport = transport + } +} + +func NewDescriber(verbose bool, opts ...DescriberOpt) *Describer { + d := &Describer{verbose: verbose} + for _, o := range opts { + o(d) } + return d } // Describe a function by name. @@ -99,14 +109,11 @@ func (d *Describer) Describe(ctx context.Context, name, namespace string) (fn.In middlewareVersion := "" commit := "" - if image != "" && d.imageInspector != nil { - v, err := d.imageInspector.MiddlewareVersion(image) - if err == nil { - middlewareVersion = v - } - c, err := d.imageInspector.Commit(image) + if image != "" && d.transport != nil { + labels, err := fn.ImageLabels(image, d.transport) if err == nil { - commit = c + middlewareVersion = labels[fn.MiddlewareVersionLabelKey] + commit = labels[fn.CommitLabelKey] } } diff --git a/pkg/keda/describer_int_test.go b/pkg/keda/describer_int_test.go index c09bddfc12..bc32ccdd70 100644 --- a/pkg/keda/describer_int_test.go +++ b/pkg/keda/describer_int_test.go @@ -11,7 +11,7 @@ import ( func TestInt_Describe(t *testing.T) { describertesting.TestInt_Describe(t, - keda.NewDescriber(true, nil), + keda.NewDescriber(true), keda.NewDeployer(keda.WithDeployerVerbose(true)), keda.NewRemover(true), keda.KedaDeployerName) diff --git a/pkg/keda/lister_int_test.go b/pkg/keda/lister_int_test.go index 753beb6366..8160086893 100644 --- a/pkg/keda/lister_int_test.go +++ b/pkg/keda/lister_int_test.go @@ -13,7 +13,7 @@ func TestInt_List(t *testing.T) { listertesting.TestInt_List(t, keda.NewLister(true), keda.NewDeployer(keda.WithDeployerVerbose(true)), - keda.NewDescriber(true, nil), + keda.NewDescriber(true), keda.NewRemover(true), keda.KedaDeployerName) } diff --git a/pkg/keda/remover_int_test.go b/pkg/keda/remover_int_test.go index 416fe87d01..4dfa6e630c 100644 --- a/pkg/keda/remover_int_test.go +++ b/pkg/keda/remover_int_test.go @@ -13,7 +13,7 @@ func TestInt_Remove(t *testing.T) { removertesting.TestInt_Remove(t, keda.NewRemover(true), keda.NewDeployer(keda.WithDeployerVerbose(true)), - keda.NewDescriber(true, nil), + keda.NewDescriber(true), keda.NewLister(true), keda.KedaDeployerName) } diff --git a/pkg/knative/deployer_int_test.go b/pkg/knative/deployer_int_test.go index bba5f3ff9f..97895a9459 100644 --- a/pkg/knative/deployer_int_test.go +++ b/pkg/knative/deployer_int_test.go @@ -14,7 +14,7 @@ func TestInt_FullPath(t *testing.T) { knative.NewDeployer(knative.WithDeployerVerbose(true)), knative.NewRemover(true), knative.NewLister(true), - knative.NewDescriber(true, nil), + knative.NewDescriber(true), knative.KnativeDeployerName) } @@ -22,7 +22,7 @@ func TestInt_Deploy(t *testing.T) { deployertesting.TestInt_Deploy(t, knative.NewDeployer(knative.WithDeployerVerbose(true)), knative.NewRemover(false), - knative.NewDescriber(false, nil), + knative.NewDescriber(false), knative.KnativeDeployerName) } @@ -30,7 +30,7 @@ func TestInt_Metadata(t *testing.T) { deployertesting.TestInt_Metadata(t, knative.NewDeployer(knative.WithDeployerVerbose(true)), knative.NewRemover(false), - knative.NewDescriber(false, nil), + knative.NewDescriber(false), knative.KnativeDeployerName) } @@ -38,7 +38,7 @@ func TestInt_Events(t *testing.T) { deployertesting.TestInt_Events(t, knative.NewDeployer(knative.WithDeployerVerbose(true)), knative.NewRemover(false), - knative.NewDescriber(false, nil), + knative.NewDescriber(false), knative.KnativeDeployerName) } @@ -46,7 +46,7 @@ func TestInt_Scale(t *testing.T) { deployertesting.TestInt_Scale(t, knative.NewDeployer(knative.WithDeployerVerbose(true)), knative.NewRemover(false), - knative.NewDescriber(false, nil), + knative.NewDescriber(false), knative.KnativeDeployerName) } @@ -54,6 +54,6 @@ func TestInt_EnvsUpdate(t *testing.T) { deployertesting.TestInt_EnvsUpdate(t, knative.NewDeployer(knative.WithDeployerVerbose(true)), knative.NewRemover(false), - knative.NewDescriber(false, nil), + knative.NewDescriber(false), knative.KnativeDeployerName) } diff --git a/pkg/knative/describer.go b/pkg/knative/describer.go index bc2e54631b..1923c460a3 100644 --- a/pkg/knative/describer.go +++ b/pkg/knative/describer.go @@ -3,6 +3,7 @@ package knative import ( "context" "fmt" + "net/http" "strings" corev1 "k8s.io/api/core/v1" @@ -16,15 +17,24 @@ import ( ) type Describer struct { - verbose bool - imageInspector *fn.ImageInspector + verbose bool + transport http.RoundTripper } -func NewDescriber(verbose bool, imageInspector *fn.ImageInspector) *Describer { - return &Describer{ - verbose: verbose, - imageInspector: imageInspector, +type DescriberOpt func(*Describer) + +func WithDescriberTransport(transport http.RoundTripper) DescriberOpt { + return func(d *Describer) { + d.transport = transport + } +} + +func NewDescriber(verbose bool, opts ...DescriberOpt) *Describer { + d := &Describer{verbose: verbose} + for _, o := range opts { + o(d) } + return d } // Describe a function by name. Note that the consuming API uses domain style @@ -129,16 +139,13 @@ func (d *Describer) Describe(ctx context.Context, name, namespace string) (fn.In } } - if description.Image != "" && d.imageInspector != nil { - v, err := d.imageInspector.MiddlewareVersion(description.Image) + if description.Image != "" && d.transport != nil { + labels, err := fn.ImageLabels(description.Image, d.transport) if err == nil { description.Middleware = fn.Middleware{ - Version: v, + Version: labels[fn.MiddlewareVersionLabelKey], } - } - c, err := d.imageInspector.Commit(description.Image) - if err == nil { - description.Commit = c + description.Commit = labels[fn.CommitLabelKey] } } diff --git a/pkg/knative/describer_int_test.go b/pkg/knative/describer_int_test.go index 1b3c142add..4ddc036488 100644 --- a/pkg/knative/describer_int_test.go +++ b/pkg/knative/describer_int_test.go @@ -11,7 +11,7 @@ import ( func TestInt_Describe(t *testing.T) { describertesting.TestInt_Describe(t, - knative.NewDescriber(true, nil), + knative.NewDescriber(true), knative.NewDeployer(knative.WithDeployerVerbose(true)), knative.NewRemover(true), knative.KnativeDeployerName) diff --git a/pkg/knative/lister_int_test.go b/pkg/knative/lister_int_test.go index 1c5d188c3e..a316c55613 100644 --- a/pkg/knative/lister_int_test.go +++ b/pkg/knative/lister_int_test.go @@ -13,7 +13,7 @@ func TestInt_List(t *testing.T) { listertesting.TestInt_List(t, knative.NewLister(true), knative.NewDeployer(knative.WithDeployerVerbose(true)), - knative.NewDescriber(true, nil), + knative.NewDescriber(true), knative.NewRemover(true), knative.KnativeDeployerName) } diff --git a/pkg/knative/remover_int_test.go b/pkg/knative/remover_int_test.go index 2bf9a8ef86..6107e96a27 100644 --- a/pkg/knative/remover_int_test.go +++ b/pkg/knative/remover_int_test.go @@ -13,7 +13,7 @@ func TestInt_Remove(t *testing.T) { removertesting.TestInt_Remove(t, knative.NewRemover(true), knative.NewDeployer(knative.WithDeployerVerbose(true)), - knative.NewDescriber(true, nil), + knative.NewDescriber(true), knative.NewLister(true), knative.KnativeDeployerName) } diff --git a/pkg/pipelines/tekton/pipelines_int_test.go b/pkg/pipelines/tekton/pipelines_int_test.go index 4f7b4c908f..c0ecf5e87b 100644 --- a/pkg/pipelines/tekton/pipelines_int_test.go +++ b/pkg/pipelines/tekton/pipelines_int_test.go @@ -48,7 +48,7 @@ func newRemoteTestClient(verbose bool, deployer string, opts ...fn.Option) *fn.C baseOpts := []fn.Option{ fn.WithBuilder(buildpacks.NewBuilder(buildpacks.WithVerbose(verbose))), fn.WithPusher(docker.NewPusher(docker.WithCredentialsProvider(testCP))), - fn.WithDescribers(knative.NewDescriber(verbose, nil), k8s.NewDescriber(verbose, nil), keda.NewDescriber(verbose, nil)), + fn.WithDescribers(knative.NewDescriber(verbose), k8s.NewDescriber(verbose), keda.NewDescriber(verbose)), fn.WithListers(knative.NewLister(verbose), k8s.NewLister(verbose), keda.NewLister(verbose)), fn.WithRemovers(knative.NewRemover(verbose), k8s.NewRemover(verbose), keda.NewRemover(verbose)), fn.WithPipelinesProvider(tekton.NewPipelinesProvider(tekton.WithCredentialsProvider(testCP), tekton.WithVerbose(verbose))), diff --git a/pkg/pipelines/tekton/pipelines_provider.go b/pkg/pipelines/tekton/pipelines_provider.go index c2d590ee96..15182ecc12 100644 --- a/pkg/pipelines/tekton/pipelines_provider.go +++ b/pkg/pipelines/tekton/pipelines_provider.go @@ -7,6 +7,7 @@ import ( "fmt" "io" "io/fs" + "net/http" "os" "path" "path/filepath" @@ -56,7 +57,7 @@ type PipelinesProvider struct { getPacURL pacURLCallback credentialsProvider oci.CredentialsProvider decorator PipelineDecorator - imageInspector *fn.ImageInspector + transport http.RoundTripper } func WithCredentialsProvider(credentialsProvider oci.CredentialsProvider) Opt { @@ -77,9 +78,9 @@ func WithPipelineDecorator(decorator PipelineDecorator) Opt { } } -func WithImageInspector(ii *fn.ImageInspector) Opt { +func WithTransport(transport http.RoundTripper) Opt { return func(pp *PipelinesProvider) { - pp.imageInspector = ii + pp.transport = transport } } @@ -252,12 +253,12 @@ func (pp *PipelinesProvider) Run(ctx context.Context, f fn.Function) (string, fn var describer fn.Describer switch f.Deploy.Deployer { case k8s.KubernetesDeployerName: - describer = k8s.NewDescriber(false, pp.imageInspector) + describer = k8s.NewDescriber(false, k8s.WithDescriberTransport(pp.transport)) case keda.KedaDeployerName: - describer = keda.NewDescriber(false, pp.imageInspector) + describer = keda.NewDescriber(false, keda.WithDescriberTransport(pp.transport)) default: // default to knative - describer = knative.NewDescriber(false, pp.imageInspector) + describer = knative.NewDescriber(false, knative.WithDescriberTransport(pp.transport)) } obj, err := describer.Describe(ctx, f.Name, f.Namespace) From c9961b47f6f1b4d6755cb4c06dda20486c6e82b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20St=C3=A4bler?= Date: Mon, 27 Apr 2026 10:05:52 +0200 Subject: [PATCH 6/7] feat: use OCI standard label org.opencontainers.image.revision for commit --- pkg/functions/function_labels.go | 2 +- pkg/pipelines/tekton/task-buildpack.yaml.tmpl | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/functions/function_labels.go b/pkg/functions/function_labels.go index 0232b7a70d..9f6a67035f 100644 --- a/pkg/functions/function_labels.go +++ b/pkg/functions/function_labels.go @@ -13,7 +13,7 @@ import ( const ( MiddlewareVersionLabelKey = "middleware-version" - CommitLabelKey = "commit" + CommitLabelKey = "org.opencontainers.image.revision" ) type Label struct { diff --git a/pkg/pipelines/tekton/task-buildpack.yaml.tmpl b/pkg/pipelines/tekton/task-buildpack.yaml.tmpl index d71644ebfe..2fafd465f4 100644 --- a/pkg/pipelines/tekton/task-buildpack.yaml.tmpl +++ b/pkg/pipelines/tekton/task-buildpack.yaml.tmpl @@ -159,11 +159,11 @@ spec: echo "No middleware-version file ($middleware_version_file) found" fi - # Add commit label + # Add revision label commit="$(params.COMMIT)" if [ -n "$commit" ]; then - echo "--> Adding commit label: $commit" - echo -n " commit=$commit" >> "${ENV_DIR}/BP_IMAGE_LABELS" + echo "--> Adding revision label: $commit" + echo -n " org.opencontainers.image.revision=$commit" >> "${ENV_DIR}/BP_IMAGE_LABELS" fi ############################################ From 7afd4f240d1bee97048b97dedf49f733f18850e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20St=C3=A4bler?= Date: Mon, 27 Apr 2026 10:09:25 +0200 Subject: [PATCH 7/7] refactor: rename Instance.Commit to Instance.Revision in describe output --- pkg/functions/client.go | 2 +- pkg/k8s/describer.go | 2 +- pkg/keda/describer.go | 2 +- pkg/knative/describer.go | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/functions/client.go b/pkg/functions/client.go index 979368a0e0..54b9c1d115 100644 --- a/pkg/functions/client.go +++ b/pkg/functions/client.go @@ -188,7 +188,7 @@ type Instance struct { Subscriptions []Subscription `json:"subscriptions" yaml:"subscriptions"` Labels map[string]string `json:"labels" yaml:"labels" xml:"-"` Middleware Middleware `json:"middleware,omitempty" yaml:"middleware,omitempty"` - Commit string `json:"commit,omitempty" yaml:"commit,omitempty"` + Revision string `json:"revision,omitempty" yaml:"revision,omitempty"` Generation int64 `json:"generation,omitempty" yaml:"generation,omitempty"` Ready string `json:"ready,omitempty" yaml:"ready,omitempty"` } diff --git a/pkg/k8s/describer.go b/pkg/k8s/describer.go index 56ffc9c88e..14f8468fdf 100644 --- a/pkg/k8s/describer.go +++ b/pkg/k8s/describer.go @@ -109,7 +109,7 @@ func (d *Describer) Describe(ctx context.Context, name, namespace string) (fn.In Middleware: fn.Middleware{ Version: middlewareVersion, }, - Commit: commit, + Revision: commit, Generation: deployment.Generation, Ready: strings.ToLower(string(ready)), } diff --git a/pkg/keda/describer.go b/pkg/keda/describer.go index 5f06777842..946f6e2a44 100644 --- a/pkg/keda/describer.go +++ b/pkg/keda/describer.go @@ -128,7 +128,7 @@ func (d *Describer) Describe(ctx context.Context, name, namespace string) (fn.In Middleware: fn.Middleware{ Version: middlewareVersion, }, - Commit: commit, + Revision: commit, Generation: deployment.Generation, Ready: strings.ToLower(string(ready)), } diff --git a/pkg/knative/describer.go b/pkg/knative/describer.go index 1923c460a3..37de836cd8 100644 --- a/pkg/knative/describer.go +++ b/pkg/knative/describer.go @@ -145,7 +145,7 @@ func (d *Describer) Describe(ctx context.Context, name, namespace string) (fn.In description.Middleware = fn.Middleware{ Version: labels[fn.MiddlewareVersionLabelKey], } - description.Commit = labels[fn.CommitLabelKey] + description.Revision = labels[fn.CommitLabelKey] } }