[lxc-devel] [lxd/master] dnsmasq version parsing

stgraber on Github lxc-bot at linuxcontainers.org
Tue Sep 19 17:31:00 UTC 2017


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 301 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20170919/12839c43/attachment.bin>
-------------- next part --------------
From 9cb022f80613b5840a45ca910fab7f9129972d3c Mon Sep 17 00:00:00 2001
From: Alberto Donato <alberto.donato at canonical.com>
Date: Mon, 18 Sep 2017 09:50:14 +0200
Subject: [PATCH 1/2] network: only add --quiet-* options to dnsmasq if version
 supports them

Signed-off-by: Alberto Donato <alberto.donato at canonical.com>
---
 lxd/networks.go       | 10 +++++++++-
 lxd/networks_utils.go | 10 ++++++++++
 2 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/lxd/networks.go b/lxd/networks.go
index 939869556..007706cb7 100644
--- a/lxd/networks.go
+++ b/lxd/networks.go
@@ -778,7 +778,15 @@ func (n *network) Start() error {
 		fmt.Sprintf("--interface=%s", n.name)}
 
 	if !debug {
-		dnsmasqCmd = append(dnsmasqCmd, []string{"--quiet-dhcp", "--quiet-dhcp6", "--quiet-ra"}...)
+		// --quiet options are only supported on >2.67
+		v, err := networkGetDnsmasqVersion()
+		if err != nil {
+			return err
+		}
+		minVer, _ := version.NewDottedVersion("2.67")
+		if v.Compare(minVer) > 0 {
+			dnsmasqCmd = append(dnsmasqCmd, []string{"--quiet-dhcp", "--quiet-dhcp6", "--quiet-ra"}...)
+		}
 	}
 
 	// Configure IPv4
diff --git a/lxd/networks_utils.go b/lxd/networks_utils.go
index 37ab63d83..5e6594231 100644
--- a/lxd/networks_utils.go
+++ b/lxd/networks_utils.go
@@ -24,6 +24,7 @@ import (
 	"github.com/lxc/lxd/lxd/state"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/logger"
+	"github.com/lxc/lxd/shared/version"
 )
 
 var networkStaticLock sync.Mutex
@@ -727,6 +728,15 @@ func networkKillDnsmasq(name string, reload bool) error {
 	return nil
 }
 
+func networkGetDnsmasqVersion() (*version.DottedVersion, error) {
+	output, err := shared.TryRunCommand("dnsmasq", "--version")
+	if err != nil {
+		return nil, fmt.Errorf("Failed to check dnsmasq version")
+	}
+	lines := strings.Split(output, " ")
+	return version.NewDottedVersion(lines[2])
+}
+
 func networkUpdateStatic(s *state.State, networkName string) error {
 	// We don't want to race with ourselves here
 	networkStaticLock.Lock()

From f71426436dda81e7c811b88419ab970b967e5784 Mon Sep 17 00:00:00 2001
From: Alberto Donato <alberto.donato at canonical.com>
Date: Tue, 19 Sep 2017 09:32:25 +0200
Subject: [PATCH 2/2] shared: add helpers to parse/compare versions

Signed-off-by: Alberto Donato <alberto.donato at canonical.com>
---
 shared/version/version.go      | 91 +++++++++++++++++++++++++++++++++++++++++
 shared/version/version_test.go | 93 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 184 insertions(+)
 create mode 100644 shared/version/version.go
 create mode 100644 shared/version/version_test.go

diff --git a/shared/version/version.go b/shared/version/version.go
new file mode 100644
index 000000000..51ac6715f
--- /dev/null
+++ b/shared/version/version.go
@@ -0,0 +1,91 @@
+package version
+
+import (
+	"fmt"
+	"regexp"
+	"strconv"
+	"strings"
+)
+
+// DottedVersion holds element of a version in the maj.min[.patch] format.
+type DottedVersion struct {
+	Major int
+	Minor int
+	Patch int
+}
+
+// NewDottedVersion returns a new Version.
+func NewDottedVersion(versionString string) (*DottedVersion, error) {
+	formatError := fmt.Errorf("Invalid version format: %s", versionString)
+	split := strings.Split(versionString, ".")
+	if len(split) < 2 {
+		return nil, formatError
+	}
+
+	maj, err := strconv.Atoi(split[0])
+	if err != nil {
+		return nil, formatError
+	}
+
+	min, err := strconv.Atoi(split[1])
+	if err != nil {
+		return nil, formatError
+	}
+
+	patch := -1
+	if len(split) == 3 {
+		patch, err = strconv.Atoi(split[2])
+		if err != nil {
+			return nil, formatError
+		}
+	}
+
+	return &DottedVersion{
+		Major: maj,
+		Minor: min,
+		Patch: patch,
+	}, nil
+}
+
+// Parse parses a string starting with a dotted version and returns it.
+func Parse(s string) (*DottedVersion, error) {
+	r, _ := regexp.Compile(`^([0-9]+.[0-9]+(.[0-9]+))?.*`)
+	matches := r.FindAllStringSubmatch(s, -1)
+	if len(matches[0]) < 2 {
+		return nil, fmt.Errorf("Can't parse a version")
+	}
+	return NewDottedVersion(matches[0][1])
+}
+
+// String returns version as a string
+func (v *DottedVersion) String() string {
+	version := fmt.Sprintf("%d.%d", v.Major, v.Minor)
+	if v.Patch != -1 {
+		version += fmt.Sprintf(".%d", v.Patch)
+	}
+	return version
+}
+
+// Compare returns result of comparison between two versions
+func (v *DottedVersion) Compare(other *DottedVersion) int {
+	result := compareInts(v.Major, other.Major)
+	if result != 0 {
+		return result
+	}
+	result = compareInts(v.Minor, other.Minor)
+	if result != 0 {
+		return result
+	}
+	return compareInts(v.Patch, other.Patch)
+}
+
+func compareInts(i1 int, i2 int) int {
+	switch {
+	case i1 < i2:
+		return -1
+	case i1 > i2:
+		return 1
+	default:
+		return 0
+	}
+}
diff --git a/shared/version/version_test.go b/shared/version/version_test.go
new file mode 100644
index 000000000..8c6c2c24d
--- /dev/null
+++ b/shared/version/version_test.go
@@ -0,0 +1,93 @@
+package version
+
+import (
+	"testing"
+
+	"github.com/stretchr/testify/suite"
+)
+
+type versionTestSuite struct {
+	suite.Suite
+}
+
+func TestVersionTestSuite(t *testing.T) {
+	suite.Run(t, new(versionTestSuite))
+}
+
+func (s *versionTestSuite) TestNewVersion() {
+	v, err := NewDottedVersion("1.2.3")
+	s.Nil(err)
+	s.Equal(1, v.Major)
+	s.Equal(2, v.Minor)
+	s.Equal(3, v.Patch)
+}
+
+func (s *versionTestSuite) TestNewVersionNoPatch() {
+	v, err := NewDottedVersion("1.2")
+	s.Nil(err)
+	s.Equal(-1, v.Patch)
+}
+
+func (s *versionTestSuite) TestNewVersionInvalid() {
+	v, err := NewDottedVersion("1.nope")
+	s.Nil(v)
+	s.NotNil(err)
+}
+
+func (s *versionTestSuite) TestParseDashes() {
+	v, err := Parse("1.2.3-asdf")
+	s.Nil(err)
+	s.Equal(1, v.Major)
+	s.Equal(2, v.Minor)
+	s.Equal(3, v.Patch)
+}
+
+func (s *versionTestSuite) TestParseParentheses() {
+	v, err := Parse("1.2.3(beta1)")
+	s.Nil(err)
+	s.Equal(1, v.Major)
+	s.Equal(2, v.Minor)
+	s.Equal(3, v.Patch)
+}
+
+func (s *versionTestSuite) TestParseFail() {
+	v, err := Parse("asdfaf")
+	s.Nil(v)
+	s.NotNil(err)
+}
+
+func (s *versionTestSuite) TestString() {
+	v, _ := NewDottedVersion("1.2.3")
+	s.Equal("1.2.3", v.String())
+}
+
+func (s *versionTestSuite) TestCompareEqual() {
+	v1, _ := NewDottedVersion("1.2.3")
+	v2, _ := NewDottedVersion("1.2.3")
+	s.Equal(0, v1.Compare(v2))
+	s.Equal(0, v2.Compare(v1))
+	v3, _ := NewDottedVersion("1.2")
+	v4, _ := NewDottedVersion("1.2")
+	s.Equal(0, v3.Compare(v4))
+	s.Equal(0, v4.Compare(v3))
+}
+
+func (s *versionTestSuite) TestCompareOlder() {
+	v1, _ := NewDottedVersion("1.2.3")
+	v2, _ := NewDottedVersion("1.2.4")
+	v3, _ := NewDottedVersion("1.3")
+	v4, _ := NewDottedVersion("2.2.3")
+	s.Equal(-1, v1.Compare(v2))
+	s.Equal(-1, v1.Compare(v3))
+	s.Equal(-1, v1.Compare(v4))
+}
+
+func (s *versionTestSuite) TestCompareNewer() {
+	v1, _ := NewDottedVersion("1.2.3")
+	v2, _ := NewDottedVersion("1.2.2")
+	v3, _ := NewDottedVersion("1.1")
+	v4, _ := NewDottedVersion("0.3.3")
+	s.Equal(1, v1.Compare(v2))
+	s.Equal(1, v1.Compare(v3))
+	s.Equal(1, v1.Compare(v4))
+}


More information about the lxc-devel mailing list