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
2 changes: 1 addition & 1 deletion Dockerfile.podman-next
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ unqualified-search-registries = ["docker.io", "quay.io", "registry.fedoraproject
short-name-mode="permissive"

[[registry]]
location="localhost:50000"
location="registry.localtest.me"
insecure=true
EOF

Expand Down
8 changes: 5 additions & 3 deletions cmd/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,7 @@ func (c buildConfig) clientOptions() ([]fn.Option, error) {
}

t := newTransport(c.RegistryInsecure)
creds := newCredentialsProvider(config.Dir(), t, c.RegistryAuthfile)
creds := newCredentialsProvider(config.Dir(), t, c.RegistryAuthfile, c.RegistryInsecure)

switch c.Builder {
case builders.Host:
Expand All @@ -470,7 +470,8 @@ func (c buildConfig) clientOptions() ([]fn.Option, error) {
fn.WithPusher(docker.NewPusher(
docker.WithCredentialsProvider(creds),
docker.WithTransport(t),
docker.WithVerbose(c.Verbose))))
docker.WithVerbose(c.Verbose),
docker.WithInsecure(c.RegistryInsecure))))
case builders.S2I:
o = append(o,
fn.WithScaffolder(s2i.NewScaffolder(c.Verbose)),
Expand All @@ -480,7 +481,8 @@ func (c buildConfig) clientOptions() ([]fn.Option, error) {
fn.WithPusher(docker.NewPusher(
docker.WithCredentialsProvider(creds),
docker.WithTransport(t),
docker.WithVerbose(c.Verbose))))
docker.WithVerbose(c.Verbose),
docker.WithInsecure(c.RegistryInsecure))))
default:
return o, builders.ErrUnknownBuilder{Name: c.Builder, Known: KnownBuilders()}
}
Expand Down
13 changes: 8 additions & 5 deletions cmd/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,9 @@ func NewTestClient(options ...fn.Option) ClientFactory {
// 'Verbose' indicates the system should write out a higher amount of logging.
func NewClient(cfg ClientConfig, options ...fn.Option) (*fn.Client, func()) {
var (
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)
t = newTransport(cfg.InsecureSkipVerify) // may provide a custom impl which proxies
c = newCredentialsProvider(config.Dir(), t, "", cfg.InsecureSkipVerify) // for accessing registries
d = newKnativeDeployer(cfg.Verbose) // default deployer (can be overridden via options)
pp = newTektonPipelinesProvider(c, cfg.Verbose, t)
o = []fn.Option{ // standard (shared) options for all commands
fn.WithVerbose(cfg.Verbose),
Expand All @@ -81,7 +81,8 @@ func NewClient(cfg ClientConfig, options ...fn.Option) (*fn.Client, func()) {
fn.WithPusher(docker.NewPusher(
docker.WithCredentialsProvider(c),
docker.WithTransport(t),
docker.WithVerbose(cfg.Verbose))),
docker.WithVerbose(cfg.Verbose),
docker.WithInsecure(cfg.InsecureSkipVerify))),
}
)

Expand Down Expand Up @@ -110,7 +111,8 @@ func newTransport(insecureSkipVerify bool) fnhttp.RoundTripCloser {
// has cluster-flavor specific additional credential loaders to take advantage
// of features or configuration nuances of cluster variants.
// If authFilePath is provided (non-empty), it will be used as the primary auth file.
func newCredentialsProvider(configPath string, t http.RoundTripper, authFilePath string) oci.CredentialsProvider {
// When insecure is true, credential verification uses plain HTTP instead of HTTPS.
func newCredentialsProvider(configPath string, t http.RoundTripper, authFilePath string, insecure bool) oci.CredentialsProvider {
additionalLoaders := append(k8s.GetOpenShiftDockerCredentialLoaders(), k8s.GetGoogleCredentialLoader()...)
additionalLoaders = append(additionalLoaders, k8s.GetECRCredentialLoader()...)
additionalLoaders = append(additionalLoaders, k8s.GetACRCredentialLoader()...)
Expand All @@ -135,6 +137,7 @@ func newCredentialsProvider(configPath string, t http.RoundTripper, authFilePath
creds.WithPromptForCredentials(prompt.NewPromptForCredentials(os.Stdin, os.Stdout, os.Stderr)),
creds.WithPromptForCredentialStore(prompt.NewPromptForCredentialStore()),
creds.WithTransport(t),
creds.WithInsecure(insecure),
creds.WithAdditionalCredentialLoaders(additionalLoaders...),
}

Expand Down
2 changes: 1 addition & 1 deletion cmd/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -791,7 +791,7 @@ func (c deployConfig) clientOptions() ([]fn.Option, error) {
}

t := newTransport(c.RegistryInsecure)
creds := newCredentialsProvider(config.Dir(), t, c.RegistryAuthfile)
creds := newCredentialsProvider(config.Dir(), t, c.RegistryAuthfile, c.RegistryInsecure)

// Override the pipelines provider to use custom credentials
// This is needed for remote builds (deploy --remote)
Expand Down
4 changes: 2 additions & 2 deletions e2e/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,13 +99,13 @@ the `kn-func` plugged in use `FUNC_E2E_BIN=/path/to/kn FUNC_E2E_PLUGIN=func`.

`FUNC_E2E_REGISTRY`: if provided, tests will use this registry (in form
`registry.example.com/user`) instead of the test suite default of
`localhost:50000/func`. This is used for local builds that push from the
`registry.localtest.me/func`. This is used for local builds that push from the
developer's machine to the registry.

`FUNC_E2E_CLUSTER_REGISTRY`: specifies the cluster-internal registry URL used
for in-cluster (remote) builds with Tekton. This registry must be accessible
from within the cluster. Format: `registry.namespace.svc.cluster.local:port/path`.
Defaults to `registry.default.svc.cluster.local:5000/func`.
Defaults to `registry.localtest.me/func`.

`FUNC_E2E_MATRIX_RUNTIMES`: Sets which runtimes will be tested during the matrix
tests. By default matrix test are not enabled unless this value is passed.
Expand Down
63 changes: 59 additions & 4 deletions e2e/e2e_config_ci_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ import (
"fmt"
"os"
"os/exec"
"path/filepath"
"strings"
"testing"

"gopkg.in/yaml.v3"
)

func TestConfigCI_DeployFuncViaGeneratedGitHubWorkflow(t *testing.T) {
Expand Down Expand Up @@ -72,12 +76,20 @@ func gitInit(t *testing.T, dir string) {
func runGitHubWorkflow(t *testing.T, dir string) {
t.Helper()

cmd := exec.Command("act", "push",
// Patch the generated workflow to use the locally-built func binary
// instead of downloading a release via functions-dev/action.
patchWorkflowWithLocalBinary(t, filepath.Join(dir, ".github", "workflows", "func-deploy.yaml"))

args := []string{"push",
"-P", "ubuntu-latest=-self-hosted",
"-W", ".github/workflows/func-deploy.yaml",
"-s", "KUBECONFIG="+readFile(t, Kubeconfig),
"--var", "REGISTRY_URL="+Registry,
)
"-s", "KUBECONFIG=" + readFile(t, Kubeconfig),
"--var", "REGISTRY_URL=" + Registry,
}
if strings.Contains(Registry, "registry.localtest.me") {
args = append(args, "--env", "FUNC_REGISTRY_INSECURE=true")
}
cmd := exec.Command("act", args...)
cmd.Dir = dir
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
Expand All @@ -86,6 +98,49 @@ func runGitHubWorkflow(t *testing.T, dir string) {
}
}

// patchWorkflowWithLocalBinary replaces the "Install func cli" step in the
// generated GitHub workflow with a step that symlinks the locally-built binary.
// This ensures the CI config test exercises the current code rather than a
// released version that may lack recent fixes.
func patchWorkflowWithLocalBinary(t *testing.T, workflowPath string) {
t.Helper()

data, err := os.ReadFile(workflowPath)
if err != nil {
t.Fatalf("failed to read workflow %s: %v", workflowPath, err)
}

var wf map[string]interface{}
if err := yaml.Unmarshal(data, &wf); err != nil {
t.Fatalf("failed to parse workflow: %v", err)
}

jobs, _ := wf["jobs"].(map[string]interface{})
deploy, _ := jobs["deploy"].(map[string]interface{})
steps, _ := deploy["steps"].([]interface{})

binDir := t.TempDir()
for i, s := range steps {
step, _ := s.(map[string]interface{})
if step["name"] == "Install func cli" {
steps[i] = map[string]interface{}{
"name": "Install func cli",
"run": fmt.Sprintf("ln -sf %s %s/func && echo %s >> $GITHUB_PATH", Bin, binDir, binDir),
}
break
}
}

out, err := yaml.Marshal(wf)
if err != nil {
t.Fatalf("failed to marshal workflow: %v", err)
}

if err := os.WriteFile(workflowPath, out, 0644); err != nil {
t.Fatalf("failed to write workflow %s: %v", workflowPath, err)
}
}

func readFile(t *testing.T, path string) string {
t.Helper()

Expand Down
2 changes: 1 addition & 1 deletion e2e/e2e_matrix_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ func TestMatrix_Remote(t *testing.T) {
}

// Deploy
if err := newCmd(t, "deploy", "--builder", builder, "--remote", fmt.Sprintf("--registry=%s", ClusterRegistry)).Run(); err != nil {
if err := newCmd(t, "deploy", "--builder", builder, "--remote", fmt.Sprintf("--registry=%s", Registry)).Run(); err != nil {
t.Fatal(err)
}

Expand Down
31 changes: 27 additions & 4 deletions e2e/e2e_remote_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func TestRemote_Deploy(t *testing.T) {
if err := newCmd(t, "init", "-l=go").Run(); err != nil {
t.Fatal(err)
}
if err := newCmd(t, "deploy", "--remote", "--builder=pack", fmt.Sprintf("--registry=%s", ClusterRegistry)).Run(); err != nil {
if err := newCmd(t, "deploy", "--remote", "--builder=pack", fmt.Sprintf("--registry=%s", Registry)).Run(); err != nil {
t.Fatal(err)
}
defer func() {
Expand Down Expand Up @@ -57,7 +57,7 @@ func TestRemote_Source(t *testing.T) {
// Trigger the deploy
if err := newCmd(t, "deploy", "--remote",
"--git-url", "https://github.com/functions-dev/func-e2e-tests",
"--registry", ClusterRegistry,
"--registry", Registry,
"--builder", "pack",
).Run(); err != nil {
t.Fatal(err)
Expand Down Expand Up @@ -101,7 +101,7 @@ func TestRemote_Ref(t *testing.T) {
if err := newCmd(t, "deploy", "--remote",
"--git-url", "https://github.com/functions-dev/func-e2e-tests",
"--git-branch", name,
"--registry", ClusterRegistry,
"--registry", Registry,
"--builder", "pack",
"--build",
).Run(); err != nil {
Expand Down Expand Up @@ -148,7 +148,7 @@ func TestRemote_Dir(t *testing.T) {
if err := newCmd(t, "deploy", "--remote",
"--git-url", "https://github.com/functions-dev/func-e2e-tests",
"--git-dir", name,
"--registry", ClusterRegistry,
"--registry", Registry,
"--builder", "pack",
"--build",
).Run(); err != nil {
Expand All @@ -163,3 +163,26 @@ func TestRemote_Dir(t *testing.T) {
t.Fatal("function did not deploy correctly")
}
}

// TestRemote_Deploy_InClusterRegistry ensures that the in-cluster dialer
// tunneling path works correctly by using the cluster-internal registry URL.
//
// func deploy --remote --registry=registry.default.svc.cluster.local:5000/func
func TestRemote_Deploy_InClusterRegistry(t *testing.T) {
name := "func-e2e-test-remote-incluster"
_ = fromCleanEnv(t, name)

if err := newCmd(t, "init", "-l=go").Run(); err != nil {
t.Fatal(err)
}
if err := newCmd(t, "deploy", "--remote", "--builder=pack", "--registry=registry.default.svc.cluster.local:5000/func").Run(); err != nil {
t.Fatal(err)
}
defer func() {
clean(t, name, Namespace)
}()

if !waitFor(t, ksvcUrl(name)) {
t.Fatal("function did not deploy correctly")
}
}
33 changes: 10 additions & 23 deletions e2e/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,13 +88,13 @@ const (
// of the registry created by default when using the cluster.sh script
// to set up a local testing cluster, but can be customized with
// FUNC_E2E_REGISTRY.
DefaultRegistry = "localhost:50000/func"
DefaultRegistry = "registry.localtest.me/func"

// DefaultClusterRegistry to use for in-cluster (remote) builds.
// This is the cluster-internal registry URL accessible from within
// the cluster for Tekton builds. Can be customized with
// FUNC_E2E_CLUSTER_REGISTRY.
DefaultClusterRegistry = "registry.default.svc.cluster.local:5000/func"
DefaultClusterRegistry = "registry.localtest.me/func"

// DefaultVerbose sets the default for the --verbose flag of all commands.
DefaultVerbose = false
Expand Down Expand Up @@ -494,6 +494,12 @@ func setupEnv(t *testing.T) {
// global config, or already defaulted by the user via environment variable.
os.Setenv("FUNC_REGISTRY", Registry)

// When using the default registry (registry.localtest.me), mark it as
// insecure since it serves plain HTTP.
if strings.Contains(Registry, "registry.localtest.me") {
os.Setenv("FUNC_REGISTRY_INSECURE", "true")
}

// If the docker host is set, it should affect any tests which perform
// container operations except for podman-specific tests. These use
// the FUNC_E2E_PODMAN_HOST value during test execution directly.
Expand All @@ -507,8 +513,7 @@ func setupEnv(t *testing.T) {
}

// setupPodmanEnvs
// - configures VM to treat localhost:50000 as an insecure registry
// - proxy connections to the host if running in a VM (like on darwin)
// - configures VM to treat registry.localtest.me as an insecure registry
// - creates an XDG_CONFIG_HOME and XDG_DATA_HOME
func setupPodman(t *testing.T) error {
t.Helper()
Expand All @@ -523,7 +528,7 @@ func setupPodman(t *testing.T) error {
short-name-mode="permissive"

[[registry]]
location="localhost:50000"
location="registry.localtest.me"
insecure=true
`
cfgPath := filepath.Join(t.TempDir(), "registries.conf")
Expand Down Expand Up @@ -559,24 +564,6 @@ insecure=true
return fmt.Errorf("Podman machine is not running. Please start it with: podman machine start podman-machine-default")
}

// Kill any existing process on port 50000 in the Podman VM
killCmd := exec.Command("podman", "machine", "ssh", "--",
"sudo lsof -ti :50000 | sudo xargs kill -9 2>/dev/null || true")
if output, err = killCmd.CombinedOutput(); err != nil {
t.Logf("output: %s", output)
return fmt.Errorf("failed killing existing registry proxy: %v", err)
}

// Set up socat proxy to forward localhost:50000 to host.containers.internal:50000
// This allows containers in Podman to access the host's registry
proxyCmd := exec.Command("podman", "machine", "ssh", "--",
"sudo sh -c 'socat TCP-LISTEN:50000,fork,reuseaddr TCP:host.containers.internal:50000 </dev/null >/dev/null 2>&1 & echo Registry proxy started'")
if output, err = proxyCmd.CombinedOutput(); err != nil {
t.Logf("output: %s", output)
return fmt.Errorf("failed to set up registry proxy: %v, output: %s", err, output)
}
t.Logf("Podman registry proxy enabled: %s", strings.TrimSpace(string(output)))

return nil
}

Expand Down
2 changes: 1 addition & 1 deletion e2e/e2e_userdeps_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func TestCore_PythonUserDepsRemote(t *testing.T) {

// Deploy remotely via Tekton
if err := newCmd(t, "deploy", "--builder", "pack", "--remote",
fmt.Sprintf("--registry=%s", ClusterRegistry)).Run(); err != nil {
fmt.Sprintf("--registry=%s", Registry)).Run(); err != nil {
t.Fatal(err)
}

Expand Down
Binary file modified hack/allow-insecure.tar
Binary file not shown.
Loading
Loading