mirror of https://github.com/knative/func.git
Run func without HOME defined/ unaccessible .config dir (#2236)
* fixed integration tests Signed-off-by: gauron99 <fridrich.david19@gmail.com> * def creds back Signed-off-by: gauron99 <fridrich.david19@gmail.com> * docker config.json credentials test when HOME not defined Signed-off-by: gauron99 <fridrich.david19@gmail.com> * pack test Signed-off-by: gauron99 <fridrich.david19@gmail.com> * simplify Signed-off-by: gauron99 <fridrich.david19@gmail.com> * og creds, small fixes Signed-off-by: gauron99 <fridrich.david19@gmail.com> * s2i test no home Signed-off-by: gauron99 <fridrich.david19@gmail.com> * remove unnecessary stuff Signed-off-by: gauron99 <fridrich.david19@gmail.com> * deploy test without home Signed-off-by: gauron99 <fridrich.david19@gmail.com> * confict fix after rebase Signed-off-by: gauron99 <fridrich.david19@gmail.com> * move test, dont delete Signed-off-by: gauron99 <fridrich.david19@gmail.com> * runtime change Signed-off-by: gauron99 <fridrich.david19@gmail.com> * node image signals fixed and smaller size for GH actions Signed-off-by: gauron99 <fridrich.david19@gmail.com> * return err Signed-off-by: gauron99 <fridrich.david19@gmail.com> * cred test Signed-off-by: gauron99 <fridrich.david19@gmail.com> * clean up comments Signed-off-by: gauron99 <fridrich.david19@gmail.com> --------- Signed-off-by: gauron99 <fridrich.david19@gmail.com>
This commit is contained in:
parent
a2bc6f6ffd
commit
aa909bdc44
|
@ -159,9 +159,6 @@ func runBuild(cmd *cobra.Command, _ []string, newClient ClientFactory) (err erro
|
|||
cfg buildConfig
|
||||
f fn.Function
|
||||
)
|
||||
if err = config.CreatePaths(); err != nil { // for possible auth.json usage
|
||||
return
|
||||
}
|
||||
if cfg, err = newBuildConfig().Prompt(); err != nil { // gather values into a single instruction set
|
||||
return
|
||||
}
|
||||
|
|
|
@ -233,9 +233,6 @@ func runDeploy(cmd *cobra.Command, newClient ClientFactory) (err error) {
|
|||
cfg deployConfig
|
||||
f fn.Function
|
||||
)
|
||||
if err = config.CreatePaths(); err != nil { // for possible auth.json usage
|
||||
return
|
||||
}
|
||||
if cfg, err = newDeployConfig(cmd).Prompt(); err != nil {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -1894,3 +1894,36 @@ func TestDeploy_NoErrorOnOldFunctionNotFound(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// TestDeploy_WithoutHome ensures that deploying a function without HOME &
|
||||
// XDG_CONFIG_HOME defined succeeds
|
||||
func TestDeploy_WithoutHome(t *testing.T) {
|
||||
var (
|
||||
root = FromTempDirectory(t)
|
||||
ns = "myns"
|
||||
)
|
||||
|
||||
t.Setenv("HOME", "")
|
||||
t.Setenv("XDG_CONFIG_HOME", "")
|
||||
|
||||
// Create a basic go Function
|
||||
f := fn.Function{
|
||||
Runtime: "go",
|
||||
Root: root,
|
||||
}
|
||||
_, err := fn.New().Init(f)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Deploy the function
|
||||
cmd := NewDeployCmd(NewTestClient(
|
||||
fn.WithDeployer(mock.NewDeployer()),
|
||||
fn.WithRegistry(TestRegistry)))
|
||||
|
||||
cmd.SetArgs([]string{fmt.Sprintf("--namespace=%s", ns)})
|
||||
err = cmd.Execute()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -211,7 +211,7 @@ func (b *Builder) Build(ctx context.Context, f fn.Function, platforms []fn.Platf
|
|||
if err = impl.Build(ctx, opts); err != nil {
|
||||
if ctx.Err() != nil {
|
||||
return // SIGINT
|
||||
} else if !b.verbose {
|
||||
} else if b.verbose {
|
||||
err = fmt.Errorf("failed to build the function: %w", err)
|
||||
fmt.Fprintln(color.Stderr(), "")
|
||||
_, _ = io.Copy(color.Stderr(), &b.outBuff)
|
||||
|
|
|
@ -165,24 +165,31 @@ func NewCredentialsProvider(configPath string, opts ...Opt) docker.CredentialsPr
|
|||
}
|
||||
}
|
||||
|
||||
// default credential loaders map -- load only those that should be there.
|
||||
var defaultCredentialLoaders = []CredentialsCallback{}
|
||||
|
||||
c.authFilePath = filepath.Join(configPath, "auth.json")
|
||||
sys := &containersTypes.SystemContext{
|
||||
AuthFilePath: c.authFilePath,
|
||||
}
|
||||
|
||||
home, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
if _, err := os.Stat(c.authFilePath); err == nil {
|
||||
defaultCredentialLoaders = append(defaultCredentialLoaders,
|
||||
func(registry string) (docker.Credentials, error) {
|
||||
return getCredentialsByCredentialHelper(c.authFilePath, registry)
|
||||
})
|
||||
}
|
||||
dockerConfigPath := filepath.Join(home, ".docker", "config.json")
|
||||
|
||||
var defaultCredentialLoaders = []CredentialsCallback{
|
||||
func(registry string) (docker.Credentials, error) {
|
||||
return getCredentialsByCredentialHelper(c.authFilePath, registry)
|
||||
},
|
||||
func(registry string) (docker.Credentials, error) {
|
||||
return getCredentialsByCredentialHelper(dockerConfigPath, registry)
|
||||
},
|
||||
// add only if home dir is defined -- for .docker/config.json creds
|
||||
home, err := os.UserHomeDir()
|
||||
if err == nil {
|
||||
dockerConfigPath := filepath.Join(home, ".docker", "config.json")
|
||||
defaultCredentialLoaders = append(defaultCredentialLoaders,
|
||||
func(registry string) (docker.Credentials, error) {
|
||||
return getCredentialsByCredentialHelper(dockerConfigPath, registry)
|
||||
})
|
||||
}
|
||||
defaultCredentialLoaders = append(defaultCredentialLoaders,
|
||||
func(registry string) (docker.Credentials, error) {
|
||||
creds, err := dockerConfig.GetCredentials(sys, registry)
|
||||
if err != nil {
|
||||
|
@ -195,7 +202,8 @@ func NewCredentialsProvider(configPath string, opts ...Opt) docker.CredentialsPr
|
|||
Username: creds.Username,
|
||||
Password: creds.Password,
|
||||
}, nil
|
||||
},
|
||||
})
|
||||
defaultCredentialLoaders = append(defaultCredentialLoaders,
|
||||
func(registry string) (docker.Credentials, error) {
|
||||
// Fallback onto default docker config locations
|
||||
emptySys := &containersTypes.SystemContext{}
|
||||
|
@ -207,11 +215,11 @@ func NewCredentialsProvider(configPath string, opts ...Opt) docker.CredentialsPr
|
|||
Username: creds.Username,
|
||||
Password: creds.Password,
|
||||
}, nil
|
||||
},
|
||||
})
|
||||
defaultCredentialLoaders = append(defaultCredentialLoaders,
|
||||
func(registry string) (docker.Credentials, error) { // empty credentials provider for unsecured registries
|
||||
return docker.Credentials{}, nil
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
c.credentialLoaders = append(c.credentialLoaders, defaultCredentialLoaders...)
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ import (
|
|||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
|
@ -284,7 +285,6 @@ func startServer(t *testing.T, uname, pwd string) (addr, addrTLS string) {
|
|||
panic(err)
|
||||
}
|
||||
}()
|
||||
|
||||
// make the testing CA trusted by default HTTP transport/client
|
||||
oldDefaultTransport := http.DefaultTransport
|
||||
newDefaultTransport := http.DefaultTransport.(*http.Transport).Clone()
|
||||
|
@ -549,6 +549,77 @@ func TestCredentialsProviderSavingFromUserInput(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// TestCredentialsWithoutHome tests different scenarios when HOME is not set
|
||||
func TestCredentialsWithoutHome(t *testing.T) {
|
||||
type args struct {
|
||||
promptUser creds.CredentialsCallback
|
||||
verifyCredentials creds.VerifyCredentialsCallback
|
||||
registry string
|
||||
setUpEnv setUpEnv
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
testHomePathEmpty bool
|
||||
args args
|
||||
want Credentials
|
||||
}{
|
||||
{
|
||||
name: "empty home with correct user prompt",
|
||||
testHomePathEmpty: true,
|
||||
args: args{
|
||||
promptUser: correctPwdCallback, // user inputs correct credentials
|
||||
verifyCredentials: correctVerifyCbk,
|
||||
registry: "docker.io",
|
||||
setUpEnv: setEmptyHome,
|
||||
},
|
||||
want: Credentials{Username: dockerIoUser, Password: dockerIoUserPwd},
|
||||
},
|
||||
{
|
||||
name: "empty config with user prompt",
|
||||
args: args{
|
||||
promptUser: correctPwdCallback,
|
||||
verifyCredentials: correctVerifyCbk,
|
||||
registry: "docker.io",
|
||||
},
|
||||
want: Credentials{Username: dockerIoUser, Password: dockerIoUserPwd},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
resetHomeDir(t)
|
||||
if tt.args.setUpEnv != nil {
|
||||
tt.args.setUpEnv(t)
|
||||
}
|
||||
|
||||
// prepare config path for credentials provider
|
||||
var configPath string
|
||||
if tt.testHomePathEmpty {
|
||||
configPath = ""
|
||||
} else {
|
||||
configPath = testConfigPath(t)
|
||||
}
|
||||
|
||||
credentialsProvider := creds.NewCredentialsProvider(
|
||||
configPath,
|
||||
creds.WithPromptForCredentials(tt.args.promptUser),
|
||||
creds.WithVerifyCredentials(tt.args.verifyCredentials),
|
||||
)
|
||||
|
||||
got, err := credentialsProvider(context.Background(), tt.args.registry+"/someorg/someimage:sometag")
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
return
|
||||
}
|
||||
if !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("got: %v, want: %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// ********************** helper functions below **************************** \\
|
||||
|
||||
func resetHomeDir(t *testing.T) {
|
||||
t.TempDir()
|
||||
if err := os.RemoveAll(homeTempDir); err != nil {
|
||||
|
@ -903,3 +974,10 @@ func (i *inMemoryHelper) Delete(serverURL string) error {
|
|||
|
||||
return credentials.NewErrCredentialsNotFound()
|
||||
}
|
||||
|
||||
// set home variables to empty values
|
||||
func setEmptyHome(t *testing.T) {
|
||||
t.Helper()
|
||||
t.Setenv("HOME", "")
|
||||
t.Setenv("XDG_CONFIG_HOME", "")
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import (
|
|||
"github.com/docker/docker/client"
|
||||
|
||||
"knative.dev/func/pkg/builders/buildpacks"
|
||||
"knative.dev/func/pkg/builders/s2i"
|
||||
"knative.dev/func/pkg/docker"
|
||||
fn "knative.dev/func/pkg/functions"
|
||||
"knative.dev/func/pkg/knative"
|
||||
|
@ -545,6 +546,31 @@ func Handle(ctx context.Context, w http.ResponseWriter, req *http.Request) {
|
|||
}
|
||||
}
|
||||
|
||||
// TestDeployWithoutHome ensures that running client.New works without
|
||||
// home
|
||||
func TestDeployWithoutHome(t *testing.T) {
|
||||
root, cleanup := Mktemp(t)
|
||||
defer cleanup()
|
||||
|
||||
t.Setenv("HOME", "")
|
||||
t.Setenv("XDG_CONFIG_HOME", "")
|
||||
verbose := false
|
||||
name := "test-deploy-no-home"
|
||||
|
||||
f := fn.Function{Runtime: "node", Name: name, Root: root, Namespace: DefaultNamespace}
|
||||
|
||||
// client with s2i builder because pack needs HOME
|
||||
client := newClientWithS2i(verbose)
|
||||
|
||||
// expect to succeed
|
||||
_, _, err := client.New(context.Background(), f)
|
||||
if err != nil {
|
||||
t.Fatalf("expected no errors but got %v", err)
|
||||
}
|
||||
|
||||
defer del(t, client, name, DefaultNamespace)
|
||||
}
|
||||
|
||||
// ***********
|
||||
// Helpers
|
||||
// ***********
|
||||
|
@ -571,6 +597,27 @@ func newClient(verbose bool) *fn.Client {
|
|||
)
|
||||
}
|
||||
|
||||
// copy of newClient just builder is s2i instead of buildpacks
|
||||
func newClientWithS2i(verbose bool) *fn.Client {
|
||||
builder := s2i.NewBuilder(s2i.WithVerbose(verbose))
|
||||
pusher := docker.NewPusher(docker.WithVerbose(verbose))
|
||||
deployer := knative.NewDeployer(knative.WithDeployerVerbose(verbose))
|
||||
describer := knative.NewDescriber(verbose)
|
||||
remover := knative.NewRemover(verbose)
|
||||
lister := knative.NewLister(verbose)
|
||||
|
||||
return fn.New(
|
||||
fn.WithRegistry(DefaultRegistry),
|
||||
fn.WithVerbose(verbose),
|
||||
fn.WithBuilder(builder),
|
||||
fn.WithPusher(pusher),
|
||||
fn.WithDeployer(deployer),
|
||||
fn.WithDescriber(describer),
|
||||
fn.WithRemover(remover),
|
||||
fn.WithLister(lister),
|
||||
)
|
||||
}
|
||||
|
||||
// Del cleans up after a test by removing a function by name.
|
||||
// (test fails if the named function does not exist)
|
||||
//
|
||||
|
|
Loading…
Reference in New Issue