The following pull request was submitted through Github.
It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/6436

This e-mail was sent by the LXC bot, direct replies will not reach the author
unless they happen to be subscribed to this list.

=== Description (from pull-request) ===
Adds support for `lxc exec` for VMs via `lxd-agent`.

This is a WIP.
From e50caecd0d2a48a351446778ea68020789f18ff7 Mon Sep 17 00:00:00 2001
From: Thomas Hipp <thomas.h...@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.h...@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.parr...@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.parr...@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.parr...@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.parr...@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.parr...@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.parr...@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.parr...@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.parr...@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
_______________________________________________
lxc-devel mailing list
lxc-devel@lists.linuxcontainers.org
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to