Refactor Nomad Command Generation.

- Abstracting from the exec form while generating.
- Removal of single quotes (usage of only double-quotes).
- Bash-nesting using escaping of special characters.
This commit is contained in:
Maximilian Paß
2023-03-06 00:20:09 +00:00
committed by Sebastian Serth
parent f309d0f70e
commit 7dadc5dfe9
13 changed files with 1148 additions and 150 deletions

View File

@@ -98,10 +98,11 @@ func (w *AWSFunctionWorkload) ExecuteInteractively(
hideEnvironmentVariables(request, "AWS")
request.PrivilegedExecution = true // AWS does not support multiple users at this moment.
command, ctx, cancel := prepareExecution(request, w.ctx)
commands := []string{"/bin/bash", "-c", command}
exitInternal := make(chan ExitInfo)
exit := make(chan ExitInfo, 1)
go w.executeCommand(ctx, command, stdout, stderr, exitInternal)
go w.executeCommand(ctx, commands, stdout, stderr, exitInternal)
go w.handleRunnerTimeout(ctx, exitInternal, exit, id)
return exit, cancel, nil

View File

@@ -96,9 +96,9 @@ func TestAWSFunctionWorkload_ExecuteInteractively(t *testing.T) {
<-time.After(tests.ShortTimeout)
cancel()
expectedRequestData := "{\"action\":\"" + environment.Image() +
"\",\"cmd\":[\"env\",\"CODEOCEAN=true\",\"bash\",\"-c\",\"unset \\\"${!AWS@}\\\" \\u0026\\u0026 " + command +
"\"],\"files\":{}}"
expectedRequestData := `{"action":"` + environment.Image() +
`","cmd":["/bin/bash","-c","env CODEOCEAN=true /bin/bash -c \"unset \\\"\\${!AWS@}\\\" \u0026\u0026 ` + command +
`\""],"files":{}}`
assert.Equal(t, expectedRequestData, awsMock.receivedData)
})
}
@@ -131,9 +131,9 @@ func TestAWSFunctionWorkload_UpdateFileSystem(t *testing.T) {
<-time.After(tests.ShortTimeout)
execCancel()
expectedRequestData := "{\"action\":\"" + environment.Image() +
"\",\"cmd\":[\"env\",\"CODEOCEAN=true\",\"bash\",\"-c\",\"unset \\\"${!AWS@}\\\" \\u0026\\u0026 " + command +
"\"]," + "\"files\":{\"" + string(myFile.Path) + "\":\"" + base64.StdEncoding.EncodeToString(myFile.Content) + "\"}}"
expectedRequestData := `{"action":"` + environment.Image() +
`","cmd":["/bin/bash","-c","env CODEOCEAN=true /bin/bash -c \"unset \\\"\\${!AWS@}\\\" \u0026\u0026 ` + command +
`\""],"files":{"` + string(myFile.Path) + `":"` + base64.StdEncoding.EncodeToString(myFile.Content) + `"}}`
assert.Equal(t, expectedRequestData, awsMock.receivedData)
}

View File

@@ -232,7 +232,7 @@ func (r *NomadJob) Destroy() error {
}
func prepareExecution(request *dto.ExecutionRequest, environmentCtx context.Context) (
command []string, ctx context.Context, cancel context.CancelFunc,
command string, ctx context.Context, cancel context.CancelFunc,
) {
command = request.FullCommand()
if request.TimeLimit == 0 {
@@ -243,7 +243,7 @@ func prepareExecution(request *dto.ExecutionRequest, environmentCtx context.Cont
return command, ctx, cancel
}
func (r *NomadJob) executeCommand(ctx context.Context, command []string, privilegedExecution bool,
func (r *NomadJob) executeCommand(ctx context.Context, command string, privilegedExecution bool,
stdin io.ReadWriter, stdout, stderr io.Writer, exit chan<- ExitInfo,
) {
exitCode, err := r.api.ExecuteCommand(r.id, ctx, command, true, privilegedExecution, stdin, stdout, stderr)

View File

@@ -247,7 +247,7 @@ type UpdateFileSystemTestSuite struct {
timer *InactivityTimerMock
apiMock *nomad.ExecutorAPIMock
mockedExecuteCommandCall *mock.Call
command []string
command string
stdin *bytes.Buffer
}
@@ -266,7 +266,7 @@ func (s *UpdateFileSystemTestSuite) SetupTest() {
mock.Anything, false, mock.AnythingOfType("bool"), mock.Anything, mock.Anything, mock.Anything).
Run(func(args mock.Arguments) {
var ok bool
s.command, ok = args.Get(2).([]string)
s.command, ok = args.Get(2).(string)
s.Require().True(ok)
s.stdin, ok = args.Get(5).(*bytes.Buffer)
s.Require().True(ok)
@@ -365,7 +365,7 @@ func (s *UpdateFileSystemTestSuite) TestFilesToRemoveGetEscaped() {
s.NoError(err)
s.apiMock.AssertCalled(s.T(), "ExecuteCommand", mock.Anything, mock.Anything, mock.Anything, false, true,
mock.Anything, mock.Anything, mock.Anything)
s.Contains(strings.Join(s.command, " "), "'/some/potentially/harmful'\\''filename'")
s.Contains(s.command, "'/some/potentially/harmful'\\\\''filename'")
}
func (s *UpdateFileSystemTestSuite) TestResetTimerGetsCalled() {