mirror of https://github.com/knative/func.git
feat: s2i Go support (#2203)
This commit is contained in:
parent
e6fa020f78
commit
b0418f95bb
|
|
@ -12,6 +12,11 @@
|
||||||
/target
|
/target
|
||||||
/hack/bin
|
/hack/bin
|
||||||
|
|
||||||
|
/e2e/testdata/default_home/go
|
||||||
|
/e2e/testdata/default_home/.cache
|
||||||
|
|
||||||
|
/pkg/functions/testdata/migrations/*/.gitignore
|
||||||
|
|
||||||
# Nodejs
|
# Nodejs
|
||||||
node_modules
|
node_modules
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
package s2i
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
fn "knative.dev/func/pkg/functions"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GoAssembler
|
||||||
|
//
|
||||||
|
// Adapted from /usr/libexec/s2i/assemble within the UBI-8 go-toolchain
|
||||||
|
// such that the "go build" command builds subdirectory .s2i/builds/last
|
||||||
|
// (where main resides) rather than the root.
|
||||||
|
// TODO: many apps use the pattern of having main in a subdirectory, for
|
||||||
|
// example the idiomatic "./cmd/myapp/main.go". It would therefore be
|
||||||
|
// beneficial to submit a patch to the go-toolchain source allowing this
|
||||||
|
// path to be customized with an environment variable instead
|
||||||
|
const GoAssembler = `
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
pushd /tmp/src
|
||||||
|
if [[ $(go list -f {{.Incomplete}}) == "true" ]]; then
|
||||||
|
INSTALL_URL=${INSTALL_URL:-$IMPORT_URL}
|
||||||
|
if [[ ! -z "$IMPORT_URL" ]]; then
|
||||||
|
popd
|
||||||
|
echo "Assembling GOPATH"
|
||||||
|
export GOPATH=$(realpath $HOME/go)
|
||||||
|
mkdir -p $GOPATH/src/$IMPORT_URL
|
||||||
|
mv /tmp/src/* $GOPATH/src/$IMPORT_URL
|
||||||
|
if [[ -d /tmp/artifacts/pkg ]]; then
|
||||||
|
echo "Restoring previous build artifacts"
|
||||||
|
mv /tmp/artifacts/pkg $GOPATH
|
||||||
|
fi
|
||||||
|
# Resolve dependencies, ignore if vendor present
|
||||||
|
if [[ ! -d $GOPATH/src/$INSTALL_URL/vendor ]]; then
|
||||||
|
echo "Resolving dependencies"
|
||||||
|
pushd $GOPATH/src/$INSTALL_URL
|
||||||
|
go get
|
||||||
|
popd
|
||||||
|
fi
|
||||||
|
# lets build
|
||||||
|
pushd $GOPATH/src/$INSTALL_URL
|
||||||
|
echo "Building"
|
||||||
|
go install -i $INSTALL_URL
|
||||||
|
mv $GOPATH/bin/* /opt/app-root/gobinary
|
||||||
|
popd
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
exec /$STI_SCRIPTS_PATH/usage
|
||||||
|
else
|
||||||
|
pushd .s2i/builds/last
|
||||||
|
go get f
|
||||||
|
go build -o /opt/app-root/gobinary
|
||||||
|
popd
|
||||||
|
popd
|
||||||
|
fi
|
||||||
|
`
|
||||||
|
|
||||||
|
func assembler(f fn.Function) (string, error) {
|
||||||
|
switch f.Runtime {
|
||||||
|
case "go":
|
||||||
|
return GoAssembler, nil
|
||||||
|
default:
|
||||||
|
return "", fmt.Errorf("no assembler defined for runtime %q", f.Runtime)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -33,6 +33,7 @@ import (
|
||||||
"knative.dev/func/pkg/builders"
|
"knative.dev/func/pkg/builders"
|
||||||
"knative.dev/func/pkg/docker"
|
"knative.dev/func/pkg/docker"
|
||||||
fn "knative.dev/func/pkg/functions"
|
fn "knative.dev/func/pkg/functions"
|
||||||
|
"knative.dev/func/pkg/scaffolding"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DefaultName when no WithName option is provided to NewBuilder
|
// DefaultName when no WithName option is provided to NewBuilder
|
||||||
|
|
@ -41,14 +42,16 @@ const DefaultName = builders.S2I
|
||||||
var DefaultNodeBuilder = "registry.access.redhat.com/ubi8/nodejs-20-minimal"
|
var DefaultNodeBuilder = "registry.access.redhat.com/ubi8/nodejs-20-minimal"
|
||||||
var DefaultQuarkusBuilder = "registry.access.redhat.com/ubi8/openjdk-21"
|
var DefaultQuarkusBuilder = "registry.access.redhat.com/ubi8/openjdk-21"
|
||||||
var DefaultPythonBuilder = "registry.access.redhat.com/ubi8/python-39"
|
var DefaultPythonBuilder = "registry.access.redhat.com/ubi8/python-39"
|
||||||
|
var DefaultGoBuilder = "registry.access.redhat.com/ubi8/go-toolset"
|
||||||
|
|
||||||
// DefaultBuilderImages for s2i builders indexed by Runtime Language
|
// DefaultBuilderImages for s2i builders indexed by Runtime Language
|
||||||
var DefaultBuilderImages = map[string]string{
|
var DefaultBuilderImages = map[string]string{
|
||||||
|
"go": DefaultGoBuilder,
|
||||||
"node": DefaultNodeBuilder,
|
"node": DefaultNodeBuilder,
|
||||||
"nodejs": DefaultNodeBuilder,
|
"nodejs": DefaultNodeBuilder,
|
||||||
"typescript": DefaultNodeBuilder,
|
|
||||||
"quarkus": DefaultQuarkusBuilder,
|
|
||||||
"python": DefaultPythonBuilder,
|
"python": DefaultPythonBuilder,
|
||||||
|
"quarkus": DefaultQuarkusBuilder,
|
||||||
|
"typescript": DefaultNodeBuilder,
|
||||||
}
|
}
|
||||||
|
|
||||||
// DockerClient is subset of dockerClient.CommonAPIClient required by this package
|
// DockerClient is subset of dockerClient.CommonAPIClient required by this package
|
||||||
|
|
@ -120,7 +123,8 @@ func (b *Builder) Build(ctx context.Context, f fn.Function, platforms []fn.Platf
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// If a platform was requestd
|
|
||||||
|
// Validate Platforms
|
||||||
if len(platforms) == 1 {
|
if len(platforms) == 1 {
|
||||||
platform := strings.ToLower(platforms[0].OS + "/" + platforms[0].Architecture)
|
platform := strings.ToLower(platforms[0].OS + "/" + platforms[0].Architecture)
|
||||||
// Try to get the platform image from within the builder image
|
// Try to get the platform image from within the builder image
|
||||||
|
|
@ -134,47 +138,6 @@ func (b *Builder) Build(ctx context.Context, f fn.Function, platforms []fn.Platf
|
||||||
return errors.New("the S2I builder currently only supports specifying a single target platform")
|
return errors.New("the S2I builder currently only supports specifying a single target platform")
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO this function currently doesn't support private s2i builder images since credentials are not set
|
|
||||||
|
|
||||||
// Build Config
|
|
||||||
cfg := &api.Config{}
|
|
||||||
cfg.Quiet = !b.verbose
|
|
||||||
cfg.Tag = f.Build.Image
|
|
||||||
cfg.Source = &git.URL{URL: url.URL{Path: f.Root}, Type: git.URLTypeLocal}
|
|
||||||
cfg.BuilderImage = builderImage
|
|
||||||
cfg.BuilderPullPolicy = api.DefaultBuilderPullPolicy
|
|
||||||
cfg.PreviousImagePullPolicy = api.DefaultPreviousImagePullPolicy
|
|
||||||
cfg.RuntimeImagePullPolicy = api.DefaultRuntimeImagePullPolicy
|
|
||||||
cfg.DockerConfig = s2idocker.GetDefaultDockerConfig()
|
|
||||||
|
|
||||||
tmp, err := os.MkdirTemp("", "s2i-build")
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("cannot create temporary dir for s2i build: %w", err)
|
|
||||||
}
|
|
||||||
defer os.RemoveAll(tmp)
|
|
||||||
|
|
||||||
funcignorePath := filepath.Join(f.Root, ".funcignore")
|
|
||||||
if _, err := os.Stat(funcignorePath); err == nil {
|
|
||||||
s2iignorePath := filepath.Join(f.Root, ".s2iignore")
|
|
||||||
|
|
||||||
// If the .s2iignore file exists, remove it
|
|
||||||
if _, err := os.Stat(s2iignorePath); err == nil {
|
|
||||||
err := os.Remove(s2iignorePath)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("error removing existing s2iignore file: %w", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Create the symbolic link
|
|
||||||
err = os.Symlink(funcignorePath, s2iignorePath)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("error creating symlink: %w", err)
|
|
||||||
}
|
|
||||||
// Removing the symbolic link at the end of the function
|
|
||||||
defer os.Remove(s2iignorePath)
|
|
||||||
}
|
|
||||||
|
|
||||||
cfg.AsDockerfile = filepath.Join(tmp, "Dockerfile")
|
|
||||||
|
|
||||||
var client = b.cli
|
var client = b.cli
|
||||||
if client == nil {
|
if client == nil {
|
||||||
var c dockerClient.CommonAPIClient
|
var c dockerClient.CommonAPIClient
|
||||||
|
|
@ -186,11 +149,60 @@ func (b *Builder) Build(ctx context.Context, f fn.Function, platforms []fn.Platf
|
||||||
client = c
|
client = c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Link .s2iignore -> .funcignore
|
||||||
|
funcignorePath := filepath.Join(f.Root, ".funcignore")
|
||||||
|
s2iignorePath := filepath.Join(f.Root, ".s2iignore")
|
||||||
|
if _, err := os.Stat(funcignorePath); err == nil {
|
||||||
|
if _, err := os.Stat(s2iignorePath); err == nil {
|
||||||
|
fmt.Fprintln(os.Stderr, "Warning: an existing .s2iignore was detected. Using this with preference over .funcignore")
|
||||||
|
} else {
|
||||||
|
if err = os.Symlink("./.funcignore", s2iignorePath); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer os.Remove(s2iignorePath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build directory
|
||||||
|
tmp, err := os.MkdirTemp("", "func-s2i-build")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cannot create temporary dir for s2i build: %w", err)
|
||||||
|
}
|
||||||
|
defer os.RemoveAll(tmp)
|
||||||
|
|
||||||
|
// Build Config
|
||||||
|
cfg := &api.Config{
|
||||||
|
Source: &git.URL{
|
||||||
|
Type: git.URLTypeLocal,
|
||||||
|
URL: url.URL{Path: f.Root},
|
||||||
|
},
|
||||||
|
Quiet: !b.verbose,
|
||||||
|
Tag: f.Build.Image,
|
||||||
|
BuilderImage: builderImage,
|
||||||
|
BuilderPullPolicy: api.DefaultBuilderPullPolicy,
|
||||||
|
PreviousImagePullPolicy: api.DefaultPreviousImagePullPolicy,
|
||||||
|
RuntimeImagePullPolicy: api.DefaultRuntimeImagePullPolicy,
|
||||||
|
DockerConfig: s2idocker.GetDefaultDockerConfig(),
|
||||||
|
AsDockerfile: filepath.Join(tmp, "Dockerfile"),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scaffold
|
||||||
|
if cfg, err = scaffold(cfg, f); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract a an S2I script url from the image if provided and use
|
||||||
|
// this in the build config.
|
||||||
scriptURL, err := s2iScriptURL(ctx, client, cfg.BuilderImage)
|
scriptURL, err := s2iScriptURL(ctx, client, cfg.BuilderImage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("cannot get s2i script url: %w", err)
|
return fmt.Errorf("cannot get s2i script url: %w", err)
|
||||||
|
} else if scriptURL != "image:///usr/libexec/s2i" {
|
||||||
|
// Only set if the label found on the image is NOT the default.
|
||||||
|
// Otherwise this label, which is essentially a default fallback, will
|
||||||
|
// take precidence over any scripts provided in ./.s2i/bin, which are
|
||||||
|
// supposed to be the override to that default.
|
||||||
|
cfg.ScriptsURL = scriptURL
|
||||||
}
|
}
|
||||||
cfg.ScriptsURL = scriptURL
|
|
||||||
|
|
||||||
// Excludes
|
// Excludes
|
||||||
// Do not include .git, .env, .func or any language-specific cache directories
|
// Do not include .git, .env, .func or any language-specific cache directories
|
||||||
|
|
@ -218,8 +230,8 @@ func (b *Builder) Build(ctx context.Context, f fn.Function, platforms []fn.Platf
|
||||||
return errors.New("Unable to build via the s2i builder.")
|
return errors.New("Unable to build via the s2i builder.")
|
||||||
}
|
}
|
||||||
|
|
||||||
var impl = b.impl
|
|
||||||
// Create the S2I builder instance if not overridden
|
// Create the S2I builder instance if not overridden
|
||||||
|
var impl = b.impl
|
||||||
if impl == nil {
|
if impl == nil {
|
||||||
impl, _, err = strategies.Strategy(nil, cfg, build.Overrides{})
|
impl, _, err = strategies.Strategy(nil, cfg, build.Overrides{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -235,7 +247,7 @@ func (b *Builder) Build(ctx context.Context, f fn.Function, platforms []fn.Platf
|
||||||
|
|
||||||
if b.verbose {
|
if b.verbose {
|
||||||
for _, message := range result.Messages {
|
for _, message := range result.Messages {
|
||||||
fmt.Println(message)
|
fmt.Fprintln(os.Stderr, message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -400,3 +412,56 @@ func BuilderImage(f fn.Function, builderName string) (string, error) {
|
||||||
// delegate as the logic is shared amongst builders
|
// delegate as the logic is shared amongst builders
|
||||||
return builders.Image(f, builderName, DefaultBuilderImages)
|
return builders.Image(f, builderName, DefaultBuilderImages)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// scaffold the project
|
||||||
|
// Returns a config with settings suitable for building runtimes which
|
||||||
|
// support scaffolding.
|
||||||
|
func scaffold(cfg *api.Config, f fn.Function) (*api.Config, error) {
|
||||||
|
// Scafffolding is currently only supported by the Go runtime
|
||||||
|
if f.Runtime != "go" {
|
||||||
|
return cfg, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
contextDir := filepath.Join(".s2i", "builds", "last")
|
||||||
|
appRoot := filepath.Join(f.Root, contextDir)
|
||||||
|
_ = os.RemoveAll(appRoot)
|
||||||
|
|
||||||
|
// The enbedded repository contains the scaffolding code itself which glues
|
||||||
|
// together the middleware and a function via main
|
||||||
|
embeddedRepo, err := fn.NewRepository("", "") // default is the embedded fs
|
||||||
|
if err != nil {
|
||||||
|
return cfg, fmt.Errorf("unable to load the embedded scaffolding. %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write scaffolding to .s2i/builds/last
|
||||||
|
err = scaffolding.Write(appRoot, f.Root, f.Runtime, f.Invoke, embeddedRepo.FS())
|
||||||
|
if err != nil {
|
||||||
|
return cfg, fmt.Errorf("unable to build due to a scaffold error. %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write out an S2I assembler script if the runtime needs to override the
|
||||||
|
// one provided in the S2I image.
|
||||||
|
assemble, err := assembler(f)
|
||||||
|
if err != nil {
|
||||||
|
return cfg, err
|
||||||
|
}
|
||||||
|
if assemble != "" {
|
||||||
|
if err := os.MkdirAll(filepath.Join(f.Root, ".s2i", "bin"), 0755); err != nil {
|
||||||
|
return nil, fmt.Errorf("unable to create .s2i bin dir. %w", err)
|
||||||
|
}
|
||||||
|
if err := os.WriteFile(filepath.Join(f.Root, ".s2i", "bin", "assemble"), []byte(assemble), 0700); err != nil {
|
||||||
|
return nil, fmt.Errorf("unable to write go assembler. %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg.KeepSymlinks = true // Don't infinite loop on the symlink to root.
|
||||||
|
|
||||||
|
// We want to force that the system use the (copy via filesystem)
|
||||||
|
// method rather than a "git clone" method because (other than being
|
||||||
|
// faster) appears to have a bug where the assemble script is ignored.
|
||||||
|
// Maybe this issue is related:
|
||||||
|
// https://github.com/openshift/source-to-image/issues/1141
|
||||||
|
cfg.ForceCopy = true
|
||||||
|
|
||||||
|
return cfg, nil
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ import (
|
||||||
"knative.dev/func/pkg/builders"
|
"knative.dev/func/pkg/builders"
|
||||||
"knative.dev/func/pkg/builders/s2i"
|
"knative.dev/func/pkg/builders/s2i"
|
||||||
fn "knative.dev/func/pkg/functions"
|
fn "knative.dev/func/pkg/functions"
|
||||||
|
. "knative.dev/func/pkg/testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Test_BuildImages ensures that supported runtimes returns builder image
|
// Test_BuildImages ensures that supported runtimes returns builder image
|
||||||
|
|
@ -60,9 +61,9 @@ func Test_BuildImages(t *testing.T) {
|
||||||
wantErr: false,
|
wantErr: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Without builder - unsupported runtime - go",
|
name: "Without builder - supported runtime - go",
|
||||||
function: fn.Function{Runtime: "go"},
|
function: fn.Function{Runtime: "go"},
|
||||||
wantErr: true,
|
wantErr: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Without builder - supported runtime - python",
|
name: "Without builder - supported runtime - python",
|
||||||
|
|
@ -91,17 +92,30 @@ func Test_BuildImages(t *testing.T) {
|
||||||
// define a Builder Image will default.
|
// define a Builder Image will default.
|
||||||
func Test_BuilderImageDefault(t *testing.T) {
|
func Test_BuilderImageDefault(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
i = &mockImpl{} // mock underlying s2i implementation
|
root, done = Mktemp(t)
|
||||||
c = mockDocker{} // mock docker client
|
runtime = "go"
|
||||||
f = fn.Function{Runtime: "node"} // function with no builder image set
|
impl = &mockImpl{} // mock the underlying s2i implementation
|
||||||
b = s2i.NewBuilder( // func S2I Builder logic
|
f = fn.Function{
|
||||||
s2i.WithImpl(i), s2i.WithDockerClient(c))
|
Name: "test",
|
||||||
|
Root: root,
|
||||||
|
Runtime: runtime,
|
||||||
|
Registry: "example.com/alice"} // function with no builder image set
|
||||||
|
builder = s2i.NewBuilder( // func S2I Builder logic
|
||||||
|
s2i.WithImpl(impl),
|
||||||
|
s2i.WithDockerClient(mockDocker{}))
|
||||||
|
err error
|
||||||
)
|
)
|
||||||
|
defer done()
|
||||||
|
|
||||||
// An implementation of the underlying S2I implementation which verifies
|
// Initialize the test function
|
||||||
|
if f, err = fn.New().Init(f); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// An implementation of the underlying S2I builder which verifies
|
||||||
// the config has arrived as expected (correct functions logic applied)
|
// the config has arrived as expected (correct functions logic applied)
|
||||||
i.BuildFn = func(cfg *api.Config) (*api.Result, error) {
|
impl.BuildFn = func(cfg *api.Config) (*api.Result, error) {
|
||||||
expected := s2i.DefaultBuilderImages["node"]
|
expected := s2i.DefaultBuilderImages[runtime]
|
||||||
if cfg.BuilderImage != expected {
|
if cfg.BuilderImage != expected {
|
||||||
t.Fatalf("expected s2i config builder image '%v', got '%v'",
|
t.Fatalf("expected s2i config builder image '%v', got '%v'",
|
||||||
expected, cfg.BuilderImage)
|
expected, cfg.BuilderImage)
|
||||||
|
|
@ -111,7 +125,7 @@ func Test_BuilderImageDefault(t *testing.T) {
|
||||||
|
|
||||||
// Invoke Build, which runs function Builder logic before invoking the
|
// Invoke Build, which runs function Builder logic before invoking the
|
||||||
// mock impl above.
|
// mock impl above.
|
||||||
if err := b.Build(context.Background(), f, nil); err != nil {
|
if err := builder.Build(context.Background(), f, nil); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -151,8 +165,8 @@ func Test_BuilderImageConfigurable(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test_BuildImageWithFuncIgnore ensures that ignored files are not added to the func
|
// Test_BuildImageWithFuncIgnore ensures that ignored files are not added to
|
||||||
// image
|
// the func image
|
||||||
func Test_BuildImageWithFuncIgnore(t *testing.T) {
|
func Test_BuildImageWithFuncIgnore(t *testing.T) {
|
||||||
|
|
||||||
funcIgnoreContent := []byte(`#testing Comments
|
funcIgnoreContent := []byte(`#testing Comments
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ func TestPusher_Push(t *testing.T) {
|
||||||
|
|
||||||
// Create and push a function
|
// Create and push a function
|
||||||
client := fn.New(
|
client := fn.New(
|
||||||
fn.WithBuilder(NewBuilder("", verbose)),
|
fn.WithBuilder(NewBuilder("", false)),
|
||||||
fn.WithPusher(NewPusher(insecure, anon, verbose)))
|
fn.WithPusher(NewPusher(insecure, anon, verbose)))
|
||||||
|
|
||||||
f := fn.Function{Root: root, Runtime: "go", Name: "f", Registry: l.Addr().String() + "/funcs"}
|
f := fn.Function{Root: root, Runtime: "go", Name: "f", Registry: l.Addr().String() + "/funcs"}
|
||||||
|
|
@ -85,7 +85,7 @@ func TestPusher_Push(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestPusher_Auth ensures that the pusher authenticates via basic auth when
|
// TestPusher_BasicAuth ensures that the pusher authenticates via basic auth when
|
||||||
// supplied with a username/password via the context.
|
// supplied with a username/password via the context.
|
||||||
func TestPusher_BasicAuth(t *testing.T) {
|
func TestPusher_BasicAuth(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
|
|
@ -106,7 +106,7 @@ func TestPusher_BasicAuth(t *testing.T) {
|
||||||
// no header. ask for auth
|
// no header. ask for auth
|
||||||
w.Header().Add("www-authenticate", "Basic realm=\"Registry Realm\"")
|
w.Header().Add("www-authenticate", "Basic realm=\"Registry Realm\"")
|
||||||
http.Error(w, "Unauthorized", http.StatusUnauthorized)
|
http.Error(w, "Unauthorized", http.StatusUnauthorized)
|
||||||
} else if u != "username" || p != "password" {
|
} else if u != username || p != password {
|
||||||
// header exists, but creds are either missing or incorrect
|
// header exists, but creds are either missing or incorrect
|
||||||
t.Fatalf("Unauthorized. Expected user %q pass %q, got user %q pass %q", username, password, u, p)
|
t.Fatalf("Unauthorized. Expected user %q pass %q, got user %q pass %q", username, password, u, p)
|
||||||
http.Error(w, "Unauthorized", http.StatusUnauthorized)
|
http.Error(w, "Unauthorized", http.StatusUnauthorized)
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ func Test_validatePipeline(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "Unsupported runtime - Go - s2i builder",
|
name: "Unsupported runtime - Go - s2i builder",
|
||||||
function: fn.Function{Build: fn.BuildSpec{Builder: builders.S2I}, Runtime: "go"},
|
function: fn.Function{Build: fn.BuildSpec{Builder: builders.S2I}, Runtime: "go"},
|
||||||
wantErr: true,
|
wantErr: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Supported runtime - Quarkus - pack builder - without additional Buildpacks",
|
name: "Supported runtime - Quarkus - pack builder - without additional Buildpacks",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue