Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions cmd/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,19 @@ 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)
pp = newTektonPipelinesProvider(c, cfg.Verbose, t)
o = []fn.Option{ // standard (shared) options for all commands
fn.WithVerbose(cfg.Verbose),
fn.WithTransport(t),
fn.WithRepositoriesPath(config.RepositoriesPath()),
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, 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),
Expand Down Expand Up @@ -143,11 +147,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, transport http.RoundTripper) *tekton.PipelinesProvider {
options := []tekton.Opt{
tekton.WithCredentialsProvider(creds),
tekton.WithVerbose(verbose),
tekton.WithPipelineDecorator(deployDecorator{}),
tekton.WithTransport(transport),
}

return tekton.NewPipelinesProvider(options...)
Expand Down
2 changes: 1 addition & 1 deletion cmd/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -782,7 +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)
o = append(o, fn.WithPipelinesProvider(newTektonPipelinesProvider(creds, c.Verbose)))
o = append(o, fn.WithPipelinesProvider(newTektonPipelinesProvider(creds, c.Verbose, t)))

// Add the appropriate deployer based on deploy type
deployer := c.Deployer
Expand Down
6 changes: 6 additions & 0 deletions cmd/func-util/s2i_generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ type genConfig struct {
imageScriptUrl string
logLevel string
middlewareVersion string
commit string
envVars []string
}

Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -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)
Expand Down
18 changes: 16 additions & 2 deletions pkg/buildpacks/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
1 change: 1 addition & 0 deletions pkg/functions/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"`
Revision string `json:"revision,omitempty" yaml:"revision,omitempty"`
Generation int64 `json:"generation,omitempty" yaml:"generation,omitempty"`
Ready string `json:"ready,omitempty" yaml:"ready,omitempty"`
}
Expand Down
28 changes: 28 additions & 0 deletions pkg/functions/function_labels.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,18 @@ 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"
)

const (
MiddlewareVersionLabelKey = "middleware-version"
CommitLabelKey = "org.opencontainers.image.revision"
)

type Label struct {
Expand Down Expand Up @@ -77,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
}
41 changes: 41 additions & 0 deletions pkg/functions/git_commit.go
Original file line number Diff line number Diff line change
@@ -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 "<sha>-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
}
33 changes: 0 additions & 33 deletions pkg/functions/middleware.go
Original file line number Diff line number Diff line change
@@ -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)
}
30 changes: 22 additions & 8 deletions pkg/k8s/describer.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package k8s
import (
"context"
"fmt"
"net/http"
"strings"

v1 "k8s.io/api/apps/v1"
Expand All @@ -13,13 +14,24 @@ import (
)

type Describer struct {
verbose bool
verbose bool
transport http.RoundTripper
}

func NewDescriber(verbose bool) *Describer {
return &Describer{
verbose: verbose,
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.
Expand Down Expand Up @@ -77,11 +89,12 @@ func (d *Describer) Describe(ctx context.Context, name, namespace string) (fn.In
}

middlewareVersion := ""
if image != "" {
v, err := fn.MiddlewareVersion(image)
commit := ""
if image != "" && d.transport != nil {
labels, err := fn.ImageLabels(image, d.transport)
if err == nil {
// don't fail on errors
middlewareVersion = v
middlewareVersion = labels[fn.MiddlewareVersionLabelKey]
commit = labels[fn.CommitLabelKey]
}
}

Expand All @@ -96,6 +109,7 @@ func (d *Describer) Describe(ctx context.Context, name, namespace string) (fn.In
Middleware: fn.Middleware{
Version: middlewareVersion,
},
Revision: commit,
Generation: deployment.Generation,
Ready: strings.ToLower(string(ready)),
}
Expand Down
30 changes: 22 additions & 8 deletions pkg/keda/describer.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package keda
import (
"context"
"fmt"
"net/http"
"strings"

"github.com/kedacore/http-add-on/operator/apis/http/v1alpha1"
Expand All @@ -15,13 +16,24 @@ import (
)

type Describer struct {
verbose bool
verbose bool
transport http.RoundTripper
}

func NewDescriber(verbose bool) *Describer {
return &Describer{
verbose: verbose,
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.
Expand Down Expand Up @@ -96,11 +108,12 @@ func (d *Describer) Describe(ctx context.Context, name, namespace string) (fn.In
}

middlewareVersion := ""
if image != "" {
v, err := fn.MiddlewareVersion(image)
commit := ""
if image != "" && d.transport != nil {
labels, err := fn.ImageLabels(image, d.transport)
if err == nil {
// don't fail on errors
middlewareVersion = v
middlewareVersion = labels[fn.MiddlewareVersionLabelKey]
commit = labels[fn.CommitLabelKey]
}
}

Expand All @@ -115,6 +128,7 @@ func (d *Describer) Describe(ctx context.Context, name, namespace string) (fn.In
Middleware: fn.Middleware{
Version: middlewareVersion,
},
Revision: commit,
Generation: deployment.Generation,
Ready: strings.ToLower(string(ready)),
}
Expand Down
Loading
Loading