The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/5940
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) ===
From 56bddfc7868af7ee2030dd0b7e2eeb665beb2fd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgra...@ubuntu.com> Date: Thu, 11 Jul 2019 11:33:35 -0400 Subject: [PATCH 1/2] shared: Better handle stdout/stderr in RunCommand MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stéphane Graber <stgra...@ubuntu.com> --- shared/util.go | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/shared/util.go b/shared/util.go index d833d4e7f4..da6bd619cd 100644 --- a/shared/util.go +++ b/shared/util.go @@ -765,25 +765,41 @@ func RemoveDuplicatesFromString(s string, sep string) string { } type RunError struct { - msg string - Err error + msg string + Err error + Stdout string + Stderr string } func (e RunError) Error() string { return e.msg } -func RunCommand(name string, arg ...string) (string, error) { - output, err := exec.Command(name, arg...).CombinedOutput() +func RunCommandSplit(name string, arg ...string) (string, string, error) { + cmd := exec.Command(name, arg...) + + var stdout bytes.Buffer + var stderr bytes.Buffer + cmd.Stdout = &stdout + cmd.Stderr = &stderr + + err := cmd.Run() if err != nil { err := RunError{ - msg: fmt.Sprintf("Failed to run: %s %s: %s", name, strings.Join(arg, " "), strings.TrimSpace(string(output))), - Err: err, + msg: fmt.Sprintf("Failed to run: %s %s: %s", name, strings.Join(arg, " "), strings.TrimSpace(string(stderr.Bytes()))), + Stdout: string(stdout.Bytes()), + Stderr: string(stderr.Bytes()), + Err: err, } - return string(output), err + return string(stdout.Bytes()), string(stderr.Bytes()), err } - return string(output), nil + return string(stdout.Bytes()), string(stderr.Bytes()), nil +} + +func RunCommand(name string, arg ...string) (string, error) { + stdout, _, err := RunCommandSplit(name, arg...) + return stdout, err } func RunCommandWithFds(stdin io.Reader, stdout io.Writer, name string, arg ...string) error { From 9ecce230607eb7920ad5e3f13086e50c8b18d6d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgra...@ubuntu.com> Date: Thu, 11 Jul 2019 12:27:44 -0400 Subject: [PATCH 2/2] lxd: Use RunCommandSplit when needed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stéphane Graber <stgra...@ubuntu.com> --- lxd/container_lxc.go | 64 +++++++++++++------------------------------- lxd/seccomp.go | 4 +-- 2 files changed, 20 insertions(+), 48 deletions(-) diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go index 9f9f506189..934050cbef 100644 --- a/lxd/container_lxc.go +++ b/lxd/container_lxc.go @@ -2732,7 +2732,7 @@ func (c *containerLXC) detachInterfaceRename(netns string, ifName string, hostNa lxdPID := os.Getpid() // Run forknet detach - out, err := shared.RunCommand( + _, err := shared.RunCommand( c.state.OS.ExecPath, "forknet", "detach", @@ -2744,7 +2744,7 @@ func (c *containerLXC) detachInterfaceRename(netns string, ifName string, hostNa // Process forknet detach response if err != nil { - logger.Error("Error calling 'lxd forknet detach", log.Ctx{"container": c.name, "output": out, "netns": netns, "ifName": ifName, "hostName": hostName, "pid": lxdPID}) + logger.Error("Error calling 'lxd forknet detach", log.Ctx{"container": c.name, "err": err, "netns": netns, "ifName": ifName, "hostName": hostName, "pid": lxdPID}) } return nil @@ -3173,20 +3173,12 @@ func (c *containerLXC) Start(stateful bool) error { name := projectPrefix(c.Project(), c.name) // Start the LXC container - out, err := shared.RunCommand( + _, err = shared.RunCommand( c.state.OS.ExecPath, "forkstart", name, c.state.OS.LxcPath, configPath) - - // Capture debug output - if out != "" { - for _, line := range strings.Split(strings.TrimRight(out, "\n"), "\n") { - logger.Debugf("forkstart: %s", line) - } - } - if err != nil && !c.IsRunning() { // Attempt to extract the LXC errors lxcLog := "" @@ -6328,8 +6320,7 @@ func (c *containerLXC) Migrate(args *CriuMigrationArgs) error { finalStateDir = fmt.Sprintf("%s/%s", args.stateDir, args.dumpDir) } - var out string - out, migrateErr = shared.RunCommand( + _, migrateErr = shared.RunCommand( c.state.OS.ExecPath, "forkmigrate", c.name, @@ -6338,12 +6329,6 @@ func (c *containerLXC) Migrate(args *CriuMigrationArgs) error { finalStateDir, fmt.Sprintf("%v", preservesInodes)) - if out != "" { - for _, line := range strings.Split(strings.TrimRight(out, "\n"), "\n") { - logger.Debugf("forkmigrate: %s", line) - } - } - if migrateErr == nil { // Start proxy devices err = c.restartProxyDevices() @@ -6599,7 +6584,7 @@ func (c *containerLXC) FileExists(path string) error { } // Check if the file exists in the container - out, err := shared.RunCommand( + _, stderr, err := shared.RunCommandSplit( c.state.OS.ExecPath, "forkfile", "exists", @@ -6617,12 +6602,12 @@ func (c *containerLXC) FileExists(path string) error { } // Process forkcheckfile response - if out != "" { - if strings.HasPrefix(out, "error:") { - return fmt.Errorf(strings.TrimPrefix(strings.TrimSuffix(out, "\n"), "error: ")) + if stderr != "" { + if strings.HasPrefix(stderr, "error:") { + return fmt.Errorf(strings.TrimPrefix(strings.TrimSuffix(stderr, "\n"), "error: ")) } - for _, line := range strings.Split(strings.TrimRight(out, "\n"), "\n") { + for _, line := range strings.Split(strings.TrimRight(stderr, "\n"), "\n") { logger.Debugf("forkcheckfile: %s", line) } } @@ -6646,7 +6631,7 @@ func (c *containerLXC) FilePull(srcpath string, dstpath string) (int64, int64, o } // Get the file from the container - out, err := shared.RunCommand( + _, stderr, err := shared.RunCommandSplit( c.state.OS.ExecPath, "forkfile", "pull", @@ -6672,7 +6657,7 @@ func (c *containerLXC) FilePull(srcpath string, dstpath string) (int64, int64, o var errStr string // Process forkgetfile response - for _, line := range strings.Split(strings.TrimRight(out, "\n"), "\n") { + for _, line := range strings.Split(strings.TrimRight(stderr, "\n"), "\n") { if line == "" { continue } @@ -6790,7 +6775,7 @@ func (c *containerLXC) FilePush(type_ string, srcpath string, dstpath string, ui } // Push the file to the container - out, err := shared.RunCommand( + _, stderr, err := shared.RunCommandSplit( c.state.OS.ExecPath, "forkfile", "push", @@ -6817,7 +6802,7 @@ func (c *containerLXC) FilePush(type_ string, srcpath string, dstpath string, ui } // Process forkgetfile response - for _, line := range strings.Split(strings.TrimRight(out, "\n"), "\n") { + for _, line := range strings.Split(strings.TrimRight(stderr, "\n"), "\n") { if line == "" { continue } @@ -6859,7 +6844,7 @@ func (c *containerLXC) FileRemove(path string) error { } // Remove the file from the container - out, err := shared.RunCommand( + _, stderr, err := shared.RunCommandSplit( c.state.OS.ExecPath, "forkfile", "remove", @@ -6877,7 +6862,7 @@ func (c *containerLXC) FileRemove(path string) error { } // Process forkremovefile response - for _, line := range strings.Split(strings.TrimRight(out, "\n"), "\n") { + for _, line := range strings.Split(strings.TrimRight(stderr, "\n"), "\n") { if line == "" { continue } @@ -7169,7 +7154,7 @@ func (c *containerLXC) networkState() map[string]api.ContainerStateNetwork { // Process forkgetnet response if err != nil { - logger.Error("Error calling 'lxd forkgetnet", log.Ctx{"container": c.name, "output": out, "pid": pid}) + logger.Error("Error calling 'lxd forkgetnet", log.Ctx{"container": c.name, "err": err, "pid": pid}) return result } @@ -7344,13 +7329,7 @@ func (c *containerLXC) insertMountLXD(source, target, fstype string, flags int, mntsrc := filepath.Join("/dev/.lxd-mounts", filepath.Base(tmpMount)) pidStr := fmt.Sprintf("%d", pid) - out, err := shared.RunCommand(c.state.OS.ExecPath, "forkmount", "lxd-mount", pidStr, mntsrc, target) - - if out != "" { - for _, line := range strings.Split(strings.TrimRight(out, "\n"), "\n") { - logger.Debugf("forkmount: %s", line) - } - } + _, err = shared.RunCommand(c.state.OS.ExecPath, "forkmount", "lxd-mount", pidStr, mntsrc, target) if err != nil { return err } @@ -7408,14 +7387,7 @@ func (c *containerLXC) removeMount(mount string) error { } else { // Remove the mount from the container pidStr := fmt.Sprintf("%d", pid) - out, err := shared.RunCommand(c.state.OS.ExecPath, "forkmount", "lxd-umount", pidStr, mount) - - if out != "" { - for _, line := range strings.Split(strings.TrimRight(out, "\n"), "\n") { - logger.Debugf("forkumount: %s", line) - } - } - + _, err := shared.RunCommand(c.state.OS.ExecPath, "forkmount", "lxd-umount", pidStr, mount) if err != nil { return err } diff --git a/lxd/seccomp.go b/lxd/seccomp.go index 6e5a497e17..3654ecb5e8 100644 --- a/lxd/seccomp.go +++ b/lxd/seccomp.go @@ -793,12 +793,12 @@ func (s *SeccompServer) doMknod(c container, dev types.Device, requestPID int) ( prefixPath = strings.TrimPrefix(prefixPath, rootPath) dev["hostpath"] = filepath.Join(c.RootfsPath(), rootPath, prefixPath, dev["path"]) - errnoMsg, err := shared.RunCommand(util.GetExecPath(), + _, stderr, err := shared.RunCommandSplit(util.GetExecPath(), "forkmknod", dev["pid"], dev["path"], dev["mode_t"], dev["dev_t"], dev["hostpath"], fmt.Sprintf("%d", uid), fmt.Sprintf("%d", gid)) if err != nil { - tmp, err2 := strconv.Atoi(errnoMsg) + tmp, err2 := strconv.Atoi(stderr) if err2 == nil { goErrno = -tmp }
_______________________________________________ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel