diff --git a/cmd/finch/main.go b/cmd/finch/main.go index 4f1a7f382..dfef4cbd9 100644 --- a/cmd/finch/main.go +++ b/cmd/finch/main.go @@ -15,7 +15,7 @@ import ( "github.com/runfinch/finch/pkg/command" "github.com/runfinch/finch/pkg/config" "github.com/runfinch/finch/pkg/dependency" - "github.com/runfinch/finch/pkg/dependency/credHelper" + "github.com/runfinch/finch/pkg/dependency/credhelper" "github.com/runfinch/finch/pkg/dependency/vmnet" "github.com/runfinch/finch/pkg/disk" "github.com/runfinch/finch/pkg/flog" @@ -121,7 +121,11 @@ func virtualMachineCommands( fs afero.Fs, fc *config.Finch, ) *cobra.Command { - optionalDepGroups := []*dependency.Group{vmnet.NewDependencyGroup(ecc, lcc, fs, fp, logger), credHelper.NewDependencyGroup(ecc, fs, fp, logger, fc, system.NewStdLib().Env("USER"), system.NewStdLib().Arch())} + optionalDepGroups := []*dependency.Group{ + vmnet.NewDependencyGroup(ecc, lcc, fs, fp, logger), + credhelper.NewDependencyGroup(ecc, fs, fp, logger, fc, system.NewStdLib().Env("USER"), + system.NewStdLib().Arch()), + } return newVirtualMachineCommand( lcc, logger, diff --git a/pkg/config/nerdctl_config_applier_test.go b/pkg/config/nerdctl_config_applier_test.go index 01090533e..c847a669b 100644 --- a/pkg/config/nerdctl_config_applier_test.go +++ b/pkg/config/nerdctl_config_applier_test.go @@ -48,7 +48,8 @@ func Test_updateEnvironment(t *testing.T) { fileBytes, err := afero.ReadFile(fs, "/home/mock_user.linux/.bashrc") require.NoError(t, err) assert.Equal(t, - []byte("\nexport DOCKER_CONFIG=\"/Users/mock_user/.finch\"\n[ -L /usr/local/bin/docker-credential-ecr-login ] || sudo ln -s "+ + []byte("\nexport DOCKER_CONFIG=\"/Users/mock_user/.finch\""+ + "\n[ -L /usr/local/bin/docker-credential-ecr-login ] || sudo ln -s "+ "/Users/mock_user/.finch/cred-helpers/docker-credential-ecr-login /usr/local/bin/"+ "\n[ -L $HOME/.aws ] || ln -s /Users/mock_user/.aws $HOME/.aws\n"+ "[ -L /root/.aws ] || sudo ln -fs /Users/mock_user/.aws /root/.aws"), fileBytes) @@ -75,7 +76,8 @@ func Test_updateEnvironment(t *testing.T) { postRunCheck: func(t *testing.T, fs afero.Fs) { fileBytes, err := afero.ReadFile(fs, "/home/mock_user.linux/.bashrc") require.NoError(t, err) - assert.Equal(t, []byte(`export DOCKER_CONFIG="/Users/mock_user/.finch"`+"\n"+"[ -L /usr/local/bin/docker-credential-ecr-login ] "+ + assert.Equal(t, []byte(`export DOCKER_CONFIG="/Users/mock_user/.finch"`+"\n"+ + "[ -L /usr/local/bin/docker-credential-ecr-login ] "+ "|| sudo ln -s /Users/mock_user/.finch/cred-helpers/docker-credential-ecr-login /usr/local/bin/"+ "\n"+"[ -L $HOME/.aws ] || ln -s /Users/mock_user/.aws $HOME/.aws"+"\n"+ "[ -L /root/.aws ] || sudo ln -fs /Users/mock_user/.aws /root/.aws"), fileBytes) diff --git a/pkg/dependency/credHelper/cred_helper.go b/pkg/dependency/credhelper/cred_helper.go similarity index 81% rename from pkg/dependency/credHelper/cred_helper.go rename to pkg/dependency/credhelper/cred_helper.go index 8413cdd27..67aa9e727 100644 --- a/pkg/dependency/credHelper/cred_helper.go +++ b/pkg/dependency/credhelper/cred_helper.go @@ -1,7 +1,8 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package credHelper +// Package credhelper for integrating credential helpers into Finch +package credhelper import ( "fmt" @@ -20,6 +21,7 @@ const ( errMsg = "Failed to finish installing credential helper" ) +// NewDependencyGroup returns a dependency group that contains all the dependencies required to make credhelper work. func NewDependencyGroup( execCmdCreator command.Creator, fs afero.Fs, @@ -35,7 +37,7 @@ func NewDependencyGroup( type helperConfig struct { binaryName string - credHelperUrl string + credHelperURL string hash string installFolder string finchPath string @@ -52,12 +54,12 @@ func newDeps( ) []dependency.Dependency { var deps []dependency.Dependency - credHelperUrl := fmt.Sprintf("https://amazon-ecr-credential-helper-releases.s3.us-east-2.amazonaws.com"+ + credHelperURL := fmt.Sprintf("https://amazon-ecr-credential-helper-releases.s3.us-east-2.amazonaws.com"+ "/0.7.0/linux-%s/docker-credential-ecr-login", arch) installFolder := fmt.Sprintf("/Users/%s/.finch/cred-helpers/", user) finchPath := fmt.Sprintf("/Users/%s/.finch/", user) hc := helperConfig{ - binaryName: "docker-credential-ecr-login", credHelperUrl: credHelperUrl, + binaryName: "docker-credential-ecr-login", credHelperURL: credHelperURL, hash: "sha256:ff14a4da40d28a2d2d81a12a7c9c36294ddf8e6439780c4ccbc96622991f3714", installFolder: installFolder, finchPath: finchPath, } diff --git a/pkg/dependency/credHelper/cred_helper_binary.go b/pkg/dependency/credhelper/cred_helper_binary.go similarity index 92% rename from pkg/dependency/credHelper/cred_helper_binary.go rename to pkg/dependency/credhelper/cred_helper_binary.go index 892e4aae8..508bba30f 100644 --- a/pkg/dependency/credHelper/cred_helper_binary.go +++ b/pkg/dependency/credhelper/cred_helper_binary.go @@ -1,7 +1,7 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package credHelper +package credhelper import ( "encoding/json" @@ -19,6 +19,7 @@ import ( "github.com/runfinch/finch/pkg/path" ) +// ConfigFile is taken from https://github.com/docker/cli/blob/master/cli/config/configfile/file.go type ConfigFile struct { AuthConfigs map[string]interface{} `json:"auths,omitempty"` HTTPHeaders map[string]string `json:"HttpHeaders,omitempty"` @@ -81,7 +82,6 @@ func updateConfigFile(bin *binaries) error { return err } if !fileExists { - file, err := bin.fs.Create(cfgPath) if err != nil { return err @@ -98,16 +98,17 @@ func updateConfigFile(bin *binaries) error { return err } bytes, err := afero.ReadAll(fileRead) + if err != nil { + return err + } var cfg ConfigFile err = json.Unmarshal(bytes, &cfg) if err != nil { return err } credsStore := cfg.CredentialsStore - defer fileRead.Close() + defer fileRead.Close() //nolint:errcheck // closing the file if strings.Compare(credsStore, binCfgName) != 0 { - - //populate credsStore field with correct name file, err := bin.fs.OpenFile(cfgPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0o755) if err != nil { return err @@ -121,7 +122,7 @@ func updateConfigFile(bin *binaries) error { if err != nil { return err } - defer file.Close() + defer file.Close() //nolint:errcheck // closing the file before exit } } @@ -129,7 +130,7 @@ func updateConfigFile(bin *binaries) error { } func (bin *binaries) credHelperConfigName() string { - return strings.Replace(bin.hcfg.binaryName, "docker-credential-", "", -1) + return strings.ReplaceAll(bin.hcfg.binaryName, "docker-credential-", "") } func (bin *binaries) fullInstallPath() string { @@ -163,7 +164,7 @@ func (bin *binaries) Installed() bool { bin.l.Error(err) return false } - defer file.Close() + defer file.Close() //nolint:errcheck // closing the file if strings.Compare(hash.String(), bin.hcfg.hash) != 0 { bin.l.Info("Hash of the installed credential helper binary does not match") err := bin.fs.Remove(bin.fullInstallPath()) @@ -191,7 +192,7 @@ func (bin *binaries) Install() error { } curlCmd := bin.cmdCreator.Create("curl", "--retry", "5", "--retry-max-time", "30", "--url", - bin.hcfg.credHelperUrl, "--output", bin.fullInstallPath()) + bin.hcfg.credHelperURL, "--output", bin.fullInstallPath()) _, err = curlCmd.Output() if err != nil { diff --git a/pkg/dependency/credHelper/cred_helper_binary_test.go b/pkg/dependency/credhelper/cred_helper_binary_test.go similarity index 91% rename from pkg/dependency/credHelper/cred_helper_binary_test.go rename to pkg/dependency/credhelper/cred_helper_binary_test.go index 30c9dadd4..dc13ddac7 100644 --- a/pkg/dependency/credHelper/cred_helper_binary_test.go +++ b/pkg/dependency/credhelper/cred_helper_binary_test.go @@ -3,14 +3,15 @@ // Ensures that the binaries required for networking are installed in a privileged location. // More information here: https://github.com/lima-vm/socket_vmnet -package credHelper +package credhelper import ( "fmt" - "github.com/runfinch/finch/pkg/config" "io/fs" "testing" + "github.com/runfinch/finch/pkg/config" + "github.com/runfinch/finch/pkg/mocks" "github.com/runfinch/finch/pkg/path" @@ -29,17 +30,21 @@ func Test_credHelperConfigName(t *testing.T) { t.Parallel() got := newCredHelperBinary("", nil, nil, nil, nil, "user", - helperConfig{"docker-credential-cred-helper", "", "", - "", ""}).credHelperConfigName() + helperConfig{ + "docker-credential-cred-helper", "", "", + "", "", + }).credHelperConfigName() assert.Equal(t, "cred-helper", got) - } + func Test_fullInstallPath(t *testing.T) { t.Parallel() got := newCredHelperBinary("", nil, nil, nil, nil, "user", - helperConfig{"docker-credential-cred-helper", "", "", "/folder/", - ""}).fullInstallPath() + helperConfig{ + "docker-credential-cred-helper", "", "", "/folder/", + "", + }).fullInstallPath() assert.Equal(t, "/folder/docker-credential-cred-helper", got) } @@ -72,7 +77,6 @@ func Test_updateConfigFile(t *testing.T) { name: "file doesn't exist", mockSvc: func(t *testing.T, mFs afero.Fs, l *mocks.Logger) { require.NoError(t, mFs.MkdirAll("/mock_prefix/.finch/", fs.ModeDir)) - }, postRunCheck: func(t *testing.T, fs afero.Fs) { fileBytes, err := afero.ReadFile(fs, "mock_prefix/.finch/config.json") @@ -97,7 +101,6 @@ func Test_updateConfigFile(t *testing.T) { fileData, 0o666) require.NoError(t, err) - }, postRunCheck: func(t *testing.T, fs afero.Fs) { fileBytes, err := afero.ReadFile(fs, "mock_prefix/.finch/config.json") @@ -121,10 +124,12 @@ func Test_updateConfigFile(t *testing.T) { mFs := afero.NewMemMapFs() l := mocks.NewLogger(ctrl) tc.mockSvc(t, mFs, l) - hc := helperConfig{"docker-credential-binary", "", + hc := helperConfig{ + "docker-credential-binary", "", "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "mock_prefix/cred-helpers/", - "mock_prefix/.finch/"} - //hash of an empty file + "mock_prefix/.finch/", + } + // hash of an empty file got := updateConfigFile(newCredHelperBinary(mockFinchPath, mFs, nil, l, nil, "", hc)) assert.Equal(t, tc.want, got) @@ -165,7 +170,6 @@ func TestBinaries_Installed(t *testing.T) { name: "folder exists file doesn't exist", mockSvc: func(t *testing.T, mFs afero.Fs, l *mocks.Logger) { require.NoError(t, mFs.MkdirAll("/mock_prefix/cred-helpers/", fs.ModeDir)) - }, want: false, }, @@ -195,10 +199,12 @@ func TestBinaries_Installed(t *testing.T) { mFs := afero.NewMemMapFs() l := mocks.NewLogger(ctrl) tc.mockSvc(t, mFs, l) - hc := helperConfig{"docker-credential-binary", "", + hc := helperConfig{ + "docker-credential-binary", "", "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "mock_prefix/cred-helpers/", - "mock_prefix/.finch/"} - //hash of an empty file + "mock_prefix/.finch/", + } + // hash of an empty file got := newCredHelperBinary(mockFinchPath, mFs, nil, l, nil, "", hc).Installed() assert.Equal(t, tc.want, got) @@ -228,7 +234,8 @@ func TestBinaries_Install(t *testing.T) { creator.EXPECT().Create("mkdir", "-p", "mock_prefix/cred-helpers/").Return(cmd) creator.EXPECT().Create("curl", "--retry", "5", "--retry-max-time", "30", "--url", "https://amazon-ecr-credential-helper-releases.s3.us-east-2.amazonaws.com"+ - "/0.7.0/linux-arm64/docker-credential-ecr-login", "--output", "mock_prefix/cred-helpers/docker-credential-ecr-login").Return(cmd) + "/0.7.0/linux-arm64/docker-credential-ecr-login", "--output", + "mock_prefix/cred-helpers/docker-credential-ecr-login").Return(cmd) }, want: nil, }, @@ -246,13 +253,15 @@ func TestBinaries_Install(t *testing.T) { creator := mocks.NewCommandCreator(ctrl) tc.mockSvc(l, cmd, creator, mFs) - credHelperUrl := "https://amazon-ecr-credential-helper-releases.s3.us-east-2.amazonaws.com" + + credHelperURL := "https://amazon-ecr-credential-helper-releases.s3.us-east-2.amazonaws.com" + "/0.7.0/linux-arm64/docker-credential-ecr-login" - hc := helperConfig{"docker-credential-ecr-login", credHelperUrl, + hc := helperConfig{ + "docker-credential-ecr-login", credHelperURL, "sha256:ff14a4da40d28a2d2d81a12a7c9c36294ddf8e6439780c4ccbc96622991f3714", "mock_prefix/cred-helpers/", - "mock_prefix/.finch/"} + "mock_prefix/.finch/", + } fc := "ecr-login" got := newCredHelperBinary(mockFinchPath, mFs, creator, l, &config.Finch{CredsHelper: &fc}, "", hc).Install() assert.Equal(t, tc.want, got) diff --git a/pkg/dependency/credHelper/cred_helper_test.go b/pkg/dependency/credhelper/cred_helper_test.go similarity index 97% rename from pkg/dependency/credHelper/cred_helper_test.go rename to pkg/dependency/credhelper/cred_helper_test.go index c5613fba9..7d106e63f 100644 --- a/pkg/dependency/credHelper/cred_helper_test.go +++ b/pkg/dependency/credhelper/cred_helper_test.go @@ -1,7 +1,7 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package credHelper +package credhelper import ( "testing"