From 7dadc5dfe9e8ebce52d779663aa0703d0050549b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Pa=C3=9F?= <22845248+mpass99@users.noreply.github.com> Date: Mon, 6 Mar 2023 00:20:09 +0000 Subject: [PATCH] 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. --- internal/api/websocket_test.go | 16 +- internal/nomad/api_querier.go | 10 +- internal/nomad/api_querier_mock.go | 386 ++++++++++++++- internal/nomad/executor_api_mock.go | 671 +++++++++++++++++++++++++- internal/nomad/nomad.go | 92 ++-- internal/nomad/nomad_test.go | 50 +- internal/nomad/sentry_debug_writer.go | 20 +- internal/runner/aws_runner.go | 3 +- internal/runner/aws_runner_test.go | 12 +- internal/runner/nomad_runner.go | 4 +- internal/runner/nomad_runner_test.go | 6 +- pkg/dto/dto.go | 23 +- tests/e2e/runners_test.go | 5 +- 13 files changed, 1148 insertions(+), 150 deletions(-) diff --git a/internal/api/websocket_test.go b/internal/api/websocket_test.go index 406210a..8c20540 100644 --- a/internal/api/websocket_test.go +++ b/internal/api/websocket_test.go @@ -290,7 +290,7 @@ func TestWebSocketProxyStopsReadingTheWebSocketAfterClosingIt(t *testing.T) { r.StoreExecution(executionID, &executionRequestHead) mockAPIExecute(apiMock, &executionRequestHead, - func(_ string, ctx context.Context, _ []string, _ bool, _ io.Reader, _, _ io.Writer) (int, error) { + func(_ string, ctx context.Context, _ string, _ bool, _ io.Reader, _, _ io.Writer) (int, error) { return 0, nil }) connection, _, err := websocket.DefaultDialer.Dial(wsURL.String(), nil) @@ -376,7 +376,7 @@ var executionRequestLs = dto.ExecutionRequest{Command: "ls"} // 'ls existing-file non-existing-file' was executed. func mockAPIExecuteLs(api *nomad.ExecutorAPIMock) { mockAPIExecute(api, &executionRequestLs, - func(_ string, _ context.Context, _ []string, _ bool, _ io.Reader, stdout, stderr io.Writer) (int, error) { + func(_ string, _ context.Context, _ string, _ bool, _ io.Reader, stdout, stderr io.Writer) (int, error) { _, _ = stdout.Write([]byte("existing-file\n")) _, _ = stderr.Write([]byte("ls: cannot access 'non-existing-file': No such file or directory\n")) return 0, nil @@ -388,7 +388,7 @@ var executionRequestHead = dto.ExecutionRequest{Command: "head -n 1"} // mockAPIExecuteHead mocks the ExecuteCommand of an ExecutorApi to act as if 'head -n 1' was executed. func mockAPIExecuteHead(api *nomad.ExecutorAPIMock) { mockAPIExecute(api, &executionRequestHead, - func(_ string, _ context.Context, _ []string, _ bool, + func(_ string, _ context.Context, _ string, _ bool, stdin io.Reader, stdout io.Writer, stderr io.Writer, ) (int, error) { scanner := bufio.NewScanner(stdin) @@ -408,7 +408,7 @@ func mockAPIExecuteSleep(api *nomad.ExecutorAPIMock) <-chan bool { canceled := make(chan bool, 1) mockAPIExecute(api, &executionRequestSleep, - func(_ string, ctx context.Context, _ []string, _ bool, + func(_ string, ctx context.Context, _ string, _ bool, stdin io.Reader, stdout io.Writer, stderr io.Writer, ) (int, error) { var err error @@ -429,7 +429,7 @@ var executionRequestError = dto.ExecutionRequest{Command: "error"} // mockAPIExecuteError mocks the ExecuteCommand method of an ExecutorApi to return an error. func mockAPIExecuteError(api *nomad.ExecutorAPIMock) { mockAPIExecute(api, &executionRequestError, - func(_ string, _ context.Context, _ []string, _ bool, _ io.Reader, _, _ io.Writer) (int, error) { + func(_ string, _ context.Context, _ string, _ bool, _ io.Reader, _, _ io.Writer) (int, error) { return 0, tests.ErrDefault }) } @@ -439,7 +439,7 @@ var executionRequestExitNonZero = dto.ExecutionRequest{Command: "exit 42"} // mockAPIExecuteExitNonZero mocks the ExecuteCommand method of an ExecutorApi to exit with exit status 42. func mockAPIExecuteExitNonZero(api *nomad.ExecutorAPIMock) { mockAPIExecute(api, &executionRequestExitNonZero, - func(_ string, _ context.Context, _ []string, _ bool, _ io.Reader, _, _ io.Writer) (int, error) { + func(_ string, _ context.Context, _ string, _ bool, _ io.Reader, _, _ io.Writer) (int, error) { return 42, nil }) } @@ -447,7 +447,7 @@ func mockAPIExecuteExitNonZero(api *nomad.ExecutorAPIMock) { // mockAPIExecute mocks the ExecuteCommand method of an ExecutorApi to call the given method run when the command // corresponding to the given ExecutionRequest is called. func mockAPIExecute(api *nomad.ExecutorAPIMock, request *dto.ExecutionRequest, - run func(runnerId string, ctx context.Context, command []string, tty bool, + run func(runnerId string, ctx context.Context, command string, tty bool, stdin io.Reader, stdout, stderr io.Writer) (int, error)) { call := api.On("ExecuteCommand", mock.AnythingOfType("string"), @@ -461,7 +461,7 @@ func mockAPIExecute(api *nomad.ExecutorAPIMock, request *dto.ExecutionRequest, call.Run(func(args mock.Arguments) { exit, err := run(args.Get(0).(string), args.Get(1).(context.Context), - args.Get(2).([]string), + args.Get(2).(string), args.Get(3).(bool), args.Get(5).(io.Reader), args.Get(6).(io.Writer), diff --git a/internal/nomad/api_querier.go b/internal/nomad/api_querier.go index 6e3b07b..fdf9356 100644 --- a/internal/nomad/api_querier.go +++ b/internal/nomad/api_querier.go @@ -34,7 +34,7 @@ type apiQuerier interface { DeleteJob(jobID string) (err error) // Execute runs a command in the passed job. - Execute(jobID string, ctx context.Context, command []string, tty bool, + Execute(jobID string, ctx context.Context, command string, tty bool, stdin io.Reader, stdout, stderr io.Writer) (int, error) // listJobs loads all jobs with the specified prefix. @@ -87,11 +87,10 @@ func (nc *nomadAPIClient) DeleteJob(jobID string) (err error) { } func (nc *nomadAPIClient) Execute(runnerID string, - ctx context.Context, command []string, tty bool, + ctx context.Context, cmd string, tty bool, stdin io.Reader, stdout, stderr io.Writer, ) (int, error) { - log.WithField("command", strings.ReplaceAll(strings.Join(command, ", "), "\n", "")). - Trace("Requesting Nomad Exec") + log.WithField("command", strings.ReplaceAll(cmd, "\n", "")).Trace("Requesting Nomad Exec") var allocations []*nomadApi.AllocationListStub var err error logging.StartSpan("nomad.execute.list", "List Allocations for id", ctx, func(_ context.Context) { @@ -115,8 +114,9 @@ func (nc *nomadAPIClient) Execute(runnerID string, var exitCode int logging.StartSpan("nomad.execute.exec", "Execute Command in Allocation", ctx, func(ctx context.Context) { debugWriter := NewSentryDebugWriter(stdout, ctx) + commands := []string{"/bin/bash", "-c", cmd} exitCode, err = nc.client.Allocations(). - Exec(ctx, allocation, TaskName, tty, command, stdin, debugWriter, stderr, nil, nil) + Exec(ctx, allocation, TaskName, tty, commands, stdin, debugWriter, stderr, nil, nil) debugWriter.Close(exitCode) }) switch { diff --git a/internal/nomad/api_querier_mock.go b/internal/nomad/api_querier_mock.go index 11c45a5..075226a 100644 --- a/internal/nomad/api_querier_mock.go +++ b/internal/nomad/api_querier_mock.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.9.4. DO NOT EDIT. +// Code generated by mockery v2.21.0. DO NOT EDIT. package nomad @@ -18,6 +18,14 @@ type apiQuerierMock struct { mock.Mock } +type apiQuerierMock_Expecter struct { + mock *mock.Mock +} + +func (_m *apiQuerierMock) EXPECT() *apiQuerierMock_Expecter { + return &apiQuerierMock_Expecter{mock: &_m.Mock} +} + // DeleteJob provides a mock function with given fields: jobID func (_m *apiQuerierMock) DeleteJob(jobID string) error { ret := _m.Called(jobID) @@ -32,11 +40,43 @@ func (_m *apiQuerierMock) DeleteJob(jobID string) error { return r0 } +// apiQuerierMock_DeleteJob_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeleteJob' +type apiQuerierMock_DeleteJob_Call struct { + *mock.Call +} + +// DeleteJob is a helper method to define mock.On call +// - jobID string +func (_e *apiQuerierMock_Expecter) DeleteJob(jobID interface{}) *apiQuerierMock_DeleteJob_Call { + return &apiQuerierMock_DeleteJob_Call{Call: _e.mock.On("DeleteJob", jobID)} +} + +func (_c *apiQuerierMock_DeleteJob_Call) Run(run func(jobID string)) *apiQuerierMock_DeleteJob_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string)) + }) + return _c +} + +func (_c *apiQuerierMock_DeleteJob_Call) Return(err error) *apiQuerierMock_DeleteJob_Call { + _c.Call.Return(err) + return _c +} + +func (_c *apiQuerierMock_DeleteJob_Call) RunAndReturn(run func(string) error) *apiQuerierMock_DeleteJob_Call { + _c.Call.Return(run) + return _c +} + // EventStream provides a mock function with given fields: ctx func (_m *apiQuerierMock) EventStream(ctx context.Context) (<-chan *api.Events, error) { ret := _m.Called(ctx) var r0 <-chan *api.Events + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (<-chan *api.Events, error)); ok { + return rf(ctx) + } if rf, ok := ret.Get(0).(func(context.Context) <-chan *api.Events); ok { r0 = rf(ctx) } else { @@ -45,7 +85,6 @@ func (_m *apiQuerierMock) EventStream(ctx context.Context) (<-chan *api.Events, } } - var r1 error if rf, ok := ret.Get(1).(func(context.Context) error); ok { r1 = rf(ctx) } else { @@ -55,19 +94,50 @@ func (_m *apiQuerierMock) EventStream(ctx context.Context) (<-chan *api.Events, return r0, r1 } +// apiQuerierMock_EventStream_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'EventStream' +type apiQuerierMock_EventStream_Call struct { + *mock.Call +} + +// EventStream is a helper method to define mock.On call +// - ctx context.Context +func (_e *apiQuerierMock_Expecter) EventStream(ctx interface{}) *apiQuerierMock_EventStream_Call { + return &apiQuerierMock_EventStream_Call{Call: _e.mock.On("EventStream", ctx)} +} + +func (_c *apiQuerierMock_EventStream_Call) Run(run func(ctx context.Context)) *apiQuerierMock_EventStream_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *apiQuerierMock_EventStream_Call) Return(_a0 <-chan *api.Events, _a1 error) *apiQuerierMock_EventStream_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *apiQuerierMock_EventStream_Call) RunAndReturn(run func(context.Context) (<-chan *api.Events, error)) *apiQuerierMock_EventStream_Call { + _c.Call.Return(run) + return _c +} + // Execute provides a mock function with given fields: jobID, ctx, command, tty, stdin, stdout, stderr -func (_m *apiQuerierMock) Execute(jobID string, ctx context.Context, command []string, tty bool, stdin io.Reader, stdout io.Writer, stderr io.Writer) (int, error) { +func (_m *apiQuerierMock) Execute(jobID string, ctx context.Context, command string, tty bool, stdin io.Reader, stdout io.Writer, stderr io.Writer) (int, error) { ret := _m.Called(jobID, ctx, command, tty, stdin, stdout, stderr) var r0 int - if rf, ok := ret.Get(0).(func(string, context.Context, []string, bool, io.Reader, io.Writer, io.Writer) int); ok { + var r1 error + if rf, ok := ret.Get(0).(func(string, context.Context, string, bool, io.Reader, io.Writer, io.Writer) (int, error)); ok { + return rf(jobID, ctx, command, tty, stdin, stdout, stderr) + } + if rf, ok := ret.Get(0).(func(string, context.Context, string, bool, io.Reader, io.Writer, io.Writer) int); ok { r0 = rf(jobID, ctx, command, tty, stdin, stdout, stderr) } else { r0 = ret.Get(0).(int) } - var r1 error - if rf, ok := ret.Get(1).(func(string, context.Context, []string, bool, io.Reader, io.Writer, io.Writer) error); ok { + if rf, ok := ret.Get(1).(func(string, context.Context, string, bool, io.Reader, io.Writer, io.Writer) error); ok { r1 = rf(jobID, ctx, command, tty, stdin, stdout, stderr) } else { r1 = ret.Error(1) @@ -76,18 +146,55 @@ func (_m *apiQuerierMock) Execute(jobID string, ctx context.Context, command []s return r0, r1 } +// apiQuerierMock_Execute_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Execute' +type apiQuerierMock_Execute_Call struct { + *mock.Call +} + +// Execute is a helper method to define mock.On call +// - jobID string +// - ctx context.Context +// - command string +// - tty bool +// - stdin io.Reader +// - stdout io.Writer +// - stderr io.Writer +func (_e *apiQuerierMock_Expecter) Execute(jobID interface{}, ctx interface{}, command interface{}, tty interface{}, stdin interface{}, stdout interface{}, stderr interface{}) *apiQuerierMock_Execute_Call { + return &apiQuerierMock_Execute_Call{Call: _e.mock.On("Execute", jobID, ctx, command, tty, stdin, stdout, stderr)} +} + +func (_c *apiQuerierMock_Execute_Call) Run(run func(jobID string, ctx context.Context, command string, tty bool, stdin io.Reader, stdout io.Writer, stderr io.Writer)) *apiQuerierMock_Execute_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string), args[1].(context.Context), args[2].(string), args[3].(bool), args[4].(io.Reader), args[5].(io.Writer), args[6].(io.Writer)) + }) + return _c +} + +func (_c *apiQuerierMock_Execute_Call) Return(_a0 int, _a1 error) *apiQuerierMock_Execute_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *apiQuerierMock_Execute_Call) RunAndReturn(run func(string, context.Context, string, bool, io.Reader, io.Writer, io.Writer) (int, error)) *apiQuerierMock_Execute_Call { + _c.Call.Return(run) + return _c +} + // JobScale provides a mock function with given fields: jobID func (_m *apiQuerierMock) JobScale(jobID string) (uint, error) { ret := _m.Called(jobID) var r0 uint + var r1 error + if rf, ok := ret.Get(0).(func(string) (uint, error)); ok { + return rf(jobID) + } if rf, ok := ret.Get(0).(func(string) uint); ok { r0 = rf(jobID) } else { r0 = ret.Get(0).(uint) } - var r1 error if rf, ok := ret.Get(1).(func(string) error); ok { r1 = rf(jobID) } else { @@ -97,11 +204,43 @@ func (_m *apiQuerierMock) JobScale(jobID string) (uint, error) { return r0, r1 } +// apiQuerierMock_JobScale_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'JobScale' +type apiQuerierMock_JobScale_Call struct { + *mock.Call +} + +// JobScale is a helper method to define mock.On call +// - jobID string +func (_e *apiQuerierMock_Expecter) JobScale(jobID interface{}) *apiQuerierMock_JobScale_Call { + return &apiQuerierMock_JobScale_Call{Call: _e.mock.On("JobScale", jobID)} +} + +func (_c *apiQuerierMock_JobScale_Call) Run(run func(jobID string)) *apiQuerierMock_JobScale_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string)) + }) + return _c +} + +func (_c *apiQuerierMock_JobScale_Call) Return(jobScale uint, err error) *apiQuerierMock_JobScale_Call { + _c.Call.Return(jobScale, err) + return _c +} + +func (_c *apiQuerierMock_JobScale_Call) RunAndReturn(run func(string) (uint, error)) *apiQuerierMock_JobScale_Call { + _c.Call.Return(run) + return _c +} + // LoadJobList provides a mock function with given fields: func (_m *apiQuerierMock) LoadJobList() ([]*api.JobListStub, error) { ret := _m.Called() var r0 []*api.JobListStub + var r1 error + if rf, ok := ret.Get(0).(func() ([]*api.JobListStub, error)); ok { + return rf() + } if rf, ok := ret.Get(0).(func() []*api.JobListStub); ok { r0 = rf() } else { @@ -110,7 +249,6 @@ func (_m *apiQuerierMock) LoadJobList() ([]*api.JobListStub, error) { } } - var r1 error if rf, ok := ret.Get(1).(func() error); ok { r1 = rf() } else { @@ -120,18 +258,48 @@ func (_m *apiQuerierMock) LoadJobList() ([]*api.JobListStub, error) { return r0, r1 } +// apiQuerierMock_LoadJobList_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'LoadJobList' +type apiQuerierMock_LoadJobList_Call struct { + *mock.Call +} + +// LoadJobList is a helper method to define mock.On call +func (_e *apiQuerierMock_Expecter) LoadJobList() *apiQuerierMock_LoadJobList_Call { + return &apiQuerierMock_LoadJobList_Call{Call: _e.mock.On("LoadJobList")} +} + +func (_c *apiQuerierMock_LoadJobList_Call) Run(run func()) *apiQuerierMock_LoadJobList_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *apiQuerierMock_LoadJobList_Call) Return(list []*api.JobListStub, err error) *apiQuerierMock_LoadJobList_Call { + _c.Call.Return(list, err) + return _c +} + +func (_c *apiQuerierMock_LoadJobList_Call) RunAndReturn(run func() ([]*api.JobListStub, error)) *apiQuerierMock_LoadJobList_Call { + _c.Call.Return(run) + return _c +} + // RegisterNomadJob provides a mock function with given fields: job func (_m *apiQuerierMock) RegisterNomadJob(job *api.Job) (string, error) { ret := _m.Called(job) var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(*api.Job) (string, error)); ok { + return rf(job) + } if rf, ok := ret.Get(0).(func(*api.Job) string); ok { r0 = rf(job) } else { r0 = ret.Get(0).(string) } - var r1 error if rf, ok := ret.Get(1).(func(*api.Job) error); ok { r1 = rf(job) } else { @@ -141,6 +309,34 @@ func (_m *apiQuerierMock) RegisterNomadJob(job *api.Job) (string, error) { return r0, r1 } +// apiQuerierMock_RegisterNomadJob_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RegisterNomadJob' +type apiQuerierMock_RegisterNomadJob_Call struct { + *mock.Call +} + +// RegisterNomadJob is a helper method to define mock.On call +// - job *api.Job +func (_e *apiQuerierMock_Expecter) RegisterNomadJob(job interface{}) *apiQuerierMock_RegisterNomadJob_Call { + return &apiQuerierMock_RegisterNomadJob_Call{Call: _e.mock.On("RegisterNomadJob", job)} +} + +func (_c *apiQuerierMock_RegisterNomadJob_Call) Run(run func(job *api.Job)) *apiQuerierMock_RegisterNomadJob_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*api.Job)) + }) + return _c +} + +func (_c *apiQuerierMock_RegisterNomadJob_Call) Return(_a0 string, _a1 error) *apiQuerierMock_RegisterNomadJob_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *apiQuerierMock_RegisterNomadJob_Call) RunAndReturn(run func(*api.Job) (string, error)) *apiQuerierMock_RegisterNomadJob_Call { + _c.Call.Return(run) + return _c +} + // SetJobScale provides a mock function with given fields: jobID, count, reason func (_m *apiQuerierMock) SetJobScale(jobID string, count uint, reason string) error { ret := _m.Called(jobID, count, reason) @@ -155,11 +351,45 @@ func (_m *apiQuerierMock) SetJobScale(jobID string, count uint, reason string) e return r0 } +// apiQuerierMock_SetJobScale_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetJobScale' +type apiQuerierMock_SetJobScale_Call struct { + *mock.Call +} + +// SetJobScale is a helper method to define mock.On call +// - jobID string +// - count uint +// - reason string +func (_e *apiQuerierMock_Expecter) SetJobScale(jobID interface{}, count interface{}, reason interface{}) *apiQuerierMock_SetJobScale_Call { + return &apiQuerierMock_SetJobScale_Call{Call: _e.mock.On("SetJobScale", jobID, count, reason)} +} + +func (_c *apiQuerierMock_SetJobScale_Call) Run(run func(jobID string, count uint, reason string)) *apiQuerierMock_SetJobScale_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string), args[1].(uint), args[2].(string)) + }) + return _c +} + +func (_c *apiQuerierMock_SetJobScale_Call) Return(err error) *apiQuerierMock_SetJobScale_Call { + _c.Call.Return(err) + return _c +} + +func (_c *apiQuerierMock_SetJobScale_Call) RunAndReturn(run func(string, uint, string) error) *apiQuerierMock_SetJobScale_Call { + _c.Call.Return(run) + return _c +} + // allocation provides a mock function with given fields: jobID func (_m *apiQuerierMock) allocation(jobID string) (*api.Allocation, error) { ret := _m.Called(jobID) var r0 *api.Allocation + var r1 error + if rf, ok := ret.Get(0).(func(string) (*api.Allocation, error)); ok { + return rf(jobID) + } if rf, ok := ret.Get(0).(func(string) *api.Allocation); ok { r0 = rf(jobID) } else { @@ -168,7 +398,6 @@ func (_m *apiQuerierMock) allocation(jobID string) (*api.Allocation, error) { } } - var r1 error if rf, ok := ret.Get(1).(func(string) error); ok { r1 = rf(jobID) } else { @@ -178,6 +407,34 @@ func (_m *apiQuerierMock) allocation(jobID string) (*api.Allocation, error) { return r0, r1 } +// apiQuerierMock_allocation_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'allocation' +type apiQuerierMock_allocation_Call struct { + *mock.Call +} + +// allocation is a helper method to define mock.On call +// - jobID string +func (_e *apiQuerierMock_Expecter) allocation(jobID interface{}) *apiQuerierMock_allocation_Call { + return &apiQuerierMock_allocation_Call{Call: _e.mock.On("allocation", jobID)} +} + +func (_c *apiQuerierMock_allocation_Call) Run(run func(jobID string)) *apiQuerierMock_allocation_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string)) + }) + return _c +} + +func (_c *apiQuerierMock_allocation_Call) Return(_a0 *api.Allocation, _a1 error) *apiQuerierMock_allocation_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *apiQuerierMock_allocation_Call) RunAndReturn(run func(string) (*api.Allocation, error)) *apiQuerierMock_allocation_Call { + _c.Call.Return(run) + return _c +} + // init provides a mock function with given fields: nomadConfig func (_m *apiQuerierMock) init(nomadConfig *config.Nomad) error { ret := _m.Called(nomadConfig) @@ -192,11 +449,43 @@ func (_m *apiQuerierMock) init(nomadConfig *config.Nomad) error { return r0 } +// apiQuerierMock_init_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'init' +type apiQuerierMock_init_Call struct { + *mock.Call +} + +// init is a helper method to define mock.On call +// - nomadConfig *config.Nomad +func (_e *apiQuerierMock_Expecter) init(nomadConfig interface{}) *apiQuerierMock_init_Call { + return &apiQuerierMock_init_Call{Call: _e.mock.On("init", nomadConfig)} +} + +func (_c *apiQuerierMock_init_Call) Run(run func(nomadConfig *config.Nomad)) *apiQuerierMock_init_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*config.Nomad)) + }) + return _c +} + +func (_c *apiQuerierMock_init_Call) Return(err error) *apiQuerierMock_init_Call { + _c.Call.Return(err) + return _c +} + +func (_c *apiQuerierMock_init_Call) RunAndReturn(run func(*config.Nomad) error) *apiQuerierMock_init_Call { + _c.Call.Return(run) + return _c +} + // job provides a mock function with given fields: jobID func (_m *apiQuerierMock) job(jobID string) (*api.Job, error) { ret := _m.Called(jobID) var r0 *api.Job + var r1 error + if rf, ok := ret.Get(0).(func(string) (*api.Job, error)); ok { + return rf(jobID) + } if rf, ok := ret.Get(0).(func(string) *api.Job); ok { r0 = rf(jobID) } else { @@ -205,7 +494,6 @@ func (_m *apiQuerierMock) job(jobID string) (*api.Job, error) { } } - var r1 error if rf, ok := ret.Get(1).(func(string) error); ok { r1 = rf(jobID) } else { @@ -215,11 +503,43 @@ func (_m *apiQuerierMock) job(jobID string) (*api.Job, error) { return r0, r1 } +// apiQuerierMock_job_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'job' +type apiQuerierMock_job_Call struct { + *mock.Call +} + +// job is a helper method to define mock.On call +// - jobID string +func (_e *apiQuerierMock_Expecter) job(jobID interface{}) *apiQuerierMock_job_Call { + return &apiQuerierMock_job_Call{Call: _e.mock.On("job", jobID)} +} + +func (_c *apiQuerierMock_job_Call) Run(run func(jobID string)) *apiQuerierMock_job_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string)) + }) + return _c +} + +func (_c *apiQuerierMock_job_Call) Return(job *api.Job, err error) *apiQuerierMock_job_Call { + _c.Call.Return(job, err) + return _c +} + +func (_c *apiQuerierMock_job_Call) RunAndReturn(run func(string) (*api.Job, error)) *apiQuerierMock_job_Call { + _c.Call.Return(run) + return _c +} + // listJobs provides a mock function with given fields: prefix func (_m *apiQuerierMock) listJobs(prefix string) ([]*api.JobListStub, error) { ret := _m.Called(prefix) var r0 []*api.JobListStub + var r1 error + if rf, ok := ret.Get(0).(func(string) ([]*api.JobListStub, error)); ok { + return rf(prefix) + } if rf, ok := ret.Get(0).(func(string) []*api.JobListStub); ok { r0 = rf(prefix) } else { @@ -228,7 +548,6 @@ func (_m *apiQuerierMock) listJobs(prefix string) ([]*api.JobListStub, error) { } } - var r1 error if rf, ok := ret.Get(1).(func(string) error); ok { r1 = rf(prefix) } else { @@ -237,3 +556,46 @@ func (_m *apiQuerierMock) listJobs(prefix string) ([]*api.JobListStub, error) { return r0, r1 } + +// apiQuerierMock_listJobs_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'listJobs' +type apiQuerierMock_listJobs_Call struct { + *mock.Call +} + +// listJobs is a helper method to define mock.On call +// - prefix string +func (_e *apiQuerierMock_Expecter) listJobs(prefix interface{}) *apiQuerierMock_listJobs_Call { + return &apiQuerierMock_listJobs_Call{Call: _e.mock.On("listJobs", prefix)} +} + +func (_c *apiQuerierMock_listJobs_Call) Run(run func(prefix string)) *apiQuerierMock_listJobs_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string)) + }) + return _c +} + +func (_c *apiQuerierMock_listJobs_Call) Return(allocationListStub []*api.JobListStub, err error) *apiQuerierMock_listJobs_Call { + _c.Call.Return(allocationListStub, err) + return _c +} + +func (_c *apiQuerierMock_listJobs_Call) RunAndReturn(run func(string) ([]*api.JobListStub, error)) *apiQuerierMock_listJobs_Call { + _c.Call.Return(run) + return _c +} + +type mockConstructorTestingTnewApiQuerierMock interface { + mock.TestingT + Cleanup(func()) +} + +// newApiQuerierMock creates a new instance of apiQuerierMock. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func newApiQuerierMock(t mockConstructorTestingTnewApiQuerierMock) *apiQuerierMock { + mock := &apiQuerierMock{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/internal/nomad/executor_api_mock.go b/internal/nomad/executor_api_mock.go index a0559f4..cf78847 100644 --- a/internal/nomad/executor_api_mock.go +++ b/internal/nomad/executor_api_mock.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.14.0. DO NOT EDIT. +// Code generated by mockery v2.21.0. DO NOT EDIT. package nomad @@ -20,6 +20,14 @@ type ExecutorAPIMock struct { mock.Mock } +type ExecutorAPIMock_Expecter struct { + mock *mock.Mock +} + +func (_m *ExecutorAPIMock) EXPECT() *ExecutorAPIMock_Expecter { + return &ExecutorAPIMock_Expecter{mock: &_m.Mock} +} + // DeleteJob provides a mock function with given fields: jobID func (_m *ExecutorAPIMock) DeleteJob(jobID string) error { ret := _m.Called(jobID) @@ -34,11 +42,43 @@ func (_m *ExecutorAPIMock) DeleteJob(jobID string) error { return r0 } +// ExecutorAPIMock_DeleteJob_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeleteJob' +type ExecutorAPIMock_DeleteJob_Call struct { + *mock.Call +} + +// DeleteJob is a helper method to define mock.On call +// - jobID string +func (_e *ExecutorAPIMock_Expecter) DeleteJob(jobID interface{}) *ExecutorAPIMock_DeleteJob_Call { + return &ExecutorAPIMock_DeleteJob_Call{Call: _e.mock.On("DeleteJob", jobID)} +} + +func (_c *ExecutorAPIMock_DeleteJob_Call) Run(run func(jobID string)) *ExecutorAPIMock_DeleteJob_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string)) + }) + return _c +} + +func (_c *ExecutorAPIMock_DeleteJob_Call) Return(err error) *ExecutorAPIMock_DeleteJob_Call { + _c.Call.Return(err) + return _c +} + +func (_c *ExecutorAPIMock_DeleteJob_Call) RunAndReturn(run func(string) error) *ExecutorAPIMock_DeleteJob_Call { + _c.Call.Return(run) + return _c +} + // EventStream provides a mock function with given fields: ctx func (_m *ExecutorAPIMock) EventStream(ctx context.Context) (<-chan *api.Events, error) { ret := _m.Called(ctx) var r0 <-chan *api.Events + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (<-chan *api.Events, error)); ok { + return rf(ctx) + } if rf, ok := ret.Get(0).(func(context.Context) <-chan *api.Events); ok { r0 = rf(ctx) } else { @@ -47,7 +87,6 @@ func (_m *ExecutorAPIMock) EventStream(ctx context.Context) (<-chan *api.Events, } } - var r1 error if rf, ok := ret.Get(1).(func(context.Context) error); ok { r1 = rf(ctx) } else { @@ -57,19 +96,50 @@ func (_m *ExecutorAPIMock) EventStream(ctx context.Context) (<-chan *api.Events, return r0, r1 } +// ExecutorAPIMock_EventStream_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'EventStream' +type ExecutorAPIMock_EventStream_Call struct { + *mock.Call +} + +// EventStream is a helper method to define mock.On call +// - ctx context.Context +func (_e *ExecutorAPIMock_Expecter) EventStream(ctx interface{}) *ExecutorAPIMock_EventStream_Call { + return &ExecutorAPIMock_EventStream_Call{Call: _e.mock.On("EventStream", ctx)} +} + +func (_c *ExecutorAPIMock_EventStream_Call) Run(run func(ctx context.Context)) *ExecutorAPIMock_EventStream_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *ExecutorAPIMock_EventStream_Call) Return(_a0 <-chan *api.Events, _a1 error) *ExecutorAPIMock_EventStream_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ExecutorAPIMock_EventStream_Call) RunAndReturn(run func(context.Context) (<-chan *api.Events, error)) *ExecutorAPIMock_EventStream_Call { + _c.Call.Return(run) + return _c +} + // Execute provides a mock function with given fields: jobID, ctx, command, tty, stdin, stdout, stderr -func (_m *ExecutorAPIMock) Execute(jobID string, ctx context.Context, command []string, tty bool, stdin io.Reader, stdout io.Writer, stderr io.Writer) (int, error) { +func (_m *ExecutorAPIMock) Execute(jobID string, ctx context.Context, command string, tty bool, stdin io.Reader, stdout io.Writer, stderr io.Writer) (int, error) { ret := _m.Called(jobID, ctx, command, tty, stdin, stdout, stderr) var r0 int - if rf, ok := ret.Get(0).(func(string, context.Context, []string, bool, io.Reader, io.Writer, io.Writer) int); ok { + var r1 error + if rf, ok := ret.Get(0).(func(string, context.Context, string, bool, io.Reader, io.Writer, io.Writer) (int, error)); ok { + return rf(jobID, ctx, command, tty, stdin, stdout, stderr) + } + if rf, ok := ret.Get(0).(func(string, context.Context, string, bool, io.Reader, io.Writer, io.Writer) int); ok { r0 = rf(jobID, ctx, command, tty, stdin, stdout, stderr) } else { r0 = ret.Get(0).(int) } - var r1 error - if rf, ok := ret.Get(1).(func(string, context.Context, []string, bool, io.Reader, io.Writer, io.Writer) error); ok { + if rf, ok := ret.Get(1).(func(string, context.Context, string, bool, io.Reader, io.Writer, io.Writer) error); ok { r1 = rf(jobID, ctx, command, tty, stdin, stdout, stderr) } else { r1 = ret.Error(1) @@ -78,20 +148,57 @@ func (_m *ExecutorAPIMock) Execute(jobID string, ctx context.Context, command [] return r0, r1 } -// ExecuteCommand provides a mock function with given fields: allocationID, ctx, command, tty, privilegedExecution, stdin, stdout, stderr -func (_m *ExecutorAPIMock) ExecuteCommand(allocationID string, ctx context.Context, command []string, tty bool, privilegedExecution bool, stdin io.Reader, stdout io.Writer, stderr io.Writer) (int, error) { - ret := _m.Called(allocationID, ctx, command, tty, privilegedExecution, stdin, stdout, stderr) +// ExecutorAPIMock_Execute_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Execute' +type ExecutorAPIMock_Execute_Call struct { + *mock.Call +} + +// Execute is a helper method to define mock.On call +// - jobID string +// - ctx context.Context +// - command string +// - tty bool +// - stdin io.Reader +// - stdout io.Writer +// - stderr io.Writer +func (_e *ExecutorAPIMock_Expecter) Execute(jobID interface{}, ctx interface{}, command interface{}, tty interface{}, stdin interface{}, stdout interface{}, stderr interface{}) *ExecutorAPIMock_Execute_Call { + return &ExecutorAPIMock_Execute_Call{Call: _e.mock.On("Execute", jobID, ctx, command, tty, stdin, stdout, stderr)} +} + +func (_c *ExecutorAPIMock_Execute_Call) Run(run func(jobID string, ctx context.Context, command string, tty bool, stdin io.Reader, stdout io.Writer, stderr io.Writer)) *ExecutorAPIMock_Execute_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string), args[1].(context.Context), args[2].(string), args[3].(bool), args[4].(io.Reader), args[5].(io.Writer), args[6].(io.Writer)) + }) + return _c +} + +func (_c *ExecutorAPIMock_Execute_Call) Return(_a0 int, _a1 error) *ExecutorAPIMock_Execute_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ExecutorAPIMock_Execute_Call) RunAndReturn(run func(string, context.Context, string, bool, io.Reader, io.Writer, io.Writer) (int, error)) *ExecutorAPIMock_Execute_Call { + _c.Call.Return(run) + return _c +} + +// ExecuteCommand provides a mock function with given fields: jobID, ctx, command, tty, privilegedExecution, stdin, stdout, stderr +func (_m *ExecutorAPIMock) ExecuteCommand(jobID string, ctx context.Context, command string, tty bool, privilegedExecution bool, stdin io.Reader, stdout io.Writer, stderr io.Writer) (int, error) { + ret := _m.Called(jobID, ctx, command, tty, privilegedExecution, stdin, stdout, stderr) var r0 int - if rf, ok := ret.Get(0).(func(string, context.Context, []string, bool, bool, io.Reader, io.Writer, io.Writer) int); ok { - r0 = rf(allocationID, ctx, command, tty, privilegedExecution, stdin, stdout, stderr) + var r1 error + if rf, ok := ret.Get(0).(func(string, context.Context, string, bool, bool, io.Reader, io.Writer, io.Writer) (int, error)); ok { + return rf(jobID, ctx, command, tty, privilegedExecution, stdin, stdout, stderr) + } + if rf, ok := ret.Get(0).(func(string, context.Context, string, bool, bool, io.Reader, io.Writer, io.Writer) int); ok { + r0 = rf(jobID, ctx, command, tty, privilegedExecution, stdin, stdout, stderr) } else { r0 = ret.Get(0).(int) } - var r1 error - if rf, ok := ret.Get(1).(func(string, context.Context, []string, bool, bool, io.Reader, io.Writer, io.Writer) error); ok { - r1 = rf(allocationID, ctx, command, tty, privilegedExecution, stdin, stdout, stderr) + if rf, ok := ret.Get(1).(func(string, context.Context, string, bool, bool, io.Reader, io.Writer, io.Writer) error); ok { + r1 = rf(jobID, ctx, command, tty, privilegedExecution, stdin, stdout, stderr) } else { r1 = ret.Error(1) } @@ -99,18 +206,56 @@ func (_m *ExecutorAPIMock) ExecuteCommand(allocationID string, ctx context.Conte return r0, r1 } +// ExecutorAPIMock_ExecuteCommand_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ExecuteCommand' +type ExecutorAPIMock_ExecuteCommand_Call struct { + *mock.Call +} + +// ExecuteCommand is a helper method to define mock.On call +// - jobID string +// - ctx context.Context +// - command string +// - tty bool +// - privilegedExecution bool +// - stdin io.Reader +// - stdout io.Writer +// - stderr io.Writer +func (_e *ExecutorAPIMock_Expecter) ExecuteCommand(jobID interface{}, ctx interface{}, command interface{}, tty interface{}, privilegedExecution interface{}, stdin interface{}, stdout interface{}, stderr interface{}) *ExecutorAPIMock_ExecuteCommand_Call { + return &ExecutorAPIMock_ExecuteCommand_Call{Call: _e.mock.On("ExecuteCommand", jobID, ctx, command, tty, privilegedExecution, stdin, stdout, stderr)} +} + +func (_c *ExecutorAPIMock_ExecuteCommand_Call) Run(run func(jobID string, ctx context.Context, command string, tty bool, privilegedExecution bool, stdin io.Reader, stdout io.Writer, stderr io.Writer)) *ExecutorAPIMock_ExecuteCommand_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string), args[1].(context.Context), args[2].(string), args[3].(bool), args[4].(bool), args[5].(io.Reader), args[6].(io.Writer), args[7].(io.Writer)) + }) + return _c +} + +func (_c *ExecutorAPIMock_ExecuteCommand_Call) Return(_a0 int, _a1 error) *ExecutorAPIMock_ExecuteCommand_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ExecutorAPIMock_ExecuteCommand_Call) RunAndReturn(run func(string, context.Context, string, bool, bool, io.Reader, io.Writer, io.Writer) (int, error)) *ExecutorAPIMock_ExecuteCommand_Call { + _c.Call.Return(run) + return _c +} + // JobScale provides a mock function with given fields: jobID func (_m *ExecutorAPIMock) JobScale(jobID string) (uint, error) { ret := _m.Called(jobID) var r0 uint + var r1 error + if rf, ok := ret.Get(0).(func(string) (uint, error)); ok { + return rf(jobID) + } if rf, ok := ret.Get(0).(func(string) uint); ok { r0 = rf(jobID) } else { r0 = ret.Get(0).(uint) } - var r1 error if rf, ok := ret.Get(1).(func(string) error); ok { r1 = rf(jobID) } else { @@ -120,11 +265,43 @@ func (_m *ExecutorAPIMock) JobScale(jobID string) (uint, error) { return r0, r1 } +// ExecutorAPIMock_JobScale_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'JobScale' +type ExecutorAPIMock_JobScale_Call struct { + *mock.Call +} + +// JobScale is a helper method to define mock.On call +// - jobID string +func (_e *ExecutorAPIMock_Expecter) JobScale(jobID interface{}) *ExecutorAPIMock_JobScale_Call { + return &ExecutorAPIMock_JobScale_Call{Call: _e.mock.On("JobScale", jobID)} +} + +func (_c *ExecutorAPIMock_JobScale_Call) Run(run func(jobID string)) *ExecutorAPIMock_JobScale_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string)) + }) + return _c +} + +func (_c *ExecutorAPIMock_JobScale_Call) Return(jobScale uint, err error) *ExecutorAPIMock_JobScale_Call { + _c.Call.Return(jobScale, err) + return _c +} + +func (_c *ExecutorAPIMock_JobScale_Call) RunAndReturn(run func(string) (uint, error)) *ExecutorAPIMock_JobScale_Call { + _c.Call.Return(run) + return _c +} + // LoadEnvironmentJobs provides a mock function with given fields: func (_m *ExecutorAPIMock) LoadEnvironmentJobs() ([]*api.Job, error) { ret := _m.Called() var r0 []*api.Job + var r1 error + if rf, ok := ret.Get(0).(func() ([]*api.Job, error)); ok { + return rf() + } if rf, ok := ret.Get(0).(func() []*api.Job); ok { r0 = rf() } else { @@ -133,7 +310,6 @@ func (_m *ExecutorAPIMock) LoadEnvironmentJobs() ([]*api.Job, error) { } } - var r1 error if rf, ok := ret.Get(1).(func() error); ok { r1 = rf() } else { @@ -143,11 +319,42 @@ func (_m *ExecutorAPIMock) LoadEnvironmentJobs() ([]*api.Job, error) { return r0, r1 } +// ExecutorAPIMock_LoadEnvironmentJobs_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'LoadEnvironmentJobs' +type ExecutorAPIMock_LoadEnvironmentJobs_Call struct { + *mock.Call +} + +// LoadEnvironmentJobs is a helper method to define mock.On call +func (_e *ExecutorAPIMock_Expecter) LoadEnvironmentJobs() *ExecutorAPIMock_LoadEnvironmentJobs_Call { + return &ExecutorAPIMock_LoadEnvironmentJobs_Call{Call: _e.mock.On("LoadEnvironmentJobs")} +} + +func (_c *ExecutorAPIMock_LoadEnvironmentJobs_Call) Run(run func()) *ExecutorAPIMock_LoadEnvironmentJobs_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *ExecutorAPIMock_LoadEnvironmentJobs_Call) Return(_a0 []*api.Job, _a1 error) *ExecutorAPIMock_LoadEnvironmentJobs_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ExecutorAPIMock_LoadEnvironmentJobs_Call) RunAndReturn(run func() ([]*api.Job, error)) *ExecutorAPIMock_LoadEnvironmentJobs_Call { + _c.Call.Return(run) + return _c +} + // LoadJobList provides a mock function with given fields: func (_m *ExecutorAPIMock) LoadJobList() ([]*api.JobListStub, error) { ret := _m.Called() var r0 []*api.JobListStub + var r1 error + if rf, ok := ret.Get(0).(func() ([]*api.JobListStub, error)); ok { + return rf() + } if rf, ok := ret.Get(0).(func() []*api.JobListStub); ok { r0 = rf() } else { @@ -156,7 +363,6 @@ func (_m *ExecutorAPIMock) LoadJobList() ([]*api.JobListStub, error) { } } - var r1 error if rf, ok := ret.Get(1).(func() error); ok { r1 = rf() } else { @@ -166,11 +372,42 @@ func (_m *ExecutorAPIMock) LoadJobList() ([]*api.JobListStub, error) { return r0, r1 } +// ExecutorAPIMock_LoadJobList_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'LoadJobList' +type ExecutorAPIMock_LoadJobList_Call struct { + *mock.Call +} + +// LoadJobList is a helper method to define mock.On call +func (_e *ExecutorAPIMock_Expecter) LoadJobList() *ExecutorAPIMock_LoadJobList_Call { + return &ExecutorAPIMock_LoadJobList_Call{Call: _e.mock.On("LoadJobList")} +} + +func (_c *ExecutorAPIMock_LoadJobList_Call) Run(run func()) *ExecutorAPIMock_LoadJobList_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *ExecutorAPIMock_LoadJobList_Call) Return(list []*api.JobListStub, err error) *ExecutorAPIMock_LoadJobList_Call { + _c.Call.Return(list, err) + return _c +} + +func (_c *ExecutorAPIMock_LoadJobList_Call) RunAndReturn(run func() ([]*api.JobListStub, error)) *ExecutorAPIMock_LoadJobList_Call { + _c.Call.Return(run) + return _c +} + // LoadRunnerIDs provides a mock function with given fields: prefix func (_m *ExecutorAPIMock) LoadRunnerIDs(prefix string) ([]string, error) { ret := _m.Called(prefix) var r0 []string + var r1 error + if rf, ok := ret.Get(0).(func(string) ([]string, error)); ok { + return rf(prefix) + } if rf, ok := ret.Get(0).(func(string) []string); ok { r0 = rf(prefix) } else { @@ -179,7 +416,6 @@ func (_m *ExecutorAPIMock) LoadRunnerIDs(prefix string) ([]string, error) { } } - var r1 error if rf, ok := ret.Get(1).(func(string) error); ok { r1 = rf(prefix) } else { @@ -189,11 +425,43 @@ func (_m *ExecutorAPIMock) LoadRunnerIDs(prefix string) ([]string, error) { return r0, r1 } +// ExecutorAPIMock_LoadRunnerIDs_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'LoadRunnerIDs' +type ExecutorAPIMock_LoadRunnerIDs_Call struct { + *mock.Call +} + +// LoadRunnerIDs is a helper method to define mock.On call +// - prefix string +func (_e *ExecutorAPIMock_Expecter) LoadRunnerIDs(prefix interface{}) *ExecutorAPIMock_LoadRunnerIDs_Call { + return &ExecutorAPIMock_LoadRunnerIDs_Call{Call: _e.mock.On("LoadRunnerIDs", prefix)} +} + +func (_c *ExecutorAPIMock_LoadRunnerIDs_Call) Run(run func(prefix string)) *ExecutorAPIMock_LoadRunnerIDs_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string)) + }) + return _c +} + +func (_c *ExecutorAPIMock_LoadRunnerIDs_Call) Return(runnerIds []string, err error) *ExecutorAPIMock_LoadRunnerIDs_Call { + _c.Call.Return(runnerIds, err) + return _c +} + +func (_c *ExecutorAPIMock_LoadRunnerIDs_Call) RunAndReturn(run func(string) ([]string, error)) *ExecutorAPIMock_LoadRunnerIDs_Call { + _c.Call.Return(run) + return _c +} + // LoadRunnerJobs provides a mock function with given fields: environmentID func (_m *ExecutorAPIMock) LoadRunnerJobs(environmentID dto.EnvironmentID) ([]*api.Job, error) { ret := _m.Called(environmentID) var r0 []*api.Job + var r1 error + if rf, ok := ret.Get(0).(func(dto.EnvironmentID) ([]*api.Job, error)); ok { + return rf(environmentID) + } if rf, ok := ret.Get(0).(func(dto.EnvironmentID) []*api.Job); ok { r0 = rf(environmentID) } else { @@ -202,7 +470,6 @@ func (_m *ExecutorAPIMock) LoadRunnerJobs(environmentID dto.EnvironmentID) ([]*a } } - var r1 error if rf, ok := ret.Get(1).(func(dto.EnvironmentID) error); ok { r1 = rf(environmentID) } else { @@ -212,11 +479,43 @@ func (_m *ExecutorAPIMock) LoadRunnerJobs(environmentID dto.EnvironmentID) ([]*a return r0, r1 } +// ExecutorAPIMock_LoadRunnerJobs_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'LoadRunnerJobs' +type ExecutorAPIMock_LoadRunnerJobs_Call struct { + *mock.Call +} + +// LoadRunnerJobs is a helper method to define mock.On call +// - environmentID dto.EnvironmentID +func (_e *ExecutorAPIMock_Expecter) LoadRunnerJobs(environmentID interface{}) *ExecutorAPIMock_LoadRunnerJobs_Call { + return &ExecutorAPIMock_LoadRunnerJobs_Call{Call: _e.mock.On("LoadRunnerJobs", environmentID)} +} + +func (_c *ExecutorAPIMock_LoadRunnerJobs_Call) Run(run func(environmentID dto.EnvironmentID)) *ExecutorAPIMock_LoadRunnerJobs_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(dto.EnvironmentID)) + }) + return _c +} + +func (_c *ExecutorAPIMock_LoadRunnerJobs_Call) Return(_a0 []*api.Job, _a1 error) *ExecutorAPIMock_LoadRunnerJobs_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ExecutorAPIMock_LoadRunnerJobs_Call) RunAndReturn(run func(dto.EnvironmentID) ([]*api.Job, error)) *ExecutorAPIMock_LoadRunnerJobs_Call { + _c.Call.Return(run) + return _c +} + // LoadRunnerPortMappings provides a mock function with given fields: runnerID func (_m *ExecutorAPIMock) LoadRunnerPortMappings(runnerID string) ([]api.PortMapping, error) { ret := _m.Called(runnerID) var r0 []api.PortMapping + var r1 error + if rf, ok := ret.Get(0).(func(string) ([]api.PortMapping, error)); ok { + return rf(runnerID) + } if rf, ok := ret.Get(0).(func(string) []api.PortMapping); ok { r0 = rf(runnerID) } else { @@ -225,7 +524,6 @@ func (_m *ExecutorAPIMock) LoadRunnerPortMappings(runnerID string) ([]api.PortMa } } - var r1 error if rf, ok := ret.Get(1).(func(string) error); ok { r1 = rf(runnerID) } else { @@ -235,6 +533,34 @@ func (_m *ExecutorAPIMock) LoadRunnerPortMappings(runnerID string) ([]api.PortMa return r0, r1 } +// ExecutorAPIMock_LoadRunnerPortMappings_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'LoadRunnerPortMappings' +type ExecutorAPIMock_LoadRunnerPortMappings_Call struct { + *mock.Call +} + +// LoadRunnerPortMappings is a helper method to define mock.On call +// - runnerID string +func (_e *ExecutorAPIMock_Expecter) LoadRunnerPortMappings(runnerID interface{}) *ExecutorAPIMock_LoadRunnerPortMappings_Call { + return &ExecutorAPIMock_LoadRunnerPortMappings_Call{Call: _e.mock.On("LoadRunnerPortMappings", runnerID)} +} + +func (_c *ExecutorAPIMock_LoadRunnerPortMappings_Call) Run(run func(runnerID string)) *ExecutorAPIMock_LoadRunnerPortMappings_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string)) + }) + return _c +} + +func (_c *ExecutorAPIMock_LoadRunnerPortMappings_Call) Return(_a0 []api.PortMapping, _a1 error) *ExecutorAPIMock_LoadRunnerPortMappings_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ExecutorAPIMock_LoadRunnerPortMappings_Call) RunAndReturn(run func(string) ([]api.PortMapping, error)) *ExecutorAPIMock_LoadRunnerPortMappings_Call { + _c.Call.Return(run) + return _c +} + // MarkRunnerAsUsed provides a mock function with given fields: runnerID, duration func (_m *ExecutorAPIMock) MarkRunnerAsUsed(runnerID string, duration int) error { ret := _m.Called(runnerID, duration) @@ -249,6 +575,35 @@ func (_m *ExecutorAPIMock) MarkRunnerAsUsed(runnerID string, duration int) error return r0 } +// ExecutorAPIMock_MarkRunnerAsUsed_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'MarkRunnerAsUsed' +type ExecutorAPIMock_MarkRunnerAsUsed_Call struct { + *mock.Call +} + +// MarkRunnerAsUsed is a helper method to define mock.On call +// - runnerID string +// - duration int +func (_e *ExecutorAPIMock_Expecter) MarkRunnerAsUsed(runnerID interface{}, duration interface{}) *ExecutorAPIMock_MarkRunnerAsUsed_Call { + return &ExecutorAPIMock_MarkRunnerAsUsed_Call{Call: _e.mock.On("MarkRunnerAsUsed", runnerID, duration)} +} + +func (_c *ExecutorAPIMock_MarkRunnerAsUsed_Call) Run(run func(runnerID string, duration int)) *ExecutorAPIMock_MarkRunnerAsUsed_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string), args[1].(int)) + }) + return _c +} + +func (_c *ExecutorAPIMock_MarkRunnerAsUsed_Call) Return(_a0 error) *ExecutorAPIMock_MarkRunnerAsUsed_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *ExecutorAPIMock_MarkRunnerAsUsed_Call) RunAndReturn(run func(string, int) error) *ExecutorAPIMock_MarkRunnerAsUsed_Call { + _c.Call.Return(run) + return _c +} + // MonitorEvaluation provides a mock function with given fields: evaluationID, ctx func (_m *ExecutorAPIMock) MonitorEvaluation(evaluationID string, ctx context.Context) error { ret := _m.Called(evaluationID, ctx) @@ -263,18 +618,50 @@ func (_m *ExecutorAPIMock) MonitorEvaluation(evaluationID string, ctx context.Co return r0 } +// ExecutorAPIMock_MonitorEvaluation_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'MonitorEvaluation' +type ExecutorAPIMock_MonitorEvaluation_Call struct { + *mock.Call +} + +// MonitorEvaluation is a helper method to define mock.On call +// - evaluationID string +// - ctx context.Context +func (_e *ExecutorAPIMock_Expecter) MonitorEvaluation(evaluationID interface{}, ctx interface{}) *ExecutorAPIMock_MonitorEvaluation_Call { + return &ExecutorAPIMock_MonitorEvaluation_Call{Call: _e.mock.On("MonitorEvaluation", evaluationID, ctx)} +} + +func (_c *ExecutorAPIMock_MonitorEvaluation_Call) Run(run func(evaluationID string, ctx context.Context)) *ExecutorAPIMock_MonitorEvaluation_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string), args[1].(context.Context)) + }) + return _c +} + +func (_c *ExecutorAPIMock_MonitorEvaluation_Call) Return(_a0 error) *ExecutorAPIMock_MonitorEvaluation_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *ExecutorAPIMock_MonitorEvaluation_Call) RunAndReturn(run func(string, context.Context) error) *ExecutorAPIMock_MonitorEvaluation_Call { + _c.Call.Return(run) + return _c +} + // RegisterNomadJob provides a mock function with given fields: job func (_m *ExecutorAPIMock) RegisterNomadJob(job *api.Job) (string, error) { ret := _m.Called(job) var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(*api.Job) (string, error)); ok { + return rf(job) + } if rf, ok := ret.Get(0).(func(*api.Job) string); ok { r0 = rf(job) } else { r0 = ret.Get(0).(string) } - var r1 error if rf, ok := ret.Get(1).(func(*api.Job) error); ok { r1 = rf(job) } else { @@ -284,6 +671,34 @@ func (_m *ExecutorAPIMock) RegisterNomadJob(job *api.Job) (string, error) { return r0, r1 } +// ExecutorAPIMock_RegisterNomadJob_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RegisterNomadJob' +type ExecutorAPIMock_RegisterNomadJob_Call struct { + *mock.Call +} + +// RegisterNomadJob is a helper method to define mock.On call +// - job *api.Job +func (_e *ExecutorAPIMock_Expecter) RegisterNomadJob(job interface{}) *ExecutorAPIMock_RegisterNomadJob_Call { + return &ExecutorAPIMock_RegisterNomadJob_Call{Call: _e.mock.On("RegisterNomadJob", job)} +} + +func (_c *ExecutorAPIMock_RegisterNomadJob_Call) Run(run func(job *api.Job)) *ExecutorAPIMock_RegisterNomadJob_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*api.Job)) + }) + return _c +} + +func (_c *ExecutorAPIMock_RegisterNomadJob_Call) Return(_a0 string, _a1 error) *ExecutorAPIMock_RegisterNomadJob_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ExecutorAPIMock_RegisterNomadJob_Call) RunAndReturn(run func(*api.Job) (string, error)) *ExecutorAPIMock_RegisterNomadJob_Call { + _c.Call.Return(run) + return _c +} + // RegisterRunnerJob provides a mock function with given fields: template func (_m *ExecutorAPIMock) RegisterRunnerJob(template *api.Job) error { ret := _m.Called(template) @@ -298,6 +713,34 @@ func (_m *ExecutorAPIMock) RegisterRunnerJob(template *api.Job) error { return r0 } +// ExecutorAPIMock_RegisterRunnerJob_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RegisterRunnerJob' +type ExecutorAPIMock_RegisterRunnerJob_Call struct { + *mock.Call +} + +// RegisterRunnerJob is a helper method to define mock.On call +// - template *api.Job +func (_e *ExecutorAPIMock_Expecter) RegisterRunnerJob(template interface{}) *ExecutorAPIMock_RegisterRunnerJob_Call { + return &ExecutorAPIMock_RegisterRunnerJob_Call{Call: _e.mock.On("RegisterRunnerJob", template)} +} + +func (_c *ExecutorAPIMock_RegisterRunnerJob_Call) Run(run func(template *api.Job)) *ExecutorAPIMock_RegisterRunnerJob_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*api.Job)) + }) + return _c +} + +func (_c *ExecutorAPIMock_RegisterRunnerJob_Call) Return(_a0 error) *ExecutorAPIMock_RegisterRunnerJob_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *ExecutorAPIMock_RegisterRunnerJob_Call) RunAndReturn(run func(*api.Job) error) *ExecutorAPIMock_RegisterRunnerJob_Call { + _c.Call.Return(run) + return _c +} + // SetJobScale provides a mock function with given fields: jobID, count, reason func (_m *ExecutorAPIMock) SetJobScale(jobID string, count uint, reason string) error { ret := _m.Called(jobID, count, reason) @@ -312,6 +755,36 @@ func (_m *ExecutorAPIMock) SetJobScale(jobID string, count uint, reason string) return r0 } +// ExecutorAPIMock_SetJobScale_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetJobScale' +type ExecutorAPIMock_SetJobScale_Call struct { + *mock.Call +} + +// SetJobScale is a helper method to define mock.On call +// - jobID string +// - count uint +// - reason string +func (_e *ExecutorAPIMock_Expecter) SetJobScale(jobID interface{}, count interface{}, reason interface{}) *ExecutorAPIMock_SetJobScale_Call { + return &ExecutorAPIMock_SetJobScale_Call{Call: _e.mock.On("SetJobScale", jobID, count, reason)} +} + +func (_c *ExecutorAPIMock_SetJobScale_Call) Run(run func(jobID string, count uint, reason string)) *ExecutorAPIMock_SetJobScale_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string), args[1].(uint), args[2].(string)) + }) + return _c +} + +func (_c *ExecutorAPIMock_SetJobScale_Call) Return(err error) *ExecutorAPIMock_SetJobScale_Call { + _c.Call.Return(err) + return _c +} + +func (_c *ExecutorAPIMock_SetJobScale_Call) RunAndReturn(run func(string, uint, string) error) *ExecutorAPIMock_SetJobScale_Call { + _c.Call.Return(run) + return _c +} + // WatchEventStream provides a mock function with given fields: ctx, callbacks func (_m *ExecutorAPIMock) WatchEventStream(ctx context.Context, callbacks *AllocationProcessoring) error { ret := _m.Called(ctx, callbacks) @@ -326,11 +799,44 @@ func (_m *ExecutorAPIMock) WatchEventStream(ctx context.Context, callbacks *Allo return r0 } +// ExecutorAPIMock_WatchEventStream_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchEventStream' +type ExecutorAPIMock_WatchEventStream_Call struct { + *mock.Call +} + +// WatchEventStream is a helper method to define mock.On call +// - ctx context.Context +// - callbacks *AllocationProcessoring +func (_e *ExecutorAPIMock_Expecter) WatchEventStream(ctx interface{}, callbacks interface{}) *ExecutorAPIMock_WatchEventStream_Call { + return &ExecutorAPIMock_WatchEventStream_Call{Call: _e.mock.On("WatchEventStream", ctx, callbacks)} +} + +func (_c *ExecutorAPIMock_WatchEventStream_Call) Run(run func(ctx context.Context, callbacks *AllocationProcessoring)) *ExecutorAPIMock_WatchEventStream_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(*AllocationProcessoring)) + }) + return _c +} + +func (_c *ExecutorAPIMock_WatchEventStream_Call) Return(_a0 error) *ExecutorAPIMock_WatchEventStream_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *ExecutorAPIMock_WatchEventStream_Call) RunAndReturn(run func(context.Context, *AllocationProcessoring) error) *ExecutorAPIMock_WatchEventStream_Call { + _c.Call.Return(run) + return _c +} + // allocation provides a mock function with given fields: jobID func (_m *ExecutorAPIMock) allocation(jobID string) (*api.Allocation, error) { ret := _m.Called(jobID) var r0 *api.Allocation + var r1 error + if rf, ok := ret.Get(0).(func(string) (*api.Allocation, error)); ok { + return rf(jobID) + } if rf, ok := ret.Get(0).(func(string) *api.Allocation); ok { r0 = rf(jobID) } else { @@ -339,7 +845,6 @@ func (_m *ExecutorAPIMock) allocation(jobID string) (*api.Allocation, error) { } } - var r1 error if rf, ok := ret.Get(1).(func(string) error); ok { r1 = rf(jobID) } else { @@ -349,6 +854,34 @@ func (_m *ExecutorAPIMock) allocation(jobID string) (*api.Allocation, error) { return r0, r1 } +// ExecutorAPIMock_allocation_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'allocation' +type ExecutorAPIMock_allocation_Call struct { + *mock.Call +} + +// allocation is a helper method to define mock.On call +// - jobID string +func (_e *ExecutorAPIMock_Expecter) allocation(jobID interface{}) *ExecutorAPIMock_allocation_Call { + return &ExecutorAPIMock_allocation_Call{Call: _e.mock.On("allocation", jobID)} +} + +func (_c *ExecutorAPIMock_allocation_Call) Run(run func(jobID string)) *ExecutorAPIMock_allocation_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string)) + }) + return _c +} + +func (_c *ExecutorAPIMock_allocation_Call) Return(_a0 *api.Allocation, _a1 error) *ExecutorAPIMock_allocation_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ExecutorAPIMock_allocation_Call) RunAndReturn(run func(string) (*api.Allocation, error)) *ExecutorAPIMock_allocation_Call { + _c.Call.Return(run) + return _c +} + // init provides a mock function with given fields: nomadConfig func (_m *ExecutorAPIMock) init(nomadConfig *config.Nomad) error { ret := _m.Called(nomadConfig) @@ -363,11 +896,43 @@ func (_m *ExecutorAPIMock) init(nomadConfig *config.Nomad) error { return r0 } +// ExecutorAPIMock_init_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'init' +type ExecutorAPIMock_init_Call struct { + *mock.Call +} + +// init is a helper method to define mock.On call +// - nomadConfig *config.Nomad +func (_e *ExecutorAPIMock_Expecter) init(nomadConfig interface{}) *ExecutorAPIMock_init_Call { + return &ExecutorAPIMock_init_Call{Call: _e.mock.On("init", nomadConfig)} +} + +func (_c *ExecutorAPIMock_init_Call) Run(run func(nomadConfig *config.Nomad)) *ExecutorAPIMock_init_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*config.Nomad)) + }) + return _c +} + +func (_c *ExecutorAPIMock_init_Call) Return(err error) *ExecutorAPIMock_init_Call { + _c.Call.Return(err) + return _c +} + +func (_c *ExecutorAPIMock_init_Call) RunAndReturn(run func(*config.Nomad) error) *ExecutorAPIMock_init_Call { + _c.Call.Return(run) + return _c +} + // job provides a mock function with given fields: jobID func (_m *ExecutorAPIMock) job(jobID string) (*api.Job, error) { ret := _m.Called(jobID) var r0 *api.Job + var r1 error + if rf, ok := ret.Get(0).(func(string) (*api.Job, error)); ok { + return rf(jobID) + } if rf, ok := ret.Get(0).(func(string) *api.Job); ok { r0 = rf(jobID) } else { @@ -376,7 +941,6 @@ func (_m *ExecutorAPIMock) job(jobID string) (*api.Job, error) { } } - var r1 error if rf, ok := ret.Get(1).(func(string) error); ok { r1 = rf(jobID) } else { @@ -386,11 +950,43 @@ func (_m *ExecutorAPIMock) job(jobID string) (*api.Job, error) { return r0, r1 } +// ExecutorAPIMock_job_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'job' +type ExecutorAPIMock_job_Call struct { + *mock.Call +} + +// job is a helper method to define mock.On call +// - jobID string +func (_e *ExecutorAPIMock_Expecter) job(jobID interface{}) *ExecutorAPIMock_job_Call { + return &ExecutorAPIMock_job_Call{Call: _e.mock.On("job", jobID)} +} + +func (_c *ExecutorAPIMock_job_Call) Run(run func(jobID string)) *ExecutorAPIMock_job_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string)) + }) + return _c +} + +func (_c *ExecutorAPIMock_job_Call) Return(job *api.Job, err error) *ExecutorAPIMock_job_Call { + _c.Call.Return(job, err) + return _c +} + +func (_c *ExecutorAPIMock_job_Call) RunAndReturn(run func(string) (*api.Job, error)) *ExecutorAPIMock_job_Call { + _c.Call.Return(run) + return _c +} + // listJobs provides a mock function with given fields: prefix func (_m *ExecutorAPIMock) listJobs(prefix string) ([]*api.JobListStub, error) { ret := _m.Called(prefix) var r0 []*api.JobListStub + var r1 error + if rf, ok := ret.Get(0).(func(string) ([]*api.JobListStub, error)); ok { + return rf(prefix) + } if rf, ok := ret.Get(0).(func(string) []*api.JobListStub); ok { r0 = rf(prefix) } else { @@ -399,7 +995,6 @@ func (_m *ExecutorAPIMock) listJobs(prefix string) ([]*api.JobListStub, error) { } } - var r1 error if rf, ok := ret.Get(1).(func(string) error); ok { r1 = rf(prefix) } else { @@ -409,6 +1004,34 @@ func (_m *ExecutorAPIMock) listJobs(prefix string) ([]*api.JobListStub, error) { return r0, r1 } +// ExecutorAPIMock_listJobs_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'listJobs' +type ExecutorAPIMock_listJobs_Call struct { + *mock.Call +} + +// listJobs is a helper method to define mock.On call +// - prefix string +func (_e *ExecutorAPIMock_Expecter) listJobs(prefix interface{}) *ExecutorAPIMock_listJobs_Call { + return &ExecutorAPIMock_listJobs_Call{Call: _e.mock.On("listJobs", prefix)} +} + +func (_c *ExecutorAPIMock_listJobs_Call) Run(run func(prefix string)) *ExecutorAPIMock_listJobs_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string)) + }) + return _c +} + +func (_c *ExecutorAPIMock_listJobs_Call) Return(allocationListStub []*api.JobListStub, err error) *ExecutorAPIMock_listJobs_Call { + _c.Call.Return(allocationListStub, err) + return _c +} + +func (_c *ExecutorAPIMock_listJobs_Call) RunAndReturn(run func(string) ([]*api.JobListStub, error)) *ExecutorAPIMock_listJobs_Call { + _c.Call.Return(run) + return _c +} + type mockConstructorTestingTNewExecutorAPIMock interface { mock.TestingT Cleanup(func()) diff --git a/internal/nomad/nomad.go b/internal/nomad/nomad.go index 06fef8d..38eb2d9 100644 --- a/internal/nomad/nomad.go +++ b/internal/nomad/nomad.go @@ -72,7 +72,8 @@ type ExecutorAPI interface { // It writes the output of the command to stdout/stderr and reads input from stdin. // If tty is true, the command will run with a tty. // Iff privilegedExecution is true, the command will be executed privileged. - ExecuteCommand(jobID string, ctx context.Context, command []string, tty bool, privilegedExecution bool, + // The command is passed in the shell form (not the exec array form) and will be executed in a shell. + ExecuteCommand(jobID string, ctx context.Context, command string, tty bool, privilegedExecution bool, stdin io.Reader, stdout, stderr io.Writer) (int, error) // MarkRunnerAsUsed marks the runner with the given ID as used. It also stores the timeout duration in the metadata. @@ -389,10 +390,8 @@ func (a *APIClient) LoadEnvironmentJobs() ([]*nomadApi.Job, error) { // If tty is true, Nomad would normally write stdout and stderr of the command // both on the stdout stream. However, if the InteractiveStderr server config option is true, // we make sure that stdout and stderr are split correctly. -// In order for the stderr splitting to work, the command must have the structure -// []string{..., "bash", "-c", "my-command"}. func (a *APIClient) ExecuteCommand(jobID string, - ctx context.Context, command []string, tty bool, privilegedExecution bool, + ctx context.Context, command string, tty bool, privilegedExecution bool, stdin io.Reader, stdout, stderr io.Writer) (int, error) { if tty && config.Config.Server.InteractiveStderr { return a.executeCommandInteractivelyWithStderr(jobID, ctx, command, privilegedExecution, stdin, stdout, stderr) @@ -411,7 +410,7 @@ func (a *APIClient) ExecuteCommand(jobID string, // to be served both over stdout. This function circumvents this by creating a fifo for the stderr // of the command and starting a second execution that reads the stderr from that fifo. func (a *APIClient) executeCommandInteractivelyWithStderr(allocationID string, ctx context.Context, - command []string, privilegedExecution bool, stdin io.Reader, stdout, stderr io.Writer) (int, error) { + command string, privilegedExecution bool, stdin io.Reader, stdout, stderr io.Writer) (int, error) { // Use current nano time to make the stderr fifo kind of unique. currentNanoTime := time.Now().UnixNano() @@ -461,8 +460,8 @@ const ( // stderrWrapperCommandFormat, if executed, is supposed to wait until a fifo exists (it sleeps 10ms to reduce load // cause by busy waiting on the system). Once the fifo exists, the given command is executed and its stderr // redirected to the fifo. - // Example: "'until [ -e my.fifo ]; do sleep 0.01; done; (echo \"my.fifo exists\") 2> my.fifo'". - stderrWrapperCommandFormat = "'until [ -e %s ]; do sleep 0.01; done; (%s) 2> %s'" + // Example: "until [ -e my.fifo ]; do sleep 0.01; done; (echo \"my.fifo exists\") 2> my.fifo". + stderrWrapperCommandFormat = "until [ -e %s ]; do sleep 0.01; done; (%s) 2> %s" // setUserBinaryPath is due to Poseidon requires the setuser script for Nomad environments. setUserBinaryPath = "/sbin/setuser" @@ -474,58 +473,61 @@ const ( UnprivilegedExecution = false ) -func prepareCommandWithoutTTY(srcCommands []string, privilegedExecution bool) []string { - commands := make([]string, len(srcCommands)) // nozero The size is required for the copy. - copy(commands, srcCommands) +func prepareCommandWithoutTTY(command string, privilegedExecution bool) string { + command = setInnerDebugMessages(command, false) - commands[len(commands)-1] = setInnerDebugMessages(commands[len(commands)-1], false) - commands = setUserCommand(commands, privilegedExecution) - commands[len(commands)-1] = fmt.Sprintf("'%s'", commands[len(commands)-1]) - cmd := strings.Join(commands, " ") - cmd = fmt.Sprintf(unsetEnvironmentVariablesFormat, unsetEnvironmentVariablesShell, cmd) - // Debug Message - cmd = fmt.Sprintf(timeDebugMessageFormatStart, "SetUserAndUnsetEnv", cmd) - return []string{"bash", "-c", cmd} + command = setUserCommand(command, privilegedExecution) + command = unsetEnvironmentVariables(command) + return command } -func prepareCommandTTY(srcCommands []string, currentNanoTime int64, privilegedExecution bool) []string { - commands := make([]string, len(srcCommands)) // nozero The size is required for the copy. - copy(commands, srcCommands) +func prepareCommandTTY(command string, currentNanoTime int64, privilegedExecution bool) string { + command = setInnerDebugMessages(command, false) - commands[len(commands)-1] = setInnerDebugMessages(commands[len(commands)-1], true) - commands = setUserCommand(commands, privilegedExecution) - // Take the last command which is the one to be executed and wrap it to redirect stderr. + // Take the command to be executed and wrap it to redirect stderr. stderrFifoPath := stderrFifo(currentNanoTime) - commands[len(commands)-1] = - fmt.Sprintf(stderrWrapperCommandFormat, stderrFifoPath, commands[len(commands)-1], stderrFifoPath) - cmd := strings.Join(commands, " ") - cmd = fmt.Sprintf(unsetEnvironmentVariablesFormat, unsetEnvironmentVariablesShell, cmd) - // Debug Message - cmd = fmt.Sprintf(timeDebugMessageFormatStart, "SetUserAndUnsetEnv", cmd) - return []string{"bash", "-c", cmd} + command = fmt.Sprintf(stderrWrapperCommandFormat, stderrFifoPath, command, stderrFifoPath) + + command = setUserCommand(command, privilegedExecution) + command = unsetEnvironmentVariables(command) + return command } -func prepareCommandTTYStdErr(currentNanoTime int64, privilegedExecution bool) []string { +func prepareCommandTTYStdErr(currentNanoTime int64, privilegedExecution bool) string { stderrFifoPath := stderrFifo(currentNanoTime) - cmd := fmt.Sprintf(stderrFifoCommandFormat, stderrFifoPath, stderrFifoPath, stderrFifoPath) - cmd = setInnerDebugMessages(cmd, false) - return setUserCommand([]string{"bash", "-c", cmd}, privilegedExecution) -} - -// setUserCommand prefixes the passed command with the setUser command. -// The passed command needs to be wrapped in single quotes to avoid escaping the setUser binary. -func setUserCommand(command []string, privilegedExecution bool) []string { - if privilegedExecution { - return command - } else { - return append([]string{setUserBinaryPath, setUserBinaryUser}, command...) - } + command := fmt.Sprintf(stderrFifoCommandFormat, stderrFifoPath, stderrFifoPath, stderrFifoPath) + command = setInnerDebugMessages(command, false) + command = setUserCommand(command, privilegedExecution) + return command } func stderrFifo(id int64) string { return fmt.Sprintf(stderrFifoFormat, id) } +func unsetEnvironmentVariables(command string) string { + command = dto.WrapBashCommand(command) + command = fmt.Sprintf(unsetEnvironmentVariablesFormat, unsetEnvironmentVariablesShell, command) + + // Debug Message + command = fmt.Sprintf(timeDebugMessageFormatStart, "UnsetEnv", command) + return command +} + +// setUserCommand prefixes the passed command with the setUser command. +func setUserCommand(command string, privilegedExecution bool) string { + // Wrap the inner command first so that the setUserBinary applies to the whole inner command. + command = dto.WrapBashCommand(command) + + if !privilegedExecution { + command = fmt.Sprintf("%s %s %s", setUserBinaryPath, setUserBinaryUser, command) + } + + // Debug Message + command = fmt.Sprintf(timeDebugMessageFormatStart, "SetUser", command) + return command +} + // setInnerDebugMessages injects debug commands into the bash command. // The debug messages are parsed by the SentryDebugWriter. func setInnerDebugMessages(command string, includeCommandInDescription bool) (result string) { diff --git a/internal/nomad/nomad_test.go b/internal/nomad/nomad_test.go index 414e875..3968309 100644 --- a/internal/nomad/nomad_test.go +++ b/internal/nomad/nomad_test.go @@ -644,21 +644,19 @@ func TestExecuteCommandTestSuite(t *testing.T) { type ExecuteCommandTestSuite struct { suite.Suite - allocationID string - ctx context.Context - testCommand string - testCommandArray []string - expectedStdout string - expectedStderr string - apiMock *apiQuerierMock - nomadAPIClient APIClient + allocationID string + ctx context.Context + testCommand string + expectedStdout string + expectedStderr string + apiMock *apiQuerierMock + nomadAPIClient APIClient } func (s *ExecuteCommandTestSuite) SetupTest() { s.allocationID = "test-allocation-id" s.ctx = context.Background() s.testCommand = "echo \"do nothing\"" - s.testCommandArray = []string{"bash", "-c", s.testCommand} s.expectedStdout = "stdout" s.expectedStderr = "stderr" s.apiMock = &apiQuerierMock{} @@ -673,18 +671,18 @@ func (s *ExecuteCommandTestSuite) TestWithSeparateStderr() { stderrExitCode := 1 var stdout, stderr bytes.Buffer - var calledStdoutCommand, calledStderrCommand []string + var calledStdoutCommand, calledStderrCommand string // mock regular call - call := s.mockExecute(mock.AnythingOfType("[]string"), 0, nil, func(_ mock.Arguments) {}) + call := s.mockExecute(mock.AnythingOfType("string"), 0, nil, func(_ mock.Arguments) {}) call.Run(func(args mock.Arguments) { var ok bool - calledCommand, ok := args.Get(2).([]string) + calledCommand, ok := args.Get(2).(string) s.Require().True(ok) writer, ok := args.Get(5).(io.Writer) s.Require().True(ok) - if isStderrCommand := len(calledCommand) == 5; isStderrCommand { + if isStderrCommand := strings.Contains(calledCommand, "mkfifo"); isStderrCommand { calledStderrCommand = calledCommand _, err := writer.Write([]byte(s.expectedStderr)) s.Require().NoError(err) @@ -697,7 +695,7 @@ func (s *ExecuteCommandTestSuite) TestWithSeparateStderr() { } }) - exitCode, err := s.nomadAPIClient.ExecuteCommand(s.allocationID, s.ctx, s.testCommandArray, withTTY, + exitCode, err := s.nomadAPIClient.ExecuteCommand(s.allocationID, s.ctx, s.testCommand, withTTY, UnprivilegedExecution, nullio.Reader{}, &stdout, &stderr) s.Require().NoError(err) @@ -705,18 +703,18 @@ func (s *ExecuteCommandTestSuite) TestWithSeparateStderr() { s.Equal(commandExitCode, exitCode) s.Run("should wrap command in stderr wrapper", func() { - s.Require().NotNil(calledStdoutCommand) + s.Require().NotEmpty(calledStdoutCommand) stderrWrapperCommand := fmt.Sprintf(stderrWrapperCommandFormat, stderrFifoFormat, s.testCommand, stderrFifoFormat) stdoutFifoRegexp := strings.ReplaceAll(regexp.QuoteMeta(stderrWrapperCommand), "%d", "\\d*") stdoutFifoRegexp = strings.Replace(stdoutFifoRegexp, s.testCommand, ".*", 1) - s.Regexp(stdoutFifoRegexp, calledStdoutCommand[len(calledStdoutCommand)-1]) + s.Regexp(stdoutFifoRegexp, calledStdoutCommand) }) s.Run("should call correct stderr command", func() { - s.Require().NotNil(calledStderrCommand) + s.Require().NotEmpty(calledStderrCommand) stderrFifoCommand := fmt.Sprintf(stderrFifoCommandFormat, stderrFifoFormat, stderrFifoFormat, stderrFifoFormat) stderrFifoRegexp := strings.ReplaceAll(regexp.QuoteMeta(stderrFifoCommand), "%d", "\\d*") - s.Regexp(stderrFifoRegexp, calledStderrCommand[len(calledStderrCommand)-1]) + s.Regexp(stderrFifoRegexp, calledStderrCommand) }) s.Run("should return correct output", func() { @@ -728,20 +726,20 @@ func (s *ExecuteCommandTestSuite) TestWithSeparateStderr() { func (s *ExecuteCommandTestSuite) TestWithSeparateStderrReturnsCommandError() { config.Config.Server.InteractiveStderr = true - call := s.mockExecute(mock.AnythingOfType("[]string"), 0, nil, func(_ mock.Arguments) {}) + call := s.mockExecute(mock.AnythingOfType("string"), 0, nil, func(_ mock.Arguments) {}) call.Run(func(args mock.Arguments) { var ok bool - calledCommand, ok := args.Get(2).([]string) + calledCommand, ok := args.Get(2).(string) s.Require().True(ok) - if isStderrCommand := len(calledCommand) == 5; isStderrCommand { + if isStderrCommand := strings.Contains(calledCommand, "mkfifo"); isStderrCommand { call.ReturnArguments = mock.Arguments{1, nil} } else { call.ReturnArguments = mock.Arguments{1, tests.ErrDefault} } }) - _, err := s.nomadAPIClient.ExecuteCommand(s.allocationID, s.ctx, s.testCommandArray, withTTY, UnprivilegedExecution, + _, err := s.nomadAPIClient.ExecuteCommand(s.allocationID, s.ctx, s.testCommand, withTTY, UnprivilegedExecution, nullio.Reader{}, io.Discard, io.Discard) s.Equal(tests.ErrDefault, err) } @@ -752,7 +750,7 @@ func (s *ExecuteCommandTestSuite) TestWithoutSeparateStderr() { commandExitCode := 42 // mock regular call - expectedCommand := prepareCommandWithoutTTY(s.testCommandArray, UnprivilegedExecution) + expectedCommand := prepareCommandWithoutTTY(s.testCommand, UnprivilegedExecution) s.mockExecute(expectedCommand, commandExitCode, nil, func(args mock.Arguments) { stdout, ok := args.Get(5).(io.Writer) s.Require().True(ok) @@ -764,7 +762,7 @@ func (s *ExecuteCommandTestSuite) TestWithoutSeparateStderr() { s.Require().NoError(err) }) - exitCode, err := s.nomadAPIClient.ExecuteCommand(s.allocationID, s.ctx, s.testCommandArray, withTTY, + exitCode, err := s.nomadAPIClient.ExecuteCommand(s.allocationID, s.ctx, s.testCommand, withTTY, UnprivilegedExecution, nullio.Reader{}, &stdout, &stderr) s.Require().NoError(err) @@ -776,9 +774,9 @@ func (s *ExecuteCommandTestSuite) TestWithoutSeparateStderr() { func (s *ExecuteCommandTestSuite) TestWithoutSeparateStderrReturnsCommandError() { config.Config.Server.InteractiveStderr = false - expectedCommand := prepareCommandWithoutTTY(s.testCommandArray, UnprivilegedExecution) + expectedCommand := prepareCommandWithoutTTY(s.testCommand, UnprivilegedExecution) s.mockExecute(expectedCommand, 1, tests.ErrDefault, func(args mock.Arguments) {}) - _, err := s.nomadAPIClient.ExecuteCommand(s.allocationID, s.ctx, s.testCommandArray, withTTY, UnprivilegedExecution, + _, err := s.nomadAPIClient.ExecuteCommand(s.allocationID, s.ctx, s.testCommand, withTTY, UnprivilegedExecution, nullio.Reader{}, io.Discard, io.Discard) s.ErrorIs(err, tests.ErrDefault) } diff --git a/internal/nomad/sentry_debug_writer.go b/internal/nomad/sentry_debug_writer.go index c07f3d4..22534b9 100644 --- a/internal/nomad/sentry_debug_writer.go +++ b/internal/nomad/sentry_debug_writer.go @@ -4,23 +4,23 @@ import ( "context" "fmt" "github.com/getsentry/sentry-go" + "github.com/openHPI/poseidon/pkg/dto" "io" "regexp" "strconv" "time" ) -const ( - // timeDebugMessageFormat is the format of messages that will be converted to debug messages. - // Format Parameters: 1. Debug Comment, 2. command. - timeDebugMessageFormatStart = `echo -ne "\x1EPoseidon %s $(date +%%s%%3N)\x1E"; %s` - // Format Parameters: 1. command, 2. Debug Comment. - timeDebugMessageFormatEnd = `%s; bash -c "ec=$?; echo -ne \"\\x1EPoseidon %s \$(date +%%s%%3N)\\x1E\" && exit \$ec"` -) - var ( - timeDebugMessagePattern = regexp. - MustCompile(`(?P.*)\x1EPoseidon (?P.+) (?P