diff --git a/cmd/incusd/instance_exec.go b/cmd/incusd/instance_exec.go index 382e30c54a5..adee08836df 100644 --- a/cmd/incusd/instance_exec.go +++ b/cmd/incusd/instance_exec.go @@ -26,6 +26,7 @@ import ( "github.com/lxc/incus/internal/server/cluster" "github.com/lxc/incus/internal/server/db/operationtype" "github.com/lxc/incus/internal/server/instance" + "github.com/lxc/incus/internal/server/instance/drivers" "github.com/lxc/incus/internal/server/instance/instancetype" "github.com/lxc/incus/internal/server/operations" "github.com/lxc/incus/internal/server/request" @@ -286,7 +287,14 @@ func (s *execWs) Do(op *operations.Operation) error { _ = pty.Close() } + // Make VM disconnections (shutdown/reboot) match containers. + if cmdErr == drivers.ErrExecDisconnected { + cmdResult = 129 + cmdErr = nil + } + metadata := jmap.Map{"return": cmdResult} + err = op.ExtendMetadata(metadata) if err != nil { return err diff --git a/internal/server/instance/drivers/driver_qemu_cmd.go b/internal/server/instance/drivers/driver_qemu_cmd.go index c440befbe4e..022be471505 100644 --- a/internal/server/instance/drivers/driver_qemu_cmd.go +++ b/internal/server/instance/drivers/driver_qemu_cmd.go @@ -13,6 +13,9 @@ import ( "github.com/lxc/incus/shared/logger" ) +// ErrExecDisconnected is returned when the guest disconnects the exec session. +var ErrExecDisconnected = fmt.Errorf("Disconnected") + // Cmd represents a running command for an Qemu VM. type qemuCmd struct { attachedChildPid int @@ -78,7 +81,7 @@ func (c *qemuCmd) Wait() (int, error) { // so we inform the client of the disconnection with a more // descriptive message. if errors.Is(err, io.EOF) { - return exitStatus, fmt.Errorf("Disconnected") + return exitStatus, ErrExecDisconnected } return exitStatus, err