diff --git a/cluster/calcium/execute.go b/cluster/calcium/execute.go index 7eb6b8506..4f4d6c728 100644 --- a/cluster/calcium/execute.go +++ b/cluster/calcium/execute.go @@ -43,7 +43,7 @@ func (c *Calcium) ExecuteWorkload(ctx context.Context, opts *types.ExecuteWorklo Detach: false, } - execID, stdout, stderr, inStream, err := workload.Engine.Execute(ctx, opts.WorkloadID, execConfig) + result, stdout, stderr, inStream, err := workload.Engine.Execute(ctx, opts.WorkloadID, execConfig) if err != nil { logger.Errorf(ctx, "[ExecuteWorkload] Failed to attach execID: %+v", err) return @@ -52,7 +52,7 @@ func (c *Calcium) ExecuteWorkload(ctx context.Context, opts *types.ExecuteWorklo splitFunc, split := bufio.ScanLines, byte('\n') if opts.OpenStdin { processVirtualizationInStream(ctx, inStream, inCh, func(height, width uint) error { - return workload.Engine.ExecResize(ctx, execID, height, width) + return workload.Engine.ExecResize(ctx, opts.WorkloadID, result, height, width) }) splitFunc, split = bufio.ScanBytes, byte(0) } @@ -61,7 +61,7 @@ func (c *Calcium) ExecuteWorkload(ctx context.Context, opts *types.ExecuteWorklo ch <- &types.AttachWorkloadMessage{WorkloadID: opts.WorkloadID, Data: m.Data, StdStreamType: m.StdStreamType} } - execCode, err := workload.Engine.ExecExitCode(ctx, execID) + execCode, err := workload.Engine.ExecExitCode(ctx, opts.WorkloadID, result) if err != nil { logger.Errorf(ctx, "[ExecuteWorkload] Failed to get exitcode: %+v", err) return diff --git a/cluster/calcium/helper.go b/cluster/calcium/helper.go index e8f20f901..1b4044a2e 100644 --- a/cluster/calcium/helper.go +++ b/cluster/calcium/helper.go @@ -37,7 +37,7 @@ func execuateInside(ctx context.Context, client engine.API, ID, cmd, user string AttachStdout: true, } b := []byte{} - execID, stdout, stderr, _, err := client.Execute(ctx, ID, execConfig) + result, stdout, stderr, _, err := client.Execute(ctx, ID, execConfig) if err != nil { return nil, errors.WithStack(err) } @@ -46,7 +46,7 @@ func execuateInside(ctx context.Context, client engine.API, ID, cmd, user string b = append(b, m.Data...) } - exitCode, err := client.ExecExitCode(ctx, execID) + exitCode, err := client.ExecExitCode(ctx, ID, result) if err != nil { return b, errors.WithStack(err) } diff --git a/engine/docker/exec.go b/engine/docker/exec.go index 88c6407af..c595697f6 100644 --- a/engine/docker/exec.go +++ b/engine/docker/exec.go @@ -48,8 +48,8 @@ func (e *Engine) execAttach(ctx context.Context, execID string, tty bool) (io.Re } // Execute executes a workload -func (e *Engine) Execute(ctx context.Context, target string, config *enginetypes.ExecConfig) (execID string, stdout, stderr io.ReadCloser, stdin io.WriteCloser, err error) { - if execID, err = e.execCreate(ctx, target, config); err != nil { +func (e *Engine) Execute(ctx context.Context, ID string, config *enginetypes.ExecConfig) (execID string, stdout, stderr io.ReadCloser, stdin io.WriteCloser, err error) { + if execID, err = e.execCreate(ctx, ID, config); err != nil { return } @@ -79,7 +79,7 @@ func (e *Engine) demultiplexStdStream(ctx context.Context, stdStream io.Reader) } // ExecExitCode get exec return code -func (e *Engine) ExecExitCode(ctx context.Context, execID string) (int, error) { +func (e *Engine) ExecExitCode(ctx context.Context, ID, execID string) (int, error) { r, err := e.client.ContainerExecInspect(ctx, execID) if err != nil { return -1, err @@ -88,7 +88,7 @@ func (e *Engine) ExecExitCode(ctx context.Context, execID string) (int, error) { } // ExecResize resize exec tty -func (e *Engine) ExecResize(ctx context.Context, execID string, height, width uint) (err error) { +func (e *Engine) ExecResize(ctx context.Context, ID, execID string, height, width uint) error { opts := dockertypes.ResizeOptions{ Height: height, Width: width, diff --git a/engine/engine.go b/engine/engine.go index 22720692f..7d7b9adac 100644 --- a/engine/engine.go +++ b/engine/engine.go @@ -13,9 +13,9 @@ import ( type API interface { Info(ctx context.Context) (*enginetypes.Info, error) - Execute(ctx context.Context, target string, config *enginetypes.ExecConfig) (execID string, stdout, stderr io.ReadCloser, stdin io.WriteCloser, _ error) - ExecResize(ctx context.Context, execID string, height, width uint) (err error) - ExecExitCode(ctx context.Context, execID string) (int, error) + Execute(ctx context.Context, ID string, config *enginetypes.ExecConfig) (result string, stdout, stderr io.ReadCloser, stdin io.WriteCloser, err error) + ExecResize(ctx context.Context, ID, result string, height, width uint) (err error) + ExecExitCode(ctx context.Context, ID, result string) (int, error) NetworkConnect(ctx context.Context, network, target, ipv4, ipv6 string) ([]string, error) NetworkDisconnect(ctx context.Context, network, target string, force bool) error diff --git a/engine/mocks/API.go b/engine/mocks/API.go index f2bd176ab..78a8433e8 100644 --- a/engine/mocks/API.go +++ b/engine/mocks/API.go @@ -67,20 +67,20 @@ func (_m *API) BuildRefs(ctx context.Context, name string, tags []string) []stri return r0 } -// ExecExitCode provides a mock function with given fields: ctx, execID -func (_m *API) ExecExitCode(ctx context.Context, execID string) (int, error) { - ret := _m.Called(ctx, execID) +// ExecExitCode provides a mock function with given fields: ctx, ID, pid +func (_m *API) ExecExitCode(ctx context.Context, ID string, pid string) (int, error) { + ret := _m.Called(ctx, ID, pid) var r0 int - if rf, ok := ret.Get(0).(func(context.Context, string) int); ok { - r0 = rf(ctx, execID) + if rf, ok := ret.Get(0).(func(context.Context, string, string) int); ok { + r0 = rf(ctx, ID, pid) } else { r0 = ret.Get(0).(int) } var r1 error - if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { - r1 = rf(ctx, execID) + if rf, ok := ret.Get(1).(func(context.Context, string, string) error); ok { + r1 = rf(ctx, ID, pid) } else { r1 = ret.Error(1) } @@ -88,13 +88,13 @@ func (_m *API) ExecExitCode(ctx context.Context, execID string) (int, error) { return r0, r1 } -// ExecResize provides a mock function with given fields: ctx, execID, height, width -func (_m *API) ExecResize(ctx context.Context, execID string, height uint, width uint) error { - ret := _m.Called(ctx, execID, height, width) +// ExecResize provides a mock function with given fields: ctx, ID, result, height, width +func (_m *API) ExecResize(ctx context.Context, ID string, result string, height uint, width uint) error { + ret := _m.Called(ctx, ID, result, height, width) var r0 error - if rf, ok := ret.Get(0).(func(context.Context, string, uint, uint) error); ok { - r0 = rf(ctx, execID, height, width) + if rf, ok := ret.Get(0).(func(context.Context, string, string, uint, uint) error); ok { + r0 = rf(ctx, ID, result, height, width) } else { r0 = ret.Error(0) } @@ -102,20 +102,20 @@ func (_m *API) ExecResize(ctx context.Context, execID string, height uint, width return r0 } -// Execute provides a mock function with given fields: ctx, target, config -func (_m *API) Execute(ctx context.Context, target string, config *types.ExecConfig) (string, io.ReadCloser, io.ReadCloser, io.WriteCloser, error) { - ret := _m.Called(ctx, target, config) +// Execute provides a mock function with given fields: ctx, ID, config +func (_m *API) Execute(ctx context.Context, ID string, config *types.ExecConfig) (string, io.ReadCloser, io.ReadCloser, io.WriteCloser, error) { + ret := _m.Called(ctx, ID, config) var r0 string if rf, ok := ret.Get(0).(func(context.Context, string, *types.ExecConfig) string); ok { - r0 = rf(ctx, target, config) + r0 = rf(ctx, ID, config) } else { r0 = ret.Get(0).(string) } var r1 io.ReadCloser if rf, ok := ret.Get(1).(func(context.Context, string, *types.ExecConfig) io.ReadCloser); ok { - r1 = rf(ctx, target, config) + r1 = rf(ctx, ID, config) } else { if ret.Get(1) != nil { r1 = ret.Get(1).(io.ReadCloser) @@ -124,7 +124,7 @@ func (_m *API) Execute(ctx context.Context, target string, config *types.ExecCon var r2 io.ReadCloser if rf, ok := ret.Get(2).(func(context.Context, string, *types.ExecConfig) io.ReadCloser); ok { - r2 = rf(ctx, target, config) + r2 = rf(ctx, ID, config) } else { if ret.Get(2) != nil { r2 = ret.Get(2).(io.ReadCloser) @@ -133,7 +133,7 @@ func (_m *API) Execute(ctx context.Context, target string, config *types.ExecCon var r3 io.WriteCloser if rf, ok := ret.Get(3).(func(context.Context, string, *types.ExecConfig) io.WriteCloser); ok { - r3 = rf(ctx, target, config) + r3 = rf(ctx, ID, config) } else { if ret.Get(3) != nil { r3 = ret.Get(3).(io.WriteCloser) @@ -142,7 +142,7 @@ func (_m *API) Execute(ctx context.Context, target string, config *types.ExecCon var r4 error if rf, ok := ret.Get(4).(func(context.Context, string, *types.ExecConfig) error); ok { - r4 = rf(ctx, target, config) + r4 = rf(ctx, ID, config) } else { r4 = ret.Error(4) } diff --git a/engine/systemd/exec.go b/engine/systemd/exec.go index 7a40b196f..d85e8c40a 100644 --- a/engine/systemd/exec.go +++ b/engine/systemd/exec.go @@ -15,13 +15,13 @@ func (e *Engine) Execute(ctx context.Context, target string, config *enginetypes } // ExecResize resize the terminal size -func (e *Engine) ExecResize(ctx context.Context, execID string, height, width uint) (err error) { +func (e *Engine) ExecResize(ctx context.Context, ID, result string, height, width uint) (err error) { err = types.ErrEngineNotImplemented return } // ExecExitCode fetches exceuction exit code -func (e *Engine) ExecExitCode(ctx context.Context, execID string) (execCode int, err error) { +func (e *Engine) ExecExitCode(ctx context.Context, ID, pid string) (execCode int, err error) { err = types.ErrEngineNotImplemented return } diff --git a/engine/virt/virt.go b/engine/virt/virt.go index cc5094fdb..51827d16a 100644 --- a/engine/virt/virt.go +++ b/engine/virt/virt.go @@ -7,6 +7,7 @@ import ( "fmt" "io" "io/ioutil" + "strconv" "strings" "time" @@ -73,30 +74,36 @@ func (v *Virt) Info(ctx context.Context) (*enginetypes.Info, error) { } // Execute executes a command in vm -func (v *Virt) Execute(ctx context.Context, target string, config *enginetypes.ExecConfig) (execID string, stdout io.ReadCloser, stderr io.ReadCloser, inputStream io.WriteCloser, err error) { +func (v *Virt) Execute(ctx context.Context, ID string, config *enginetypes.ExecConfig) (pid string, stdout, stderr io.ReadCloser, stdin io.WriteCloser, err error) { if config.Tty { flags := virttypes.AttachGuestFlags{Safe: true, Force: true} - stream, err := v.client.AttachGuest(ctx, target, config.Cmd, flags) + stream, err := v.client.AttachGuest(ctx, ID, config.Cmd, flags) if err != nil { return "", nil, nil, nil, err } - return target, ioutil.NopCloser(stream), nil, stream, nil + return "", ioutil.NopCloser(stream), nil, stream, nil } - - msg, err := v.client.ExecuteGuest(ctx, target, config.Cmd) - return target, ioutil.NopCloser(bytes.NewReader(msg.Data)), nil, nil, err - + msg, err := v.client.ExecuteGuest(ctx, ID, config.Cmd) + return strconv.Itoa(msg.Pid), ioutil.NopCloser(bytes.NewReader(msg.Data)), nil, nil, err } -// ExecExitCode gets return code of a specific execution. -func (v *Virt) ExecExitCode(ctx context.Context, execID string) (code int, err error) { - return 0, nil +// ExecExitCode get return code of a specific execution. +func (v *Virt) ExecExitCode(ctx context.Context, ID, pid string) (code int, err error) { + iPid, err := strconv.Atoi(pid) + if err != nil { + return -1, err + } + code, err = v.client.ExecExitCode(ctx, ID, iPid) + if err != nil { + return -1, err + } + return } // ExecResize resize exec tty -func (v *Virt) ExecResize(ctx context.Context, execID string, height, width uint) (err error) { - return v.client.ResizeConsoleWindow(ctx, execID, height, width) +func (v *Virt) ExecResize(ctx context.Context, ID, pid string, height, width uint) (err error) { + return v.client.ResizeConsoleWindow(ctx, ID, height, width) } // NetworkConnect connects to a network. diff --git a/go.mod b/go.mod index 11b6a9f36..3ed9c7078 100644 --- a/go.mod +++ b/go.mod @@ -32,7 +32,7 @@ require ( github.com/opencontainers/runc v1.0.0-rc95 // indirect github.com/patrickmn/go-cache v2.1.0+incompatible github.com/pkg/errors v0.9.1 - github.com/projecteru2/libyavirt v0.0.0-20210920022816-abc7aa0cf6ae + github.com/projecteru2/libyavirt v0.0.0-20210927061827-61332cb449e6 github.com/prometheus/client_golang v1.11.0 github.com/sanity-io/litter v1.5.1 github.com/sirupsen/logrus v1.7.0 diff --git a/go.sum b/go.sum index 88ea8a083..2a2b4f8ad 100644 --- a/go.sum +++ b/go.sum @@ -454,8 +454,8 @@ github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= -github.com/projecteru2/libyavirt v0.0.0-20210920022816-abc7aa0cf6ae h1:Pohd/mJQaWHnwa88GIzGl63DkvGrt5AzHEQu6ymJw+w= -github.com/projecteru2/libyavirt v0.0.0-20210920022816-abc7aa0cf6ae/go.mod h1:FOc+hWBMLsMrmx5p3/moizKeSomedZPNwB6LhS+kEnE= +github.com/projecteru2/libyavirt v0.0.0-20210927061827-61332cb449e6 h1:URFUsdkCfuOdI30j+r6/rOUl7OKkAwL0AdjDrlfKhWs= +github.com/projecteru2/libyavirt v0.0.0-20210927061827-61332cb449e6/go.mod h1:FOc+hWBMLsMrmx5p3/moizKeSomedZPNwB6LhS+kEnE= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=