[lxc-devel] [lxd/master] VM Exec
tomponline on Github
lxc-bot at linuxcontainers.org
Mon Nov 11 12:33:38 UTC 2019
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 371 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20191111/9282c133/attachment.bin>
-------------- next part --------------
From e50caecd0d2a48a351446778ea68020789f18ff7 Mon Sep 17 00:00:00 2001
From: Thomas Hipp <thomas.hipp at canonical.com>
Date: Mon, 28 Oct 2019 12:29:49 +0100
Subject: [PATCH 1/5] lxd/vm: Implement Exec for VMs
Signed-off-by: Thomas Hipp <thomas.hipp at canonical.com>
---
lxd/vm_qemu.go | 36 +++++++++++++++++++++++++++++++++++-
1 file changed, 35 insertions(+), 1 deletion(-)
diff --git a/lxd/vm_qemu.go b/lxd/vm_qemu.go
index eca1bbe0e8..53cabf528f 100644
--- a/lxd/vm_qemu.go
+++ b/lxd/vm_qemu.go
@@ -1969,8 +1969,42 @@ func (vm *vmQemu) Console() (*os.File, error) {
}
func (vm *vmQemu) Exec(command []string, env map[string]string, stdin *os.File, stdout *os.File, stderr *os.File, wait bool, cwd string, uid uint32, gid uint32) (*exec.Cmd, int, int, error) {
- return nil, 0, 0, fmt.Errorf("Exec Not implemented")
+ agent, err := lxdClient.ConnectLXDHTTP(nil, vm.agentClient)
+ if err != nil {
+ return nil, 0, 0, err
+ }
+
+ post := api.InstanceExecPost{
+ Command: command,
+ WaitForWS: wait,
+ Interactive: stdin == stdout,
+ Environment: env,
+ User: uid,
+ Group: gid,
+ Cwd: cwd,
+ }
+
+ args := lxdClient.InstanceExecArgs{
+ Stdin: stdin,
+ Stdout: stdout,
+ Stderr: stderr,
+ DataDone: make(chan bool),
+ }
+
+ op, err := agent.ExecInstance("", post, &args)
+ if err != nil {
+ return nil, -1, -1, err
+ }
+
+ err = op.Wait()
+ if err != nil {
+ return nil, -1, -1, err
+ }
+ opAPI := op.Get()
+
+ <-args.DataDone
+ return nil, int(opAPI.Metadata["return"].(float64)), -1, nil
}
func (vm *vmQemu) Render() (interface{}, interface{}, error) {
From 6be5a4af1ffe09f313d1690bd8a7837ba101266c Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Mon, 11 Nov 2019 12:30:07 +0000
Subject: [PATCH 2/5] lxd-agent/exec: Proper logger
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd-agent/exec.go | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/lxd-agent/exec.go b/lxd-agent/exec.go
index 32170b01ff..562f6d8ae3 100644
--- a/lxd-agent/exec.go
+++ b/lxd-agent/exec.go
@@ -20,6 +20,7 @@ import (
"github.com/lxc/lxd/lxd/response"
"github.com/lxc/lxd/shared"
"github.com/lxc/lxd/shared/api"
+ "github.com/lxc/lxd/shared/logger"
"github.com/lxc/lxd/shared/netutils"
)
@@ -263,7 +264,7 @@ func (s *execWs) Do(op *operations.Operation) error {
}
if err != nil {
- log.Printf("Got error getting next reader %s", err)
+ logger.Debugf("Got error getting next reader %s", err)
er, ok := err.(*websocket.CloseError)
if !ok {
break
@@ -276,30 +277,30 @@ func (s *execWs) Do(op *operations.Operation) error {
// If an abnormal closure occurred, kill the attached process.
err := unix.Kill(attachedChildPid, unix.SIGKILL)
if err != nil {
- log.Printf("Failed to send SIGKILL to pid %d\n", attachedChildPid)
+ logger.Errorf("Failed to send SIGKILL to pid %d\n", attachedChildPid)
} else {
- log.Printf("Sent SIGKILL to pid %d\n", attachedChildPid)
+ logger.Infof("Sent SIGKILL to pid %d\n", attachedChildPid)
}
return
}
buf, err := ioutil.ReadAll(r)
if err != nil {
- log.Printf("Failed to read message %s\n", err)
+ logger.Errorf("Failed to read message %s\n", err)
break
}
command := api.ContainerExecControl{}
if err := json.Unmarshal(buf, &command); err != nil {
- log.Printf("Failed to unmarshal control socket command: %s\n", err)
+ logger.Errorf("Failed to unmarshal control socket command: %s\n", err)
continue
}
if command.Command == "window-resize" {
winchWidth, err := strconv.Atoi(command.Args["width"])
if err != nil {
- log.Printf("Unable to extract window width: %s\n", err)
+ logger.Errorf("Unable to extract window width: %s\n", err)
continue
}
@@ -329,12 +330,12 @@ func (s *execWs) Do(op *operations.Operation) error {
conn := s.conns[0]
s.connsLock.Unlock()
- log.Println("Starting to mirror websocket")
+ logger.Info("Starting to mirror websocket")
readDone, writeDone := netutils.WebsocketExecMirror(conn, ptys[0], ptys[0], attachedChildIsDead, int(ptys[0].Fd()))
<-readDone
<-writeDone
- log.Println("Finished to mirror websocket")
+ logger.Info("Finished to mirror websocket")
conn.Close()
wgEOF.Done()
From 35dbf3eca5339ab2df1918331afa96b6fee5dff8 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Mon, 11 Nov 2019 12:30:23 +0000
Subject: [PATCH 3/5] lxd-agent: Setup proper logger
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd-agent/main.go | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/lxd-agent/main.go b/lxd-agent/main.go
index f3f28b13da..170c26cd33 100644
--- a/lxd-agent/main.go
+++ b/lxd-agent/main.go
@@ -5,6 +5,9 @@ import (
"github.com/spf13/cobra"
+ "github.com/lxc/lxd/lxd/events"
+ "github.com/lxc/lxd/shared/logger"
+ "github.com/lxc/lxd/shared/logging"
"github.com/lxc/lxd/shared/version"
)
@@ -35,8 +38,15 @@ func main() {
app.SetVersionTemplate("{{.Version}}\n")
app.Version = version.Version
+ // Setup logger
+ log, err := logging.GetLogger("", "", globalCmd.flagLogDebug, globalCmd.flagLogDebug, events.NewEventHandler())
+ if err != nil {
+ os.Exit(1)
+ }
+ logger.Log = log
+
// Run the main command and handle errors
- err := app.Execute()
+ err = app.Execute()
if err != nil {
os.Exit(1)
}
From 4c80875e98ca61504e84502466208de091e85571 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Mon, 11 Nov 2019 12:30:41 +0000
Subject: [PATCH 4/5] lxd/container/exec: Don't require cmd to be returned from
inst.Exec()
This isn't needed when using lxd-agent.
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/container_exec.go | 27 +++++++++++++++------------
1 file changed, 15 insertions(+), 12 deletions(-)
diff --git a/lxd/container_exec.go b/lxd/container_exec.go
index b8e2622590..1459cf1b25 100644
--- a/lxd/container_exec.go
+++ b/lxd/container_exec.go
@@ -322,22 +322,25 @@ func (s *execWs) Do(op *operations.Operation) error {
attachedChildIsBorn <- attachedPid
}
- err = cmd.Wait()
- if err == nil {
- return finisher(0, nil)
- }
+ if cmd != nil {
+ err = cmd.Wait()
+ if err == nil {
+ return finisher(0, nil)
+ }
- exitErr, ok := err.(*exec.ExitError)
- if ok {
- status, ok := exitErr.Sys().(syscall.WaitStatus)
+ exitErr, ok := err.(*exec.ExitError)
if ok {
- return finisher(status.ExitStatus(), nil)
- }
+ status, ok := exitErr.Sys().(syscall.WaitStatus)
+ if ok {
+ return finisher(status.ExitStatus(), nil)
+ }
- if status.Signaled() {
- // 128 + n == Fatal error signal "n"
- return finisher(128+int(status.Signal()), nil)
+ if status.Signaled() {
+ // 128 + n == Fatal error signal "n"
+ return finisher(128+int(status.Signal()), nil)
+ }
}
+
}
return finisher(-1, nil)
From 3120be9ee0de52285b2f824b7d5a7f95c29ffa55 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Mon, 11 Nov 2019 12:31:07 +0000
Subject: [PATCH 5/5] lxd-agent/exec: Add buffered channel to prevent deadlock
on cmd exit
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd-agent/exec.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lxd-agent/exec.go b/lxd-agent/exec.go
index 562f6d8ae3..946f0ba657 100644
--- a/lxd-agent/exec.go
+++ b/lxd-agent/exec.go
@@ -236,7 +236,7 @@ func (s *execWs) Do(op *operations.Operation) error {
stderr = ttys[2]
}
- controlExit := make(chan bool)
+ controlExit := make(chan bool, 1)
attachedChildIsBorn := make(chan int)
attachedChildIsDead := make(chan bool, 1)
var wgEOF sync.WaitGroup
More information about the lxc-devel
mailing list