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

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) ===
Fixes #6109

- Checks error response from `dnsmasq.GetVersion()`.
- Updates `dnsmasq.GetVersion()` to use the new `shared.RunCommandCLocale()` which runs the `dnsmasq --version` command with a `LANG=C.UTF-8` environment variable to avoid issues when the user is using a different locale that affects version string comparison.
- Updates `shared.RunCommandSplit()` to accept and optional environment variable slice to replace the current environment.
From ae56266e6b4a22c2b6873f7d244e5b729349fac3 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Thu, 22 Aug 2019 10:14:05 +0100
Subject: [PATCH 1/5] container/lxc: Updates use of shared.RunCommandSplit

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/container_lxc.go | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index 6df108d6b5..95397799eb 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -5968,6 +5968,7 @@ func (c *containerLXC) FileExists(path string) error {
 
        // Check if the file exists in the container
        _, stderr, err := shared.RunCommandSplit(
+               nil,
                c.state.OS.ExecPath,
                "forkfile",
                "exists",
@@ -6015,6 +6016,7 @@ func (c *containerLXC) FilePull(srcpath string, dstpath 
string) (int64, int64, o
 
        // Get the file from the container
        _, stderr, err := shared.RunCommandSplit(
+               nil,
                c.state.OS.ExecPath,
                "forkfile",
                "pull",
@@ -6159,6 +6161,7 @@ func (c *containerLXC) FilePush(type_ string, srcpath 
string, dstpath string, ui
 
        // Push the file to the container
        _, stderr, err := shared.RunCommandSplit(
+               nil,
                c.state.OS.ExecPath,
                "forkfile",
                "push",
@@ -6228,6 +6231,7 @@ func (c *containerLXC) FileRemove(path string) error {
 
        // Remove the file from the container
        _, stderr, err := shared.RunCommandSplit(
+               nil,
                c.state.OS.ExecPath,
                "forkfile",
                "remove",

From 0d6181e6fb16dcd90399bf79bd99c541ca4a9c28 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Thu, 22 Aug 2019 10:15:21 +0100
Subject: [PATCH 2/5] dnsmasq/dnsmasq: Updates version check to use
 shared.RunCommandCLocale

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/dnsmasq/dnsmasq.go | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/lxd/dnsmasq/dnsmasq.go b/lxd/dnsmasq/dnsmasq.go
index b173bba61e..b72dd92966 100644
--- a/lxd/dnsmasq/dnsmasq.go
+++ b/lxd/dnsmasq/dnsmasq.go
@@ -6,7 +6,6 @@ import (
        "io/ioutil"
        "net"
        "os"
-       "os/exec"
        "path/filepath"
        "strconv"
        "strings"
@@ -155,8 +154,7 @@ func Kill(name string, reload bool) error {
 
 // GetVersion returns the version of dnsmasq.
 func GetVersion() (*version.DottedVersion, error) {
-       // Discard stderr on purpose (occasional linker errors)
-       output, err := exec.Command("dnsmasq", "--version").Output()
+       output, err := shared.RunCommandCLocale("dnsmasq", "--version")
        if err != nil {
                return nil, fmt.Errorf("Failed to check dnsmasq version: %v", 
err)
        }

From d4821614048d508ef839f0efa336576f2797f795 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Thu, 22 Aug 2019 10:16:15 +0100
Subject: [PATCH 3/5] networks: Handles error from dnsmasq version check

Fixes #6109

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/networks.go | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/lxd/networks.go b/lxd/networks.go
index 9fa46146c5..c8cd30d736 100644
--- a/lxd/networks.go
+++ b/lxd/networks.go
@@ -1292,6 +1292,9 @@ func (n *network) Start() error {
                fmt.Sprintf("--interface=%s", n.name)}
 
        dnsmasqVersion, err := dnsmasq.GetVersion()
+       if err != nil {
+               return err
+       }
 
        // --dhcp-rapid-commit option is only supported on >2.79
        minVer, _ := version.NewDottedVersion("2.79")

From 85023db6858bcb68b0983e08b4e321c436aba010 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Thu, 22 Aug 2019 10:17:03 +0100
Subject: [PATCH 4/5] seccomp: Updates use of shared.RunCommandSplit

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/seccomp.go | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lxd/seccomp.go b/lxd/seccomp.go
index c24332789a..05221cab9e 100644
--- a/lxd/seccomp.go
+++ b/lxd/seccomp.go
@@ -826,7 +826,7 @@ func CallForkmknod(c container, dev config.Device, 
requestPID int) int {
                dev["hostpath"] = filepath.Join(c.RootfsPath(), rootPath, 
dev["path"])
        }
 
-       _, stderr, err := shared.RunCommandSplit(util.GetExecPath(),
+       _, stderr, err := shared.RunCommandSplit(nil, util.GetExecPath(),
                "forksyscall", "mknod", dev["pid"], dev["path"],
                dev["mode_t"], dev["dev_t"], dev["hostpath"],
                fmt.Sprintf("%d", uid), fmt.Sprintf("%d", gid),
@@ -1030,7 +1030,7 @@ func (s *SeccompServer) HandleSetxattrSyscall(c 
container, siov *SeccompIovec) i
                whiteout = 1
        }
 
-       _, stderr, err := shared.RunCommandSplit(util.GetExecPath(),
+       _, stderr, err := shared.RunCommandSplit(nil, util.GetExecPath(),
                "forksyscall",
                "setxattr",
                fmt.Sprintf("%d", args.pid),

From 894206eed303070967ca2aab74caea06acd7bb31 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Thu, 22 Aug 2019 10:17:26 +0100
Subject: [PATCH 5/5] shared/util: Adds RunCommandCLocale() and updates
 RunCommandSplit() to accept env vars

RunCommandCLocale() calls RunCommandSplit() with an appended environment var of 
using LANG=C.UTF-8 to avoid issues when comparing dnsmasq version numbers in 
non-english locales.

Fixes #6109

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 shared/util.go | 22 ++++++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/shared/util.go b/shared/util.go
index a861be1647..ed38696132 100644
--- a/shared/util.go
+++ b/shared/util.go
@@ -793,9 +793,17 @@ func (e RunError) Error() string {
        return e.msg
 }
 
-func RunCommandSplit(name string, arg ...string) (string, string, error) {
+// RunCommandSplit runs a command with a supplied environment and optional 
arguments and returns the
+// resulting stdout and stderr output as separate variables. If the supplied 
environment is nil then
+// the default environment is used. If the command fails to start or returns a 
non-zero exit code
+// then an error is returned containing the output of stderr too.
+func RunCommandSplit(env []string, name string, arg ...string) (string, 
string, error) {
        cmd := exec.Command(name, arg...)
 
+       if env != nil {
+               cmd.Env = env
+       }
+
        var stdout bytes.Buffer
        var stderr bytes.Buffer
        cmd.Stdout = &stdout
@@ -815,8 +823,18 @@ func RunCommandSplit(name string, arg ...string) (string, 
string, error) {
        return string(stdout.Bytes()), string(stderr.Bytes()), nil
 }
 
+// RunCommand runs a command with optional arguments and returns stdout. If 
the command fails to
+// start or returns a non-zero exit code then an error is returned containing 
the output of stderr.
 func RunCommand(name string, arg ...string) (string, error) {
-       stdout, _, err := RunCommandSplit(name, arg...)
+       stdout, _, err := RunCommandSplit(nil, name, arg...)
+       return stdout, err
+}
+
+// RunCommandCLocale runs a command with a LANG=C.UTF-8 environment set with 
optional arguments and
+// returns stdout. If the command fails to start or returns a non-zero exit 
code then an error is
+// returned containing the output of stderr.
+func RunCommandCLocale(name string, arg ...string) (string, error) {
+       stdout, _, err := RunCommandSplit(append(os.Environ(), "LANG=C.UTF-8"), 
name, arg...)
        return stdout, err
 }
 
_______________________________________________
lxc-devel mailing list
lxc-devel@lists.linuxcontainers.org
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to