[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