Skip to content

Commit

Permalink
fix: parse management commands with proper arguments
Browse files Browse the repository at this point in the history
Signed-off-by: Shubharanshu Mahapatra <[email protected]>
  • Loading branch information
Shubhranshu153 committed Mar 28, 2024
1 parent 9223219 commit de7e63c
Show file tree
Hide file tree
Showing 3 changed files with 176 additions and 12 deletions.
26 changes: 22 additions & 4 deletions cmd/finch/nerdctl.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ func (nc *nerdctlCommand) run(cmdName string, args []string) error {
skip, hasCmdHander, hasArgHandler bool
cmdHandler commandHandler
aMap map[string]argHandler
envArgPos int
isDebug int
)

alias, hasAlias := aliasMap[cmdName]
Expand Down Expand Up @@ -139,6 +141,10 @@ func (nc *nerdctlCommand) run(cmdName string, args []string) error {
}
}

// envArgPos is used to preserve the position of first environment parameter
envArgPos = -1
// if a debug flag is passed before env arg pos we reduce the env arg pos by 1 to account for skipping debug flag
isDebug = 0
for i, arg := range args {
// Check if command requires arg handling
if hasArgHandler {
Expand All @@ -164,14 +170,24 @@ func (nc *nerdctlCommand) run(cmdName string, args []string) error {
switch {
case arg == "--debug":
// explicitly setting log level to avoid `--debug` flag being interpreted as nerdctl command
if envArgPos == -1 {
isDebug = 1
}
nc.logger.SetLevel(flog.Debug)
case argIsEnv(arg):
if envArgPos == -1 {
envArgPos = i - isDebug
}
shouldSkip, addEnv := handleEnv(nc.systemDeps, arg, args[i+1])
skip = shouldSkip
if addEnv != "" {
envs = append(envs, addEnv)
}
case strings.HasPrefix(arg, "--env-file"):
if envArgPos == -1 {
envArgPos = i - isDebug
}

shouldSkip, addEnvs, err := handleEnvFile(nc.fs, nc.systemDeps, arg, args[i+1])
if err != nil {
return err
Expand Down Expand Up @@ -249,14 +265,16 @@ func (nc *nerdctlCommand) run(cmdName string, args []string) error {

limaArgs = append(limaArgs, append([]string{nerdctlCmdName}, strings.Fields(cmdName)...)...)

var finalArgs []string
var envArgs []string
for key, val := range envVars {
finalArgs = append(finalArgs, "-e", fmt.Sprintf("%s=%s", key, val))
envArgs = append(envArgs, "-e", fmt.Sprintf("%s=%s", key, val))
}
if envArgPos > -1 {
nerdctlArgs = append(nerdctlArgs[:envArgPos], append(envArgs, nerdctlArgs[envArgPos:]...)...)
}
finalArgs = append(finalArgs, nerdctlArgs...)
// Add -E to sudo command in order to preserve existing environment variables, more info:
// https://stackoverflow.com/questions/8633461/how-to-keep-environment-variables-when-using-sudo/8633575#8633575
limaArgs = append(limaArgs, finalArgs...)
limaArgs = append(limaArgs, nerdctlArgs...)

if nc.shouldReplaceForHelp(cmdName, args) {
return nc.lcc.RunWithReplacingStdout([]command.Replacement{{Source: "nerdctl", Target: "finch"}}, limaArgs...)
Expand Down
76 changes: 72 additions & 4 deletions cmd/finch/nerdctl_darwin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ func TestNerdctlCommand_run(t *testing.T) {
ncsd.EXPECT().LookupEnv("COSIGN_PASSWORD").Return("", false)

lcc.EXPECT().Create("shell", limaInstanceName, "sudo", "-E", nerdctlCmdName, "run",
"-e", "ARG1=val1", "--rm", "alpine:latest", "env").Return(c)
"--rm", "-e", "ARG1=val1", "alpine:latest", "env").Return(c)
c.EXPECT().Run()
},
},
Expand Down Expand Up @@ -207,7 +207,39 @@ func TestNerdctlCommand_run(t *testing.T) {
ncsd.EXPECT().LookupEnv("ARG3").Return("val3", true)
ncsd.EXPECT().LookupEnv("COSIGN_PASSWORD").Return("", false)
lcc.EXPECT().Create("shell", limaInstanceName, "sudo", "-E", nerdctlCmdName, "run",
"-e", "ARG3=val3", "--rm", "alpine:latest", "env").Return(c)
"--rm", "-e", "ARG3=val3", "alpine:latest", "env").Return(c)
c.EXPECT().Run()
},
},
{
name: "with environment flags parsing and env value exists and with --debug flag",
cmdName: "run",
fc: &config.Finch{},
args: []string{"--debug", "--rm", "--env=ARG2", "-eARG3", "alpine:latest", "env"},
wantErr: nil,
mockSvc: func(
_ *testing.T,
lcc *mocks.LimaCmdCreator,
_ *mocks.CommandCreator,
ncsd *mocks.NerdctlCommandSystemDeps,
logger *mocks.Logger,
ctrl *gomock.Controller,
_ afero.Fs,
) {
getVMStatusC := mocks.NewCommand(ctrl)
lcc.EXPECT().CreateWithoutStdio("ls", "-f", "{{.Status}}", limaInstanceName).Return(getVMStatusC)
getVMStatusC.EXPECT().Output().Return([]byte("Running"), nil)
logger.EXPECT().SetLevel(flog.Debug)
logger.EXPECT().Debugf("Status of virtual machine: %s", "Running")
ncsd.EXPECT().LookupEnv("AWS_ACCESS_KEY_ID").Return("", false)
ncsd.EXPECT().LookupEnv("AWS_SECRET_ACCESS_KEY").Return("", false)
ncsd.EXPECT().LookupEnv("AWS_SESSION_TOKEN").Return("", false)
c := mocks.NewCommand(ctrl)
ncsd.EXPECT().LookupEnv("ARG2")
ncsd.EXPECT().LookupEnv("ARG3").Return("val3", true)
ncsd.EXPECT().LookupEnv("COSIGN_PASSWORD").Return("", false)
lcc.EXPECT().Create("shell", limaInstanceName, "sudo", "-E", nerdctlCmdName, "run",
"--rm", "-e", "ARG3=val3", "alpine:latest", "env").Return(c)
c.EXPECT().Run()
},
},
Expand Down Expand Up @@ -241,7 +273,43 @@ func TestNerdctlCommand_run(t *testing.T) {
ncsd.EXPECT().LookupEnv("NOTSETARG")
ncsd.EXPECT().LookupEnv("COSIGN_PASSWORD").Return("", false)
lcc.EXPECT().
Create("shell", limaInstanceName, "sudo", "-E", nerdctlCmdName, "run", "-e", "ARG1=val1", "--rm", "alpine:latest", "env").
Create("shell", limaInstanceName, "sudo", "-E", nerdctlCmdName, "run", "--rm", "-e", "ARG1=val1", "alpine:latest", "env").
Return(c)
c.EXPECT().Run()
},
},
{
name: "with --env-file flag replacement and with --debug flag",
cmdName: "run",
fc: &config.Finch{},
args: []string{"--debug", "--rm", "--env-file=/env-file", "alpine:latest", "env"},
wantErr: nil,
mockSvc: func(
t *testing.T,
lcc *mocks.LimaCmdCreator,
_ *mocks.CommandCreator,
ncsd *mocks.NerdctlCommandSystemDeps,
logger *mocks.Logger,
ctrl *gomock.Controller,
fs afero.Fs,
) {
envFileStr := "# a comment\nARG1=val1\n ARG2\n\n # a 2nd comment\nNOTSETARG\n "
require.NoError(t, afero.WriteFile(fs, envFilePath, []byte(envFileStr), 0o600))

getVMStatusC := mocks.NewCommand(ctrl)
lcc.EXPECT().CreateWithoutStdio("ls", "-f", "{{.Status}}", limaInstanceName).Return(getVMStatusC)
getVMStatusC.EXPECT().Output().Return([]byte("Running"), nil)
logger.EXPECT().SetLevel(flog.Debug)
logger.EXPECT().Debugf("Status of virtual machine: %s", "Running")
ncsd.EXPECT().LookupEnv("AWS_ACCESS_KEY_ID").Return("", false)
ncsd.EXPECT().LookupEnv("AWS_SECRET_ACCESS_KEY").Return("", false)
ncsd.EXPECT().LookupEnv("AWS_SESSION_TOKEN").Return("", false)
c := mocks.NewCommand(ctrl)
ncsd.EXPECT().LookupEnv("ARG2")
ncsd.EXPECT().LookupEnv("NOTSETARG")
ncsd.EXPECT().LookupEnv("COSIGN_PASSWORD").Return("", false)
lcc.EXPECT().
Create("shell", limaInstanceName, "sudo", "-E", nerdctlCmdName, "run", "--rm", "-e", "ARG1=val1", "alpine:latest", "env").
Return(c)
c.EXPECT().Run()
},
Expand Down Expand Up @@ -276,7 +344,7 @@ func TestNerdctlCommand_run(t *testing.T) {
ncsd.EXPECT().LookupEnv("NOTSETARG")
ncsd.EXPECT().LookupEnv("COSIGN_PASSWORD").Return("", false)
lcc.EXPECT().
Create("shell", limaInstanceName, "sudo", "-E", nerdctlCmdName, "run", "-e", "ARG2=val2", "--rm", "alpine:latest", "env").
Create("shell", limaInstanceName, "sudo", "-E", nerdctlCmdName, "run", "--rm", "-e", "ARG2=val2", "alpine:latest", "env").
Return(c)
c.EXPECT().Run()
},
Expand Down
86 changes: 82 additions & 4 deletions cmd/finch/nerdctl_windows_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ func TestNerdctlCommand_run(t *testing.T) {
ncsd.EXPECT().FilePathToSlash(augmentedPath).Return(wslPath)

lcc.EXPECT().Create("shell", "--workdir", wslPath, limaInstanceName, "sudo", "-E", nerdctlCmdName, "container", "run",
"-e", "ARG1=val1", "--rm", "alpine:latest", "env").Return(c)
"--rm", "-e", "ARG1=val1", "alpine:latest", "env").Return(c)
c.EXPECT().Run()
},
},
Expand Down Expand Up @@ -239,7 +239,45 @@ func TestNerdctlCommand_run(t *testing.T) {
ncsd.EXPECT().FilePathToSlash(augmentedPath).Return(wslPath)
// alias substitution run=>container run
lcc.EXPECT().Create("shell", "--workdir", wslPath, limaInstanceName, "sudo", "-E", nerdctlCmdName, "container", "run",
"-e", "ARG3=val3", "--rm", "alpine:latest", "env").Return(c)
"--rm", "-e", "ARG3=val3", "alpine:latest", "env").Return(c)
c.EXPECT().Run()
},
},
{
name: "with environment flags parsing and env value exists and with --debug flag",
cmdName: "run",
fc: &config.Finch{},
args: []string{"--debug", "--rm", "--env=ARG2", "-eARG3", "alpine:latest", "env"},
wantErr: nil,
mockSvc: func(
_ *testing.T,
_ *mocks.CommandCreator,
lcc *mocks.LimaCmdCreator,
_ *mocks.Command,
ncsd *mocks.NerdctlCommandSystemDeps,
logger *mocks.Logger,
ctrl *gomock.Controller,
_ afero.Fs,
) {
getVMStatusC := mocks.NewCommand(ctrl)
lcc.EXPECT().CreateWithoutStdio("ls", "-f", "{{.Status}}", limaInstanceName).Return(getVMStatusC)
getVMStatusC.EXPECT().Output().Return([]byte("Running"), nil)
logger.EXPECT().SetLevel(flog.Debug)
logger.EXPECT().Debugf("Status of virtual machine: %s", "Running")
ncsd.EXPECT().LookupEnv("AWS_ACCESS_KEY_ID").Return("", false)
ncsd.EXPECT().LookupEnv("AWS_SECRET_ACCESS_KEY").Return("", false)
ncsd.EXPECT().LookupEnv("AWS_SESSION_TOKEN").Return("", false)
c := mocks.NewCommand(ctrl)
ncsd.EXPECT().LookupEnv("ARG2")
ncsd.EXPECT().LookupEnv("ARG3").Return("val3", true)
ncsd.EXPECT().LookupEnv("COSIGN_PASSWORD").Return("", false)
ncsd.EXPECT().GetWd().Return("C:\\workdir", nil)
ncsd.EXPECT().FilePathAbs("C:\\workdir").Return("C:\\workdir", nil)
ncsd.EXPECT().FilePathJoin(string(filepath.Separator), "mnt", "c", "workdir").Return(augmentedPath)
ncsd.EXPECT().FilePathToSlash(augmentedPath).Return(wslPath)
// alias substitution run=>container run
lcc.EXPECT().Create("shell", "--workdir", wslPath, limaInstanceName, "sudo", "-E", nerdctlCmdName, "container", "run",
"--rm", "-e", "ARG3=val3", "alpine:latest", "env").Return(c)
c.EXPECT().Run()
},
},
Expand Down Expand Up @@ -278,7 +316,47 @@ func TestNerdctlCommand_run(t *testing.T) {
ncsd.EXPECT().FilePathJoin(string(filepath.Separator), "mnt", "c", "workdir").Return(augmentedPath)
ncsd.EXPECT().FilePathToSlash(augmentedPath).Return(wslPath)
lcc.EXPECT().Create("shell", "--workdir", wslPath, limaInstanceName,
"sudo", "-E", nerdctlCmdName, "container", "run", "-e", "ARG1=val1", "--rm", "alpine:latest", "env").Return(c)
"sudo", "-E", nerdctlCmdName, "container", "run", "--rm", "-e", "ARG1=val1", "alpine:latest", "env").Return(c)
c.EXPECT().Run()
},
},
{
name: "with --env-file flag replacement and with --debug flag",
cmdName: "run",
fc: &config.Finch{},
args: []string{"--debug", "--rm", "--env-file=" + envFilePath, "alpine:latest", "env"},
wantErr: nil,
mockSvc: func(
t *testing.T,
_ *mocks.CommandCreator,
lcc *mocks.LimaCmdCreator,
_ *mocks.Command,
ncsd *mocks.NerdctlCommandSystemDeps,
logger *mocks.Logger,
ctrl *gomock.Controller,
fs afero.Fs,
) {
envFileStr := "# a comment\nARG1=val1\n ARG2\n\n # a 2nd comment\nNOTSETARG\n "
require.NoError(t, afero.WriteFile(fs, envFilePath, []byte(envFileStr), 0o600))

getVMStatusC := mocks.NewCommand(ctrl)
lcc.EXPECT().CreateWithoutStdio("ls", "-f", "{{.Status}}", limaInstanceName).Return(getVMStatusC)
getVMStatusC.EXPECT().Output().Return([]byte("Running"), nil)
logger.EXPECT().SetLevel(flog.Debug)
logger.EXPECT().Debugf("Status of virtual machine: %s", "Running")
ncsd.EXPECT().LookupEnv("AWS_ACCESS_KEY_ID").Return("", false)
ncsd.EXPECT().LookupEnv("AWS_SECRET_ACCESS_KEY").Return("", false)
ncsd.EXPECT().LookupEnv("AWS_SESSION_TOKEN").Return("", false)
c := mocks.NewCommand(ctrl)
ncsd.EXPECT().LookupEnv("ARG2")
ncsd.EXPECT().LookupEnv("NOTSETARG")
ncsd.EXPECT().LookupEnv("COSIGN_PASSWORD").Return("", false)
ncsd.EXPECT().GetWd().Return("C:\\workdir", nil)
ncsd.EXPECT().FilePathAbs("C:\\workdir").Return("C:\\workdir", nil)
ncsd.EXPECT().FilePathJoin(string(filepath.Separator), "mnt", "c", "workdir").Return(augmentedPath)
ncsd.EXPECT().FilePathToSlash(augmentedPath).Return(wslPath)
lcc.EXPECT().Create("shell", "--workdir", wslPath, limaInstanceName,
"sudo", "-E", nerdctlCmdName, "container", "run", "--rm", "-e", "ARG1=val1", "alpine:latest", "env").Return(c)
c.EXPECT().Run()
},
},
Expand Down Expand Up @@ -317,7 +395,7 @@ func TestNerdctlCommand_run(t *testing.T) {
ncsd.EXPECT().FilePathJoin(string(filepath.Separator), "mnt", "c", "workdir").Return(augmentedPath)
ncsd.EXPECT().FilePathToSlash(augmentedPath).Return(wslPath)
lcc.EXPECT().Create("shell", "--workdir", wslPath, limaInstanceName,
"sudo", "-E", nerdctlCmdName, "container", "run", "-e", "ARG2=val2", "--rm", "alpine:latest", "env").Return(c)
"sudo", "-E", nerdctlCmdName, "container", "run", "--rm", "-e", "ARG2=val2", "alpine:latest", "env").Return(c)
c.EXPECT().Run()
},
},
Expand Down

0 comments on commit de7e63c

Please sign in to comment.