Browse code

Move parsing functions to pkg/parsers and the specific kernel handling functions to pkg/parsers/kernel, and parsing filters to pkg/parsers/filter. Adjust imports and package references.

Docker-DCO-1.1-Signed-off-by: Erik Hollensbe <github@hollensbe.org> (github: erikh)

Erik Hollensbe authored on 2014/07/29 09:23:38
Showing 32 changed files
... ...
@@ -28,13 +28,14 @@ import (
28 28
 	"github.com/docker/docker/engine"
29 29
 	"github.com/docker/docker/nat"
30 30
 	"github.com/docker/docker/opts"
31
+	"github.com/docker/docker/pkg/parsers"
32
+	"github.com/docker/docker/pkg/parsers/filters"
31 33
 	"github.com/docker/docker/pkg/signal"
32 34
 	"github.com/docker/docker/pkg/term"
33 35
 	"github.com/docker/docker/pkg/units"
34 36
 	"github.com/docker/docker/registry"
35 37
 	"github.com/docker/docker/runconfig"
36 38
 	"github.com/docker/docker/utils"
37
-	"github.com/docker/docker/utils/filters"
38 39
 )
39 40
 
40 41
 const (
... ...
@@ -204,7 +205,7 @@ func (cli *DockerCli) CmdBuild(args ...string) error {
204 204
 
205 205
 	//Check if the given image name can be resolved
206 206
 	if *tag != "" {
207
-		repository, _ := utils.ParseRepositoryTag(*tag)
207
+		repository, _ := parsers.ParseRepositoryTag(*tag)
208 208
 		if _, _, err := registry.ResolveRepositoryName(repository); err != nil {
209 209
 			return err
210 210
 		}
... ...
@@ -1137,7 +1138,7 @@ func (cli *DockerCli) CmdPush(args ...string) error {
1137 1137
 
1138 1138
 	cli.LoadConfigFile()
1139 1139
 
1140
-	remote, tag := utils.ParseRepositoryTag(name)
1140
+	remote, tag := parsers.ParseRepositoryTag(name)
1141 1141
 
1142 1142
 	// Resolve the Repository name from fqn to hostname + name
1143 1143
 	hostname, _, err := registry.ResolveRepositoryName(remote)
... ...
@@ -1210,7 +1211,7 @@ func (cli *DockerCli) CmdPull(args ...string) error {
1210 1210
 		v.Set("tag", *tag)
1211 1211
 	}
1212 1212
 
1213
-	remote, _ = utils.ParseRepositoryTag(remote)
1213
+	remote, _ = parsers.ParseRepositoryTag(remote)
1214 1214
 	// Resolve the Repository name from fqn to hostname + name
1215 1215
 	hostname, _, err := registry.ResolveRepositoryName(remote)
1216 1216
 	if err != nil {
... ...
@@ -1393,7 +1394,7 @@ func (cli *DockerCli) CmdImages(args ...string) error {
1393 1393
 		for _, out := range outs.Data {
1394 1394
 			for _, repotag := range out.GetList("RepoTags") {
1395 1395
 
1396
-				repo, tag := utils.ParseRepositoryTag(repotag)
1396
+				repo, tag := parsers.ParseRepositoryTag(repotag)
1397 1397
 				outID := out.Get("Id")
1398 1398
 				if !*noTrunc {
1399 1399
 					outID = utils.TruncateID(outID)
... ...
@@ -1594,7 +1595,7 @@ func (cli *DockerCli) CmdCommit(args ...string) error {
1594 1594
 
1595 1595
 	var (
1596 1596
 		name            = cmd.Arg(0)
1597
-		repository, tag = utils.ParseRepositoryTag(cmd.Arg(1))
1597
+		repository, tag = parsers.ParseRepositoryTag(cmd.Arg(1))
1598 1598
 	)
1599 1599
 
1600 1600
 	if name == "" || len(cmd.Args()) > 2 {
... ...
@@ -1918,7 +1919,7 @@ func (cli *DockerCli) CmdTag(args ...string) error {
1918 1918
 	}
1919 1919
 
1920 1920
 	var (
1921
-		repository, tag = utils.ParseRepositoryTag(cmd.Arg(1))
1921
+		repository, tag = parsers.ParseRepositoryTag(cmd.Arg(1))
1922 1922
 		v               = url.Values{}
1923 1923
 	)
1924 1924
 
... ...
@@ -1941,7 +1942,7 @@ func (cli *DockerCli) CmdTag(args ...string) error {
1941 1941
 
1942 1942
 func (cli *DockerCli) pullImage(image string) error {
1943 1943
 	v := url.Values{}
1944
-	repos, tag := utils.ParseRepositoryTag(image)
1944
+	repos, tag := parsers.ParseRepositoryTag(image)
1945 1945
 	// pull only the image tagged 'latest' if no tag was specified
1946 1946
 	if tag == "" {
1947 1947
 		tag = "latest"
... ...
@@ -6,6 +6,7 @@ import (
6 6
 	"strings"
7 7
 
8 8
 	"github.com/docker/docker/engine"
9
+	"github.com/docker/docker/pkg/parsers"
9 10
 	"github.com/docker/docker/pkg/version"
10 11
 	"github.com/docker/docker/utils"
11 12
 )
... ...
@@ -17,7 +18,7 @@ const (
17 17
 )
18 18
 
19 19
 func ValidateHost(val string) (string, error) {
20
-	host, err := utils.ParseHost(DEFAULTHTTPHOST, DEFAULTUNIXSOCKET, val)
20
+	host, err := parsers.ParseHost(DEFAULTHTTPHOST, DEFAULTUNIXSOCKET, val)
21 21
 	if err != nil {
22 22
 		return val, err
23 23
 	}
... ...
@@ -25,6 +25,7 @@ import (
25 25
 	"github.com/docker/docker/api"
26 26
 	"github.com/docker/docker/engine"
27 27
 	"github.com/docker/docker/pkg/listenbuffer"
28
+	"github.com/docker/docker/pkg/parsers"
28 29
 	"github.com/docker/docker/pkg/systemd"
29 30
 	"github.com/docker/docker/pkg/user"
30 31
 	"github.com/docker/docker/pkg/version"
... ...
@@ -484,7 +485,7 @@ func postImagesCreate(eng *engine.Engine, version version.Version, w http.Respon
484 484
 	}
485 485
 	if image != "" { //pull
486 486
 		if tag == "" {
487
-			image, tag = utils.ParseRepositoryTag(image)
487
+			image, tag = parsers.ParseRepositoryTag(image)
488 488
 		}
489 489
 		metaHeaders := map[string][]string{}
490 490
 		for k, v := range r.Header {
... ...
@@ -498,7 +499,7 @@ func postImagesCreate(eng *engine.Engine, version version.Version, w http.Respon
498 498
 		job.SetenvJson("authConfig", authConfig)
499 499
 	} else { //import
500 500
 		if tag == "" {
501
-			repo, tag = utils.ParseRepositoryTag(repo)
501
+			repo, tag = parsers.ParseRepositoryTag(repo)
502 502
 		}
503 503
 		job = eng.Job("import", r.Form.Get("fromSrc"), repo, tag)
504 504
 		job.Stdin.Add(r.Body)
... ...
@@ -23,6 +23,7 @@ import (
23 23
 	"github.com/docker/docker/daemon"
24 24
 	"github.com/docker/docker/engine"
25 25
 	"github.com/docker/docker/nat"
26
+	"github.com/docker/docker/pkg/parsers"
26 27
 	"github.com/docker/docker/pkg/symlink"
27 28
 	"github.com/docker/docker/pkg/system"
28 29
 	"github.com/docker/docker/registry"
... ...
@@ -86,7 +87,7 @@ func (b *buildFile) CmdFrom(name string) error {
86 86
 	image, err := b.daemon.Repositories().LookupImage(name)
87 87
 	if err != nil {
88 88
 		if b.daemon.Graph().IsNotExist(err) {
89
-			remote, tag := utils.ParseRepositoryTag(name)
89
+			remote, tag := parsers.ParseRepositoryTag(name)
90 90
 			pullRegistryAuth := b.authConfig
91 91
 			if len(b.configFile.Configs) > 0 {
92 92
 				// The request came with a full auth config file, we prefer to use that
... ...
@@ -8,9 +8,9 @@ import (
8 8
 	"github.com/docker/docker/daemon/networkdriver/bridge"
9 9
 	"github.com/docker/docker/dockerversion"
10 10
 	"github.com/docker/docker/engine"
11
+	"github.com/docker/docker/pkg/parsers/kernel"
11 12
 	"github.com/docker/docker/registry"
12 13
 	"github.com/docker/docker/server"
13
-	"github.com/docker/docker/utils"
14 14
 )
15 15
 
16 16
 func Register(eng *engine.Engine) error {
... ...
@@ -68,7 +68,7 @@ func dockerVersion(job *engine.Job) engine.Status {
68 68
 	v.Set("GoVersion", runtime.Version())
69 69
 	v.Set("Os", runtime.GOOS)
70 70
 	v.Set("Arch", runtime.GOARCH)
71
-	if kernelVersion, err := utils.GetKernelVersion(); err == nil {
71
+	if kernelVersion, err := kernel.GetKernelVersion(); err == nil {
72 72
 		v.Set("KernelVersion", kernelVersion.String())
73 73
 	}
74 74
 	if _, err := v.WriteTo(job.Stdout); err != nil {
... ...
@@ -28,6 +28,7 @@ import (
28 28
 	"github.com/docker/docker/pkg/graphdb"
29 29
 	"github.com/docker/docker/pkg/namesgenerator"
30 30
 	"github.com/docker/docker/pkg/networkfs/resolvconf"
31
+	"github.com/docker/docker/pkg/parsers"
31 32
 	"github.com/docker/docker/pkg/sysinfo"
32 33
 	"github.com/docker/docker/pkg/truncindex"
33 34
 	"github.com/docker/docker/runconfig"
... ...
@@ -724,7 +725,7 @@ func (daemon *Daemon) RegisterLink(parent, child *Container, alias string) error
724 724
 func (daemon *Daemon) RegisterLinks(container *Container, hostConfig *runconfig.HostConfig) error {
725 725
 	if hostConfig != nil && hostConfig.Links != nil {
726 726
 		for _, l := range hostConfig.Links {
727
-			parts, err := utils.PartParser("name:alias", l)
727
+			parts, err := parsers.PartParser("name:alias", l)
728 728
 			if err != nil {
729 729
 				return err
730 730
 			}
... ...
@@ -19,6 +19,7 @@ import (
19 19
 	"time"
20 20
 
21 21
 	"github.com/docker/docker/daemon/graphdriver"
22
+	"github.com/docker/docker/pkg/parsers"
22 23
 	"github.com/docker/docker/pkg/units"
23 24
 	"github.com/docker/docker/utils"
24 25
 	"github.com/docker/libcontainer/label"
... ...
@@ -1166,7 +1167,7 @@ func NewDeviceSet(root string, doInit bool, options []string) (*DeviceSet, error
1166 1166
 
1167 1167
 	foundBlkDiscard := false
1168 1168
 	for _, option := range options {
1169
-		key, val, err := utils.ParseKeyValueOpt(option)
1169
+		key, val, err := parsers.ParseKeyValueOpt(option)
1170 1170
 		if err != nil {
1171 1171
 			return nil, err
1172 1172
 		}
... ...
@@ -15,6 +15,7 @@ import (
15 15
 	"github.com/docker/docker/engine"
16 16
 	"github.com/docker/docker/pkg/iptables"
17 17
 	"github.com/docker/docker/pkg/networkfs/resolvconf"
18
+	"github.com/docker/docker/pkg/parsers/kernel"
18 19
 	"github.com/docker/docker/utils"
19 20
 	"github.com/docker/libcontainer/netlink"
20 21
 )
... ...
@@ -306,7 +307,7 @@ func createBridge(bridgeIP string) error {
306 306
 }
307 307
 
308 308
 func createBridgeIface(name string) error {
309
-	kv, err := utils.GetKernelVersion()
309
+	kv, err := kernel.GetKernelVersion()
310 310
 	// only set the bridge's mac address if the kernel version is > 3.3
311 311
 	// before that it was not supported
312 312
 	setBridgeMacAddr := err == nil && (kv.Kernel >= 3 && kv.Major >= 3)
... ...
@@ -19,6 +19,7 @@ import (
19 19
 	"github.com/docker/docker/engine"
20 20
 	"github.com/docker/docker/opts"
21 21
 	flag "github.com/docker/docker/pkg/mflag"
22
+	"github.com/docker/docker/pkg/parsers/kernel"
22 23
 	"github.com/docker/docker/sysinit"
23 24
 	"github.com/docker/docker/utils"
24 25
 )
... ...
@@ -292,10 +293,10 @@ func checkKernelAndArch() error {
292 292
 	// without actually causing a kernel panic, so we need this workaround until
293 293
 	// the circumstances of pre-3.8 crashes are clearer.
294 294
 	// For details see http://github.com/docker/docker/issues/407
295
-	if k, err := utils.GetKernelVersion(); err != nil {
295
+	if k, err := kernel.GetKernelVersion(); err != nil {
296 296
 		log.Printf("WARNING: %s\n", err)
297 297
 	} else {
298
-		if utils.CompareKernelVersion(k, &utils.KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0}) < 0 {
298
+		if kernel.CompareKernelVersion(k, &kernel.KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0}) < 0 {
299 299
 			if os.Getenv("DOCKER_NOWARN_KERNEL_VERSION") == "" {
300 300
 				log.Printf("WARNING: You are running linux kernel version %s, which might be unstable running docker. Please upgrade your kernel to 3.8.0.", k.String())
301 301
 			}
... ...
@@ -5,6 +5,7 @@ import (
5 5
 
6 6
 	"github.com/docker/docker/engine"
7 7
 	"github.com/docker/docker/image"
8
+	"github.com/docker/docker/pkg/parsers"
8 9
 	"github.com/docker/docker/utils"
9 10
 )
10 11
 
... ...
@@ -78,7 +79,7 @@ func (s *TagStore) CmdTag(job *engine.Job) engine.Status {
78 78
 		newName = job.Args[0]
79 79
 		oldName = job.Args[1]
80 80
 	)
81
-	newRepo, newTag := utils.ParseRepositoryTag(newName)
81
+	newRepo, newTag := parsers.ParseRepositoryTag(newName)
82 82
 	// FIXME: Set should either parse both old and new name, or neither.
83 83
 	// 	the current prototype is inconsistent.
84 84
 	if err := s.Set(newRepo, newTag, oldName, true); err != nil {
... ...
@@ -11,6 +11,7 @@ import (
11 11
 	"sync"
12 12
 
13 13
 	"github.com/docker/docker/image"
14
+	"github.com/docker/docker/pkg/parsers"
14 15
 	"github.com/docker/docker/utils"
15 16
 )
16 17
 
... ...
@@ -72,7 +73,7 @@ func (store *TagStore) reload() error {
72 72
 func (store *TagStore) LookupImage(name string) (*image.Image, error) {
73 73
 	// FIXME: standardize on returning nil when the image doesn't exist, and err for everything else
74 74
 	// (so we can pass all errors here)
75
-	repos, tag := utils.ParseRepositoryTag(name)
75
+	repos, tag := parsers.ParseRepositoryTag(name)
76 76
 	if tag == "" {
77 77
 		tag = DEFAULTTAG
78 78
 	}
... ...
@@ -8,7 +8,7 @@ import (
8 8
 	"strconv"
9 9
 	"strings"
10 10
 
11
-	"github.com/docker/docker/utils"
11
+	"github.com/docker/docker/pkg/parsers"
12 12
 )
13 13
 
14 14
 const (
... ...
@@ -103,7 +103,7 @@ func ParsePortSpecs(ports []string) (map[Port]struct{}, map[Port][]PortBinding,
103 103
 			rawPort = fmt.Sprintf(":%s", rawPort)
104 104
 		}
105 105
 
106
-		parts, err := utils.PartParser(PortSpecTemplate, rawPort)
106
+		parts, err := parsers.PartParser(PortSpecTemplate, rawPort)
107 107
 		if err != nil {
108 108
 			return nil, nil, err
109 109
 		}
... ...
@@ -8,7 +8,7 @@ import (
8 8
 	"regexp"
9 9
 	"strings"
10 10
 
11
-	"github.com/docker/docker/utils"
11
+	"github.com/docker/docker/pkg/parsers"
12 12
 )
13 13
 
14 14
 // ListOpts type
... ...
@@ -94,7 +94,7 @@ func ValidateAttach(val string) (string, error) {
94 94
 }
95 95
 
96 96
 func ValidateLink(val string) (string, error) {
97
-	if _, err := utils.PartParser("name:alias", val); err != nil {
97
+	if _, err := parsers.PartParser("name:alias", val); err != nil {
98 98
 		return val, err
99 99
 	}
100 100
 	return val, nil
101 101
new file mode 100644
... ...
@@ -0,0 +1 @@
0
+Erik Hollensbe <github@hollensbe.org> (@erikh)
0 1
new file mode 100644
... ...
@@ -0,0 +1,63 @@
0
+package filters
1
+
2
+import (
3
+	"encoding/json"
4
+	"errors"
5
+	"strings"
6
+)
7
+
8
+type Args map[string][]string
9
+
10
+// Parse the argument to the filter flag. Like
11
+//
12
+//   `docker ps -f 'created=today' -f 'image.name=ubuntu*'`
13
+//
14
+// If prev map is provided, then it is appended to, and returned. By default a new
15
+// map is created.
16
+func ParseFlag(arg string, prev Args) (Args, error) {
17
+	var filters Args = prev
18
+	if prev == nil {
19
+		filters = Args{}
20
+	}
21
+	if len(arg) == 0 {
22
+		return filters, nil
23
+	}
24
+
25
+	if !strings.Contains(arg, "=") {
26
+		return filters, ErrorBadFormat
27
+	}
28
+
29
+	f := strings.SplitN(arg, "=", 2)
30
+	filters[f[0]] = append(filters[f[0]], f[1])
31
+
32
+	return filters, nil
33
+}
34
+
35
+var ErrorBadFormat = errors.New("bad format of filter (expected name=value)")
36
+
37
+// packs the Args into an string for easy transport from client to server
38
+func ToParam(a Args) (string, error) {
39
+	// this way we don't URL encode {}, just empty space
40
+	if len(a) == 0 {
41
+		return "", nil
42
+	}
43
+
44
+	buf, err := json.Marshal(a)
45
+	if err != nil {
46
+		return "", err
47
+	}
48
+	return string(buf), nil
49
+}
50
+
51
+// unpacks the filter Args
52
+func FromParam(p string) (Args, error) {
53
+	args := Args{}
54
+	if len(p) == 0 {
55
+		return args, nil
56
+	}
57
+	err := json.Unmarshal([]byte(p), &args)
58
+	if err != nil {
59
+		return nil, err
60
+	}
61
+	return args, nil
62
+}
0 63
new file mode 100644
... ...
@@ -0,0 +1,78 @@
0
+package filters
1
+
2
+import (
3
+	"sort"
4
+	"testing"
5
+)
6
+
7
+func TestParseArgs(t *testing.T) {
8
+	// equivalent of `docker ps -f 'created=today' -f 'image.name=ubuntu*' -f 'image.name=*untu'`
9
+	flagArgs := []string{
10
+		"created=today",
11
+		"image.name=ubuntu*",
12
+		"image.name=*untu",
13
+	}
14
+	var (
15
+		args = Args{}
16
+		err  error
17
+	)
18
+	for i := range flagArgs {
19
+		args, err = ParseFlag(flagArgs[i], args)
20
+		if err != nil {
21
+			t.Errorf("failed to parse %s: %s", flagArgs[i], err)
22
+		}
23
+	}
24
+	if len(args["created"]) != 1 {
25
+		t.Errorf("failed to set this arg")
26
+	}
27
+	if len(args["image.name"]) != 2 {
28
+		t.Errorf("the args should have collapsed")
29
+	}
30
+}
31
+
32
+func TestParam(t *testing.T) {
33
+	a := Args{
34
+		"created":    []string{"today"},
35
+		"image.name": []string{"ubuntu*", "*untu"},
36
+	}
37
+
38
+	v, err := ToParam(a)
39
+	if err != nil {
40
+		t.Errorf("failed to marshal the filters: %s", err)
41
+	}
42
+	v1, err := FromParam(v)
43
+	if err != nil {
44
+		t.Errorf("%s", err)
45
+	}
46
+	for key, vals := range v1 {
47
+		if _, ok := a[key]; !ok {
48
+			t.Errorf("could not find key %s in original set", key)
49
+		}
50
+		sort.Strings(vals)
51
+		sort.Strings(a[key])
52
+		if len(vals) != len(a[key]) {
53
+			t.Errorf("value lengths ought to match")
54
+			continue
55
+		}
56
+		for i := range vals {
57
+			if vals[i] != a[key][i] {
58
+				t.Errorf("expected %s, but got %s", a[key][i], vals[i])
59
+			}
60
+		}
61
+	}
62
+}
63
+
64
+func TestEmpty(t *testing.T) {
65
+	a := Args{}
66
+	v, err := ToParam(a)
67
+	if err != nil {
68
+		t.Errorf("failed to marshal the filters: %s", err)
69
+	}
70
+	v1, err := FromParam(v)
71
+	if err != nil {
72
+		t.Errorf("%s", err)
73
+	}
74
+	if len(a) != len(v1) {
75
+		t.Errorf("these should both be empty sets")
76
+	}
77
+}
0 78
new file mode 100644
... ...
@@ -0,0 +1,93 @@
0
+package kernel
1
+
2
+import (
3
+	"bytes"
4
+	"errors"
5
+	"fmt"
6
+)
7
+
8
+type KernelVersionInfo struct {
9
+	Kernel int
10
+	Major  int
11
+	Minor  int
12
+	Flavor string
13
+}
14
+
15
+func (k *KernelVersionInfo) String() string {
16
+	return fmt.Sprintf("%d.%d.%d%s", k.Kernel, k.Major, k.Minor, k.Flavor)
17
+}
18
+
19
+// Compare two KernelVersionInfo struct.
20
+// Returns -1 if a < b, 0 if a == b, 1 it a > b
21
+func CompareKernelVersion(a, b *KernelVersionInfo) int {
22
+	if a.Kernel < b.Kernel {
23
+		return -1
24
+	} else if a.Kernel > b.Kernel {
25
+		return 1
26
+	}
27
+
28
+	if a.Major < b.Major {
29
+		return -1
30
+	} else if a.Major > b.Major {
31
+		return 1
32
+	}
33
+
34
+	if a.Minor < b.Minor {
35
+		return -1
36
+	} else if a.Minor > b.Minor {
37
+		return 1
38
+	}
39
+
40
+	return 0
41
+}
42
+
43
+func GetKernelVersion() (*KernelVersionInfo, error) {
44
+	var (
45
+		err error
46
+	)
47
+
48
+	uts, err := uname()
49
+	if err != nil {
50
+		return nil, err
51
+	}
52
+
53
+	release := make([]byte, len(uts.Release))
54
+
55
+	i := 0
56
+	for _, c := range uts.Release {
57
+		release[i] = byte(c)
58
+		i++
59
+	}
60
+
61
+	// Remove the \x00 from the release for Atoi to parse correctly
62
+	release = release[:bytes.IndexByte(release, 0)]
63
+
64
+	return ParseRelease(string(release))
65
+}
66
+
67
+func ParseRelease(release string) (*KernelVersionInfo, error) {
68
+	var (
69
+		kernel, major, minor, parsed int
70
+		flavor, partial              string
71
+	)
72
+
73
+	// Ignore error from Sscanf to allow an empty flavor.  Instead, just
74
+	// make sure we got all the version numbers.
75
+	parsed, _ = fmt.Sscanf(release, "%d.%d%s", &kernel, &major, &partial)
76
+	if parsed < 2 {
77
+		return nil, errors.New("Can't parse kernel version " + release)
78
+	}
79
+
80
+	// sometimes we have 3.12.25-gentoo, but sometimes we just have 3.12-1-amd64
81
+	parsed, _ = fmt.Sscanf(partial, ".%d%s", &minor, &flavor)
82
+	if parsed < 1 {
83
+		flavor = partial
84
+	}
85
+
86
+	return &KernelVersionInfo{
87
+		Kernel: kernel,
88
+		Major:  major,
89
+		Minor:  minor,
90
+		Flavor: flavor,
91
+	}, nil
92
+}
0 93
new file mode 100644
... ...
@@ -0,0 +1,61 @@
0
+package kernel
1
+
2
+import (
3
+	"testing"
4
+)
5
+
6
+func assertParseRelease(t *testing.T, release string, b *KernelVersionInfo, result int) {
7
+	var (
8
+		a *KernelVersionInfo
9
+	)
10
+	a, _ = ParseRelease(release)
11
+
12
+	if r := CompareKernelVersion(a, b); r != result {
13
+		t.Fatalf("Unexpected kernel version comparison result. Found %d, expected %d", r, result)
14
+	}
15
+	if a.Flavor != b.Flavor {
16
+		t.Fatalf("Unexpected parsed kernel flavor.  Found %s, expected %s", a.Flavor, b.Flavor)
17
+	}
18
+}
19
+
20
+func TestParseRelease(t *testing.T) {
21
+	assertParseRelease(t, "3.8.0", &KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0}, 0)
22
+	assertParseRelease(t, "3.4.54.longterm-1", &KernelVersionInfo{Kernel: 3, Major: 4, Minor: 54, Flavor: ".longterm-1"}, 0)
23
+	assertParseRelease(t, "3.4.54.longterm-1", &KernelVersionInfo{Kernel: 3, Major: 4, Minor: 54, Flavor: ".longterm-1"}, 0)
24
+	assertParseRelease(t, "3.8.0-19-generic", &KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0, Flavor: "-19-generic"}, 0)
25
+	assertParseRelease(t, "3.12.8tag", &KernelVersionInfo{Kernel: 3, Major: 12, Minor: 8, Flavor: "tag"}, 0)
26
+	assertParseRelease(t, "3.12-1-amd64", &KernelVersionInfo{Kernel: 3, Major: 12, Minor: 0, Flavor: "-1-amd64"}, 0)
27
+}
28
+
29
+func assertKernelVersion(t *testing.T, a, b *KernelVersionInfo, result int) {
30
+	if r := CompareKernelVersion(a, b); r != result {
31
+		t.Fatalf("Unexpected kernel version comparison result. Found %d, expected %d", r, result)
32
+	}
33
+}
34
+
35
+func TestCompareKernelVersion(t *testing.T) {
36
+	assertKernelVersion(t,
37
+		&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
38
+		&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
39
+		0)
40
+	assertKernelVersion(t,
41
+		&KernelVersionInfo{Kernel: 2, Major: 6, Minor: 0},
42
+		&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
43
+		-1)
44
+	assertKernelVersion(t,
45
+		&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
46
+		&KernelVersionInfo{Kernel: 2, Major: 6, Minor: 0},
47
+		1)
48
+	assertKernelVersion(t,
49
+		&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
50
+		&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
51
+		0)
52
+	assertKernelVersion(t,
53
+		&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 5},
54
+		&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
55
+		1)
56
+	assertKernelVersion(t,
57
+		&KernelVersionInfo{Kernel: 3, Major: 0, Minor: 20},
58
+		&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
59
+		-1)
60
+}
0 61
new file mode 100644
... ...
@@ -0,0 +1,18 @@
0
+// +build amd64
1
+
2
+package kernel
3
+
4
+import (
5
+	"syscall"
6
+)
7
+
8
+type Utsname syscall.Utsname
9
+
10
+func uname() (*syscall.Utsname, error) {
11
+	uts := &syscall.Utsname{}
12
+
13
+	if err := syscall.Uname(uts); err != nil {
14
+		return nil, err
15
+	}
16
+	return uts, nil
17
+}
0 18
new file mode 100644
... ...
@@ -0,0 +1,15 @@
0
+// +build !linux !amd64
1
+
2
+package kernel
3
+
4
+import (
5
+	"errors"
6
+)
7
+
8
+type Utsname struct {
9
+	Release [65]byte
10
+}
11
+
12
+func uname() (*Utsname, error) {
13
+	return nil, errors.New("Kernel version detection is available only on linux")
14
+}
0 15
new file mode 100644
... ...
@@ -0,0 +1,110 @@
0
+package parsers
1
+
2
+import (
3
+	"fmt"
4
+	"strconv"
5
+	"strings"
6
+)
7
+
8
+// FIXME: Change this not to receive default value as parameter
9
+func ParseHost(defaultHost string, defaultUnix, addr string) (string, error) {
10
+	var (
11
+		proto string
12
+		host  string
13
+		port  int
14
+	)
15
+	addr = strings.TrimSpace(addr)
16
+	switch {
17
+	case addr == "tcp://":
18
+		return "", fmt.Errorf("Invalid bind address format: %s", addr)
19
+	case strings.HasPrefix(addr, "unix://"):
20
+		proto = "unix"
21
+		addr = strings.TrimPrefix(addr, "unix://")
22
+		if addr == "" {
23
+			addr = defaultUnix
24
+		}
25
+	case strings.HasPrefix(addr, "tcp://"):
26
+		proto = "tcp"
27
+		addr = strings.TrimPrefix(addr, "tcp://")
28
+	case strings.HasPrefix(addr, "fd://"):
29
+		return addr, nil
30
+	case addr == "":
31
+		proto = "unix"
32
+		addr = defaultUnix
33
+	default:
34
+		if strings.Contains(addr, "://") {
35
+			return "", fmt.Errorf("Invalid bind address protocol: %s", addr)
36
+		}
37
+		proto = "tcp"
38
+	}
39
+
40
+	if proto != "unix" && strings.Contains(addr, ":") {
41
+		hostParts := strings.Split(addr, ":")
42
+		if len(hostParts) != 2 {
43
+			return "", fmt.Errorf("Invalid bind address format: %s", addr)
44
+		}
45
+		if hostParts[0] != "" {
46
+			host = hostParts[0]
47
+		} else {
48
+			host = defaultHost
49
+		}
50
+
51
+		if p, err := strconv.Atoi(hostParts[1]); err == nil && p != 0 {
52
+			port = p
53
+		} else {
54
+			return "", fmt.Errorf("Invalid bind address format: %s", addr)
55
+		}
56
+
57
+	} else if proto == "tcp" && !strings.Contains(addr, ":") {
58
+		return "", fmt.Errorf("Invalid bind address format: %s", addr)
59
+	} else {
60
+		host = addr
61
+	}
62
+	if proto == "unix" {
63
+		return fmt.Sprintf("%s://%s", proto, host), nil
64
+	}
65
+	return fmt.Sprintf("%s://%s:%d", proto, host, port), nil
66
+}
67
+
68
+// Get a repos name and returns the right reposName + tag
69
+// The tag can be confusing because of a port in a repository name.
70
+//     Ex: localhost.localdomain:5000/samalba/hipache:latest
71
+func ParseRepositoryTag(repos string) (string, string) {
72
+	n := strings.LastIndex(repos, ":")
73
+	if n < 0 {
74
+		return repos, ""
75
+	}
76
+	if tag := repos[n+1:]; !strings.Contains(tag, "/") {
77
+		return repos[:n], tag
78
+	}
79
+	return repos, ""
80
+}
81
+
82
+func PartParser(template, data string) (map[string]string, error) {
83
+	// ip:public:private
84
+	var (
85
+		templateParts = strings.Split(template, ":")
86
+		parts         = strings.Split(data, ":")
87
+		out           = make(map[string]string, len(templateParts))
88
+	)
89
+	if len(parts) != len(templateParts) {
90
+		return nil, fmt.Errorf("Invalid format to parse.  %s should match template %s", data, template)
91
+	}
92
+
93
+	for i, t := range templateParts {
94
+		value := ""
95
+		if len(parts) > i {
96
+			value = parts[i]
97
+		}
98
+		out[t] = value
99
+	}
100
+	return out, nil
101
+}
102
+
103
+func ParseKeyValueOpt(opt string) (string, string, error) {
104
+	parts := strings.SplitN(opt, "=", 2)
105
+	if len(parts) != 2 {
106
+		return "", "", fmt.Errorf("Unable to parse key/value option: %s", opt)
107
+	}
108
+	return strings.TrimSpace(parts[0]), strings.TrimSpace(parts[1]), nil
109
+}
0 110
new file mode 100644
... ...
@@ -0,0 +1,83 @@
0
+package parsers
1
+
2
+import (
3
+	"testing"
4
+)
5
+
6
+func TestParseHost(t *testing.T) {
7
+	var (
8
+		defaultHttpHost = "127.0.0.1"
9
+		defaultUnix     = "/var/run/docker.sock"
10
+	)
11
+	if addr, err := ParseHost(defaultHttpHost, defaultUnix, "0.0.0.0"); err == nil {
12
+		t.Errorf("tcp 0.0.0.0 address expected error return, but err == nil, got %s", addr)
13
+	}
14
+	if addr, err := ParseHost(defaultHttpHost, defaultUnix, "tcp://"); err == nil {
15
+		t.Errorf("default tcp:// address expected error return, but err == nil, got %s", addr)
16
+	}
17
+	if addr, err := ParseHost(defaultHttpHost, defaultUnix, "0.0.0.1:5555"); err != nil || addr != "tcp://0.0.0.1:5555" {
18
+		t.Errorf("0.0.0.1:5555 -> expected tcp://0.0.0.1:5555, got %s", addr)
19
+	}
20
+	if addr, err := ParseHost(defaultHttpHost, defaultUnix, ":6666"); err != nil || addr != "tcp://127.0.0.1:6666" {
21
+		t.Errorf(":6666 -> expected tcp://127.0.0.1:6666, got %s", addr)
22
+	}
23
+	if addr, err := ParseHost(defaultHttpHost, defaultUnix, "tcp://:7777"); err != nil || addr != "tcp://127.0.0.1:7777" {
24
+		t.Errorf("tcp://:7777 -> expected tcp://127.0.0.1:7777, got %s", addr)
25
+	}
26
+	if addr, err := ParseHost(defaultHttpHost, defaultUnix, ""); err != nil || addr != "unix:///var/run/docker.sock" {
27
+		t.Errorf("empty argument -> expected unix:///var/run/docker.sock, got %s", addr)
28
+	}
29
+	if addr, err := ParseHost(defaultHttpHost, defaultUnix, "unix:///var/run/docker.sock"); err != nil || addr != "unix:///var/run/docker.sock" {
30
+		t.Errorf("unix:///var/run/docker.sock -> expected unix:///var/run/docker.sock, got %s", addr)
31
+	}
32
+	if addr, err := ParseHost(defaultHttpHost, defaultUnix, "unix://"); err != nil || addr != "unix:///var/run/docker.sock" {
33
+		t.Errorf("unix:///var/run/docker.sock -> expected unix:///var/run/docker.sock, got %s", addr)
34
+	}
35
+	if addr, err := ParseHost(defaultHttpHost, defaultUnix, "udp://127.0.0.1"); err == nil {
36
+		t.Errorf("udp protocol address expected error return, but err == nil. Got %s", addr)
37
+	}
38
+	if addr, err := ParseHost(defaultHttpHost, defaultUnix, "udp://127.0.0.1:2375"); err == nil {
39
+		t.Errorf("udp protocol address expected error return, but err == nil. Got %s", addr)
40
+	}
41
+}
42
+
43
+func TestParseRepositoryTag(t *testing.T) {
44
+	if repo, tag := ParseRepositoryTag("root"); repo != "root" || tag != "" {
45
+		t.Errorf("Expected repo: '%s' and tag: '%s', got '%s' and '%s'", "root", "", repo, tag)
46
+	}
47
+	if repo, tag := ParseRepositoryTag("root:tag"); repo != "root" || tag != "tag" {
48
+		t.Errorf("Expected repo: '%s' and tag: '%s', got '%s' and '%s'", "root", "tag", repo, tag)
49
+	}
50
+	if repo, tag := ParseRepositoryTag("user/repo"); repo != "user/repo" || tag != "" {
51
+		t.Errorf("Expected repo: '%s' and tag: '%s', got '%s' and '%s'", "user/repo", "", repo, tag)
52
+	}
53
+	if repo, tag := ParseRepositoryTag("user/repo:tag"); repo != "user/repo" || tag != "tag" {
54
+		t.Errorf("Expected repo: '%s' and tag: '%s', got '%s' and '%s'", "user/repo", "tag", repo, tag)
55
+	}
56
+	if repo, tag := ParseRepositoryTag("url:5000/repo"); repo != "url:5000/repo" || tag != "" {
57
+		t.Errorf("Expected repo: '%s' and tag: '%s', got '%s' and '%s'", "url:5000/repo", "", repo, tag)
58
+	}
59
+	if repo, tag := ParseRepositoryTag("url:5000/repo:tag"); repo != "url:5000/repo" || tag != "tag" {
60
+		t.Errorf("Expected repo: '%s' and tag: '%s', got '%s' and '%s'", "url:5000/repo", "tag", repo, tag)
61
+	}
62
+}
63
+
64
+func TestParsePortMapping(t *testing.T) {
65
+	data, err := PartParser("ip:public:private", "192.168.1.1:80:8080")
66
+	if err != nil {
67
+		t.Fatal(err)
68
+	}
69
+
70
+	if len(data) != 3 {
71
+		t.FailNow()
72
+	}
73
+	if data["ip"] != "192.168.1.1" {
74
+		t.Fail()
75
+	}
76
+	if data["public"] != "80" {
77
+		t.Fail()
78
+	}
79
+	if data["private"] != "8080" {
80
+		t.Fail()
81
+	}
82
+}
... ...
@@ -25,6 +25,7 @@ import (
25 25
 
26 26
 	"github.com/docker/docker/dockerversion"
27 27
 	"github.com/docker/docker/pkg/httputils"
28
+	"github.com/docker/docker/pkg/parsers/kernel"
28 29
 	"github.com/docker/docker/utils"
29 30
 )
30 31
 
... ...
@@ -956,7 +957,7 @@ func HTTPRequestFactory(metaHeaders map[string][]string) *utils.HTTPRequestFacto
956 956
 	httpVersion = append(httpVersion, &simpleVersionInfo{"docker", dockerversion.VERSION})
957 957
 	httpVersion = append(httpVersion, &simpleVersionInfo{"go", runtime.Version()})
958 958
 	httpVersion = append(httpVersion, &simpleVersionInfo{"git-commit", dockerversion.GITCOMMIT})
959
-	if kernelVersion, err := utils.GetKernelVersion(); err == nil {
959
+	if kernelVersion, err := kernel.GetKernelVersion(); err == nil {
960 960
 		httpVersion = append(httpVersion, &simpleVersionInfo{"kernel", kernelVersion.String()})
961 961
 	}
962 962
 	httpVersion = append(httpVersion, &simpleVersionInfo{"os", runtime.GOOS})
... ...
@@ -9,6 +9,7 @@ import (
9 9
 	"github.com/docker/docker/nat"
10 10
 	"github.com/docker/docker/opts"
11 11
 	flag "github.com/docker/docker/pkg/mflag"
12
+	"github.com/docker/docker/pkg/parsers"
12 13
 	"github.com/docker/docker/pkg/sysinfo"
13 14
 	"github.com/docker/docker/pkg/units"
14 15
 	"github.com/docker/docker/utils"
... ...
@@ -306,7 +307,7 @@ func parseDriverOpts(opts opts.ListOpts) (map[string][]string, error) {
306 306
 func parseKeyValueOpts(opts opts.ListOpts) ([]utils.KeyValuePair, error) {
307 307
 	out := make([]utils.KeyValuePair, opts.Len())
308 308
 	for i, o := range opts.GetAll() {
309
-		k, v, err := utils.ParseKeyValueOpt(o)
309
+		k, v, err := parsers.ParseKeyValueOpt(o)
310 310
 		if err != nil {
311 311
 			return nil, err
312 312
 		}
... ...
@@ -3,14 +3,14 @@ package runconfig
3 3
 import (
4 4
 	"testing"
5 5
 
6
-	"github.com/docker/docker/utils"
6
+	"github.com/docker/docker/pkg/parsers"
7 7
 )
8 8
 
9 9
 func TestParseLxcConfOpt(t *testing.T) {
10 10
 	opts := []string{"lxc.utsname=docker", "lxc.utsname = docker "}
11 11
 
12 12
 	for _, o := range opts {
13
-		k, v, err := utils.ParseKeyValueOpt(o)
13
+		k, v, err := parsers.ParseKeyValueOpt(o)
14 14
 		if err != nil {
15 15
 			t.FailNow()
16 16
 		}
... ...
@@ -54,12 +54,14 @@ import (
54 54
 	"github.com/docker/docker/graph"
55 55
 	"github.com/docker/docker/image"
56 56
 	"github.com/docker/docker/pkg/graphdb"
57
+	"github.com/docker/docker/pkg/parsers"
58
+	"github.com/docker/docker/pkg/parsers/filters"
59
+	"github.com/docker/docker/pkg/parsers/kernel"
57 60
 	"github.com/docker/docker/pkg/signal"
58 61
 	"github.com/docker/docker/pkg/tailfile"
59 62
 	"github.com/docker/docker/registry"
60 63
 	"github.com/docker/docker/runconfig"
61 64
 	"github.com/docker/docker/utils"
62
-	"github.com/docker/docker/utils/filters"
63 65
 )
64 66
 
65 67
 func (srv *Server) handlerWrap(h engine.Handler) engine.Handler {
... ...
@@ -383,7 +385,7 @@ func (srv *Server) ImageExport(job *engine.Job) engine.Status {
383 383
 		}
384 384
 		if img != nil {
385 385
 			// This is a named image like 'busybox:latest'
386
-			repoName, repoTag := utils.ParseRepositoryTag(name)
386
+			repoName, repoTag := parsers.ParseRepositoryTag(name)
387 387
 			if err := srv.exportImage(job.Eng, img.ID, tempdir); err != nil {
388 388
 				return job.Error(err)
389 389
 			}
... ...
@@ -493,7 +495,7 @@ func (srv *Server) Build(job *engine.Job) engine.Status {
493 493
 	)
494 494
 	job.GetenvJson("authConfig", authConfig)
495 495
 	job.GetenvJson("configFile", configFile)
496
-	repoName, tag = utils.ParseRepositoryTag(repoName)
496
+	repoName, tag = parsers.ParseRepositoryTag(repoName)
497 497
 
498 498
 	if remoteURL == "" {
499 499
 		context = ioutil.NopCloser(job.Stdin)
... ...
@@ -789,7 +791,7 @@ func (srv *Server) DockerInfo(job *engine.Job) engine.Status {
789 789
 		imgcount = len(images)
790 790
 	}
791 791
 	kernelVersion := "<unknown>"
792
-	if kv, err := utils.GetKernelVersion(); err == nil {
792
+	if kv, err := kernel.GetKernelVersion(); err == nil {
793 793
 		kernelVersion = kv.String()
794 794
 	}
795 795
 
... ...
@@ -1746,7 +1748,7 @@ func (srv *Server) ContainerCreate(job *engine.Job) engine.Status {
1746 1746
 	container, buildWarnings, err := srv.daemon.Create(config, name)
1747 1747
 	if err != nil {
1748 1748
 		if srv.daemon.Graph().IsNotExist(err) {
1749
-			_, tag := utils.ParseRepositoryTag(config.Image)
1749
+			_, tag := parsers.ParseRepositoryTag(config.Image)
1750 1750
 			if tag == "" {
1751 1751
 				tag = graph.DEFAULTTAG
1752 1752
 			}
... ...
@@ -1924,7 +1926,7 @@ func (srv *Server) DeleteImage(name string, imgs *engine.Table, first, force, no
1924 1924
 		tagDeleted    bool
1925 1925
 	)
1926 1926
 
1927
-	repoName, tag = utils.ParseRepositoryTag(name)
1927
+	repoName, tag = parsers.ParseRepositoryTag(name)
1928 1928
 	if tag == "" {
1929 1929
 		tag = graph.DEFAULTTAG
1930 1930
 	}
... ...
@@ -1950,7 +1952,7 @@ func (srv *Server) DeleteImage(name string, imgs *engine.Table, first, force, no
1950 1950
 	//If delete by id, see if the id belong only to one repository
1951 1951
 	if repoName == "" {
1952 1952
 		for _, repoAndTag := range srv.daemon.Repositories().ByID()[img.ID] {
1953
-			parsedRepo, parsedTag := utils.ParseRepositoryTag(repoAndTag)
1953
+			parsedRepo, parsedTag := parsers.ParseRepositoryTag(repoAndTag)
1954 1954
 			if repoName == "" || repoName == parsedRepo {
1955 1955
 				repoName = parsedRepo
1956 1956
 				if parsedTag != "" {
1957 1957
deleted file mode 100644
... ...
@@ -1,63 +0,0 @@
1
-package filters
2
-
3
-import (
4
-	"encoding/json"
5
-	"errors"
6
-	"strings"
7
-)
8
-
9
-type Args map[string][]string
10
-
11
-// Parse the argument to the filter flag. Like
12
-//
13
-//   `docker ps -f 'created=today' -f 'image.name=ubuntu*'`
14
-//
15
-// If prev map is provided, then it is appended to, and returned. By default a new
16
-// map is created.
17
-func ParseFlag(arg string, prev Args) (Args, error) {
18
-	var filters Args = prev
19
-	if prev == nil {
20
-		filters = Args{}
21
-	}
22
-	if len(arg) == 0 {
23
-		return filters, nil
24
-	}
25
-
26
-	if !strings.Contains(arg, "=") {
27
-		return filters, ErrorBadFormat
28
-	}
29
-
30
-	f := strings.SplitN(arg, "=", 2)
31
-	filters[f[0]] = append(filters[f[0]], f[1])
32
-
33
-	return filters, nil
34
-}
35
-
36
-var ErrorBadFormat = errors.New("bad format of filter (expected name=value)")
37
-
38
-// packs the Args into an string for easy transport from client to server
39
-func ToParam(a Args) (string, error) {
40
-	// this way we don't URL encode {}, just empty space
41
-	if len(a) == 0 {
42
-		return "", nil
43
-	}
44
-
45
-	buf, err := json.Marshal(a)
46
-	if err != nil {
47
-		return "", err
48
-	}
49
-	return string(buf), nil
50
-}
51
-
52
-// unpacks the filter Args
53
-func FromParam(p string) (Args, error) {
54
-	args := Args{}
55
-	if len(p) == 0 {
56
-		return args, nil
57
-	}
58
-	err := json.Unmarshal([]byte(p), &args)
59
-	if err != nil {
60
-		return nil, err
61
-	}
62
-	return args, nil
63
-}
64 1
deleted file mode 100644
... ...
@@ -1,78 +0,0 @@
1
-package filters
2
-
3
-import (
4
-	"sort"
5
-	"testing"
6
-)
7
-
8
-func TestParseArgs(t *testing.T) {
9
-	// equivalent of `docker ps -f 'created=today' -f 'image.name=ubuntu*' -f 'image.name=*untu'`
10
-	flagArgs := []string{
11
-		"created=today",
12
-		"image.name=ubuntu*",
13
-		"image.name=*untu",
14
-	}
15
-	var (
16
-		args = Args{}
17
-		err  error
18
-	)
19
-	for i := range flagArgs {
20
-		args, err = ParseFlag(flagArgs[i], args)
21
-		if err != nil {
22
-			t.Errorf("failed to parse %s: %s", flagArgs[i], err)
23
-		}
24
-	}
25
-	if len(args["created"]) != 1 {
26
-		t.Errorf("failed to set this arg")
27
-	}
28
-	if len(args["image.name"]) != 2 {
29
-		t.Errorf("the args should have collapsed")
30
-	}
31
-}
32
-
33
-func TestParam(t *testing.T) {
34
-	a := Args{
35
-		"created":    []string{"today"},
36
-		"image.name": []string{"ubuntu*", "*untu"},
37
-	}
38
-
39
-	v, err := ToParam(a)
40
-	if err != nil {
41
-		t.Errorf("failed to marshal the filters: %s", err)
42
-	}
43
-	v1, err := FromParam(v)
44
-	if err != nil {
45
-		t.Errorf("%s", err)
46
-	}
47
-	for key, vals := range v1 {
48
-		if _, ok := a[key]; !ok {
49
-			t.Errorf("could not find key %s in original set", key)
50
-		}
51
-		sort.Strings(vals)
52
-		sort.Strings(a[key])
53
-		if len(vals) != len(a[key]) {
54
-			t.Errorf("value lengths ought to match")
55
-			continue
56
-		}
57
-		for i := range vals {
58
-			if vals[i] != a[key][i] {
59
-				t.Errorf("expected %s, but got %s", a[key][i], vals[i])
60
-			}
61
-		}
62
-	}
63
-}
64
-
65
-func TestEmpty(t *testing.T) {
66
-	a := Args{}
67
-	v, err := ToParam(a)
68
-	if err != nil {
69
-		t.Errorf("failed to marshal the filters: %s", err)
70
-	}
71
-	v1, err := FromParam(v)
72
-	if err != nil {
73
-		t.Errorf("%s", err)
74
-	}
75
-	if len(a) != len(v1) {
76
-		t.Errorf("these should both be empty sets")
77
-	}
78
-}
79 1
deleted file mode 100644
... ...
@@ -1,18 +0,0 @@
1
-// +build amd64
2
-
3
-package utils
4
-
5
-import (
6
-	"syscall"
7
-)
8
-
9
-type Utsname syscall.Utsname
10
-
11
-func uname() (*syscall.Utsname, error) {
12
-	uts := &syscall.Utsname{}
13
-
14
-	if err := syscall.Uname(uts); err != nil {
15
-		return nil, err
16
-	}
17
-	return uts, nil
18
-}
19 1
deleted file mode 100644
... ...
@@ -1,15 +0,0 @@
1
-// +build !linux !amd64
2
-
3
-package utils
4
-
5
-import (
6
-	"errors"
7
-)
8
-
9
-type Utsname struct {
10
-	Release [65]byte
11
-}
12
-
13
-func uname() (*Utsname, error) {
14
-	return nil, errors.New("Kernel version detection is available only on linux")
15
-}
... ...
@@ -7,7 +7,6 @@ import (
7 7
 	"crypto/sha256"
8 8
 	"encoding/hex"
9 9
 	"encoding/json"
10
-	"errors"
11 10
 	"fmt"
12 11
 	"io"
13 12
 	"io/ioutil"
... ...
@@ -401,92 +400,6 @@ func HashData(src io.Reader) (string, error) {
401 401
 	return "sha256:" + hex.EncodeToString(h.Sum(nil)), nil
402 402
 }
403 403
 
404
-type KernelVersionInfo struct {
405
-	Kernel int
406
-	Major  int
407
-	Minor  int
408
-	Flavor string
409
-}
410
-
411
-func (k *KernelVersionInfo) String() string {
412
-	return fmt.Sprintf("%d.%d.%d%s", k.Kernel, k.Major, k.Minor, k.Flavor)
413
-}
414
-
415
-// Compare two KernelVersionInfo struct.
416
-// Returns -1 if a < b, 0 if a == b, 1 it a > b
417
-func CompareKernelVersion(a, b *KernelVersionInfo) int {
418
-	if a.Kernel < b.Kernel {
419
-		return -1
420
-	} else if a.Kernel > b.Kernel {
421
-		return 1
422
-	}
423
-
424
-	if a.Major < b.Major {
425
-		return -1
426
-	} else if a.Major > b.Major {
427
-		return 1
428
-	}
429
-
430
-	if a.Minor < b.Minor {
431
-		return -1
432
-	} else if a.Minor > b.Minor {
433
-		return 1
434
-	}
435
-
436
-	return 0
437
-}
438
-
439
-func GetKernelVersion() (*KernelVersionInfo, error) {
440
-	var (
441
-		err error
442
-	)
443
-
444
-	uts, err := uname()
445
-	if err != nil {
446
-		return nil, err
447
-	}
448
-
449
-	release := make([]byte, len(uts.Release))
450
-
451
-	i := 0
452
-	for _, c := range uts.Release {
453
-		release[i] = byte(c)
454
-		i++
455
-	}
456
-
457
-	// Remove the \x00 from the release for Atoi to parse correctly
458
-	release = release[:bytes.IndexByte(release, 0)]
459
-
460
-	return ParseRelease(string(release))
461
-}
462
-
463
-func ParseRelease(release string) (*KernelVersionInfo, error) {
464
-	var (
465
-		kernel, major, minor, parsed int
466
-		flavor, partial              string
467
-	)
468
-
469
-	// Ignore error from Sscanf to allow an empty flavor.  Instead, just
470
-	// make sure we got all the version numbers.
471
-	parsed, _ = fmt.Sscanf(release, "%d.%d%s", &kernel, &major, &partial)
472
-	if parsed < 2 {
473
-		return nil, errors.New("Can't parse kernel version " + release)
474
-	}
475
-
476
-	// sometimes we have 3.12.25-gentoo, but sometimes we just have 3.12-1-amd64
477
-	parsed, _ = fmt.Sscanf(partial, ".%d%s", &minor, &flavor)
478
-	if parsed < 1 {
479
-		flavor = partial
480
-	}
481
-
482
-	return &KernelVersionInfo{
483
-		Kernel: kernel,
484
-		Major:  major,
485
-		Minor:  minor,
486
-		Flavor: flavor,
487
-	}, nil
488
-}
489
-
490 404
 // FIXME: this is deprecated by CopyWithTar in archive.go
491 405
 func CopyDirectory(source, dest string) error {
492 406
 	if output, err := exec.Command("cp", "-ra", source, dest).CombinedOutput(); err != nil {
... ...
@@ -580,80 +493,6 @@ func GetLines(input []byte, commentMarker []byte) [][]byte {
580 580
 	return output
581 581
 }
582 582
 
583
-// FIXME: Change this not to receive default value as parameter
584
-func ParseHost(defaultHost string, defaultUnix, addr string) (string, error) {
585
-	var (
586
-		proto string
587
-		host  string
588
-		port  int
589
-	)
590
-	addr = strings.TrimSpace(addr)
591
-	switch {
592
-	case addr == "tcp://":
593
-		return "", fmt.Errorf("Invalid bind address format: %s", addr)
594
-	case strings.HasPrefix(addr, "unix://"):
595
-		proto = "unix"
596
-		addr = strings.TrimPrefix(addr, "unix://")
597
-		if addr == "" {
598
-			addr = defaultUnix
599
-		}
600
-	case strings.HasPrefix(addr, "tcp://"):
601
-		proto = "tcp"
602
-		addr = strings.TrimPrefix(addr, "tcp://")
603
-	case strings.HasPrefix(addr, "fd://"):
604
-		return addr, nil
605
-	case addr == "":
606
-		proto = "unix"
607
-		addr = defaultUnix
608
-	default:
609
-		if strings.Contains(addr, "://") {
610
-			return "", fmt.Errorf("Invalid bind address protocol: %s", addr)
611
-		}
612
-		proto = "tcp"
613
-	}
614
-
615
-	if proto != "unix" && strings.Contains(addr, ":") {
616
-		hostParts := strings.Split(addr, ":")
617
-		if len(hostParts) != 2 {
618
-			return "", fmt.Errorf("Invalid bind address format: %s", addr)
619
-		}
620
-		if hostParts[0] != "" {
621
-			host = hostParts[0]
622
-		} else {
623
-			host = defaultHost
624
-		}
625
-
626
-		if p, err := strconv.Atoi(hostParts[1]); err == nil && p != 0 {
627
-			port = p
628
-		} else {
629
-			return "", fmt.Errorf("Invalid bind address format: %s", addr)
630
-		}
631
-
632
-	} else if proto == "tcp" && !strings.Contains(addr, ":") {
633
-		return "", fmt.Errorf("Invalid bind address format: %s", addr)
634
-	} else {
635
-		host = addr
636
-	}
637
-	if proto == "unix" {
638
-		return fmt.Sprintf("%s://%s", proto, host), nil
639
-	}
640
-	return fmt.Sprintf("%s://%s:%d", proto, host, port), nil
641
-}
642
-
643
-// Get a repos name and returns the right reposName + tag
644
-// The tag can be confusing because of a port in a repository name.
645
-//     Ex: localhost.localdomain:5000/samalba/hipache:latest
646
-func ParseRepositoryTag(repos string) (string, string) {
647
-	n := strings.LastIndex(repos, ":")
648
-	if n < 0 {
649
-		return repos, ""
650
-	}
651
-	if tag := repos[n+1:]; !strings.Contains(tag, "/") {
652
-		return repos[:n], tag
653
-	}
654
-	return repos, ""
655
-}
656
-
657 583
 // An StatusError reports an unsuccessful exit by a command.
658 584
 type StatusError struct {
659 585
 	Status     string
... ...
@@ -699,27 +538,6 @@ func ShellQuoteArguments(args []string) string {
699 699
 	return buf.String()
700 700
 }
701 701
 
702
-func PartParser(template, data string) (map[string]string, error) {
703
-	// ip:public:private
704
-	var (
705
-		templateParts = strings.Split(template, ":")
706
-		parts         = strings.Split(data, ":")
707
-		out           = make(map[string]string, len(templateParts))
708
-	)
709
-	if len(parts) != len(templateParts) {
710
-		return nil, fmt.Errorf("Invalid format to parse.  %s should match template %s", data, template)
711
-	}
712
-
713
-	for i, t := range templateParts {
714
-		value := ""
715
-		if len(parts) > i {
716
-			value = parts[i]
717
-		}
718
-		out[t] = value
719
-	}
720
-	return out, nil
721
-}
722
-
723 702
 var globalTestID string
724 703
 
725 704
 // TestDirectory creates a new temporary directory and returns its path.
... ...
@@ -833,14 +651,6 @@ func ReadSymlinkedDirectory(path string) (string, error) {
833 833
 	return realPath, nil
834 834
 }
835 835
 
836
-func ParseKeyValueOpt(opt string) (string, string, error) {
837
-	parts := strings.SplitN(opt, "=", 2)
838
-	if len(parts) != 2 {
839
-		return "", "", fmt.Errorf("Unable to parse key/value option: %s", opt)
840
-	}
841
-	return strings.TrimSpace(parts[0]), strings.TrimSpace(parts[1]), nil
842
-}
843
-
844 836
 // TreeSize walks a directory tree and returns its total size in bytes.
845 837
 func TreeSize(dir string) (size int64, err error) {
846 838
 	data := make(map[uint64]struct{})
... ...
@@ -34,97 +34,6 @@ func TestBufReader(t *testing.T) {
34 34
 	}
35 35
 }
36 36
 
37
-func assertKernelVersion(t *testing.T, a, b *KernelVersionInfo, result int) {
38
-	if r := CompareKernelVersion(a, b); r != result {
39
-		t.Fatalf("Unexpected kernel version comparison result. Found %d, expected %d", r, result)
40
-	}
41
-}
42
-
43
-func TestCompareKernelVersion(t *testing.T) {
44
-	assertKernelVersion(t,
45
-		&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
46
-		&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
47
-		0)
48
-	assertKernelVersion(t,
49
-		&KernelVersionInfo{Kernel: 2, Major: 6, Minor: 0},
50
-		&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
51
-		-1)
52
-	assertKernelVersion(t,
53
-		&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
54
-		&KernelVersionInfo{Kernel: 2, Major: 6, Minor: 0},
55
-		1)
56
-	assertKernelVersion(t,
57
-		&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
58
-		&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
59
-		0)
60
-	assertKernelVersion(t,
61
-		&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 5},
62
-		&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
63
-		1)
64
-	assertKernelVersion(t,
65
-		&KernelVersionInfo{Kernel: 3, Major: 0, Minor: 20},
66
-		&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
67
-		-1)
68
-}
69
-
70
-func TestParseHost(t *testing.T) {
71
-	var (
72
-		defaultHttpHost = "127.0.0.1"
73
-		defaultUnix     = "/var/run/docker.sock"
74
-	)
75
-	if addr, err := ParseHost(defaultHttpHost, defaultUnix, "0.0.0.0"); err == nil {
76
-		t.Errorf("tcp 0.0.0.0 address expected error return, but err == nil, got %s", addr)
77
-	}
78
-	if addr, err := ParseHost(defaultHttpHost, defaultUnix, "tcp://"); err == nil {
79
-		t.Errorf("default tcp:// address expected error return, but err == nil, got %s", addr)
80
-	}
81
-	if addr, err := ParseHost(defaultHttpHost, defaultUnix, "0.0.0.1:5555"); err != nil || addr != "tcp://0.0.0.1:5555" {
82
-		t.Errorf("0.0.0.1:5555 -> expected tcp://0.0.0.1:5555, got %s", addr)
83
-	}
84
-	if addr, err := ParseHost(defaultHttpHost, defaultUnix, ":6666"); err != nil || addr != "tcp://127.0.0.1:6666" {
85
-		t.Errorf(":6666 -> expected tcp://127.0.0.1:6666, got %s", addr)
86
-	}
87
-	if addr, err := ParseHost(defaultHttpHost, defaultUnix, "tcp://:7777"); err != nil || addr != "tcp://127.0.0.1:7777" {
88
-		t.Errorf("tcp://:7777 -> expected tcp://127.0.0.1:7777, got %s", addr)
89
-	}
90
-	if addr, err := ParseHost(defaultHttpHost, defaultUnix, ""); err != nil || addr != "unix:///var/run/docker.sock" {
91
-		t.Errorf("empty argument -> expected unix:///var/run/docker.sock, got %s", addr)
92
-	}
93
-	if addr, err := ParseHost(defaultHttpHost, defaultUnix, "unix:///var/run/docker.sock"); err != nil || addr != "unix:///var/run/docker.sock" {
94
-		t.Errorf("unix:///var/run/docker.sock -> expected unix:///var/run/docker.sock, got %s", addr)
95
-	}
96
-	if addr, err := ParseHost(defaultHttpHost, defaultUnix, "unix://"); err != nil || addr != "unix:///var/run/docker.sock" {
97
-		t.Errorf("unix:///var/run/docker.sock -> expected unix:///var/run/docker.sock, got %s", addr)
98
-	}
99
-	if addr, err := ParseHost(defaultHttpHost, defaultUnix, "udp://127.0.0.1"); err == nil {
100
-		t.Errorf("udp protocol address expected error return, but err == nil. Got %s", addr)
101
-	}
102
-	if addr, err := ParseHost(defaultHttpHost, defaultUnix, "udp://127.0.0.1:2375"); err == nil {
103
-		t.Errorf("udp protocol address expected error return, but err == nil. Got %s", addr)
104
-	}
105
-}
106
-
107
-func TestParseRepositoryTag(t *testing.T) {
108
-	if repo, tag := ParseRepositoryTag("root"); repo != "root" || tag != "" {
109
-		t.Errorf("Expected repo: '%s' and tag: '%s', got '%s' and '%s'", "root", "", repo, tag)
110
-	}
111
-	if repo, tag := ParseRepositoryTag("root:tag"); repo != "root" || tag != "tag" {
112
-		t.Errorf("Expected repo: '%s' and tag: '%s', got '%s' and '%s'", "root", "tag", repo, tag)
113
-	}
114
-	if repo, tag := ParseRepositoryTag("user/repo"); repo != "user/repo" || tag != "" {
115
-		t.Errorf("Expected repo: '%s' and tag: '%s', got '%s' and '%s'", "user/repo", "", repo, tag)
116
-	}
117
-	if repo, tag := ParseRepositoryTag("user/repo:tag"); repo != "user/repo" || tag != "tag" {
118
-		t.Errorf("Expected repo: '%s' and tag: '%s', got '%s' and '%s'", "user/repo", "tag", repo, tag)
119
-	}
120
-	if repo, tag := ParseRepositoryTag("url:5000/repo"); repo != "url:5000/repo" || tag != "" {
121
-		t.Errorf("Expected repo: '%s' and tag: '%s', got '%s' and '%s'", "url:5000/repo", "", repo, tag)
122
-	}
123
-	if repo, tag := ParseRepositoryTag("url:5000/repo:tag"); repo != "url:5000/repo" || tag != "tag" {
124
-		t.Errorf("Expected repo: '%s' and tag: '%s', got '%s' and '%s'", "url:5000/repo", "tag", repo, tag)
125
-	}
126
-}
127
-
128 37
 func TestCheckLocalDns(t *testing.T) {
129 38
 	for resolv, result := range map[string]bool{`# Dynamic
130 39
 nameserver 10.0.2.3
... ...
@@ -154,50 +63,6 @@ search docker.com`: true,
154 154
 		}
155 155
 	}
156 156
 }
157
-
158
-func assertParseRelease(t *testing.T, release string, b *KernelVersionInfo, result int) {
159
-	var (
160
-		a *KernelVersionInfo
161
-	)
162
-	a, _ = ParseRelease(release)
163
-
164
-	if r := CompareKernelVersion(a, b); r != result {
165
-		t.Fatalf("Unexpected kernel version comparison result. Found %d, expected %d", r, result)
166
-	}
167
-	if a.Flavor != b.Flavor {
168
-		t.Fatalf("Unexpected parsed kernel flavor.  Found %s, expected %s", a.Flavor, b.Flavor)
169
-	}
170
-}
171
-
172
-func TestParseRelease(t *testing.T) {
173
-	assertParseRelease(t, "3.8.0", &KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0}, 0)
174
-	assertParseRelease(t, "3.4.54.longterm-1", &KernelVersionInfo{Kernel: 3, Major: 4, Minor: 54, Flavor: ".longterm-1"}, 0)
175
-	assertParseRelease(t, "3.4.54.longterm-1", &KernelVersionInfo{Kernel: 3, Major: 4, Minor: 54, Flavor: ".longterm-1"}, 0)
176
-	assertParseRelease(t, "3.8.0-19-generic", &KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0, Flavor: "-19-generic"}, 0)
177
-	assertParseRelease(t, "3.12.8tag", &KernelVersionInfo{Kernel: 3, Major: 12, Minor: 8, Flavor: "tag"}, 0)
178
-	assertParseRelease(t, "3.12-1-amd64", &KernelVersionInfo{Kernel: 3, Major: 12, Minor: 0, Flavor: "-1-amd64"}, 0)
179
-}
180
-
181
-func TestParsePortMapping(t *testing.T) {
182
-	data, err := PartParser("ip:public:private", "192.168.1.1:80:8080")
183
-	if err != nil {
184
-		t.Fatal(err)
185
-	}
186
-
187
-	if len(data) != 3 {
188
-		t.FailNow()
189
-	}
190
-	if data["ip"] != "192.168.1.1" {
191
-		t.Fail()
192
-	}
193
-	if data["public"] != "80" {
194
-		t.Fail()
195
-	}
196
-	if data["private"] != "8080" {
197
-		t.Fail()
198
-	}
199
-}
200
-
201 157
 func TestReplaceAndAppendEnvVars(t *testing.T) {
202 158
 	var (
203 159
 		d = []string{"HOME=/"}