瀏覽代碼

Merge pull request #7286 from erikh/parsers

Move parsing functions to parsers/ and the specific kernel handling...
Tibor Vass 11 年之前
父節點
當前提交
403df1765a

+ 9 - 8
api/client/commands.go

@@ -28,13 +28,14 @@ import (
 	"github.com/docker/docker/engine"
 	"github.com/docker/docker/nat"
 	"github.com/docker/docker/opts"
+	"github.com/docker/docker/pkg/parsers"
+	"github.com/docker/docker/pkg/parsers/filters"
 	"github.com/docker/docker/pkg/signal"
 	"github.com/docker/docker/pkg/term"
 	"github.com/docker/docker/pkg/units"
 	"github.com/docker/docker/registry"
 	"github.com/docker/docker/runconfig"
 	"github.com/docker/docker/utils"
-	"github.com/docker/docker/utils/filters"
 )
 
 const (
@@ -204,7 +205,7 @@ func (cli *DockerCli) CmdBuild(args ...string) error {
 
 	//Check if the given image name can be resolved
 	if *tag != "" {
-		repository, _ := utils.ParseRepositoryTag(*tag)
+		repository, _ := parsers.ParseRepositoryTag(*tag)
 		if _, _, err := registry.ResolveRepositoryName(repository); err != nil {
 			return err
 		}
@@ -1137,7 +1138,7 @@ func (cli *DockerCli) CmdPush(args ...string) error {
 
 	cli.LoadConfigFile()
 
-	remote, tag := utils.ParseRepositoryTag(name)
+	remote, tag := parsers.ParseRepositoryTag(name)
 
 	// Resolve the Repository name from fqn to hostname + name
 	hostname, _, err := registry.ResolveRepositoryName(remote)
@@ -1210,7 +1211,7 @@ func (cli *DockerCli) CmdPull(args ...string) error {
 		v.Set("tag", *tag)
 	}
 
-	remote, _ = utils.ParseRepositoryTag(remote)
+	remote, _ = parsers.ParseRepositoryTag(remote)
 	// Resolve the Repository name from fqn to hostname + name
 	hostname, _, err := registry.ResolveRepositoryName(remote)
 	if err != nil {
@@ -1393,7 +1394,7 @@ func (cli *DockerCli) CmdImages(args ...string) error {
 		for _, out := range outs.Data {
 			for _, repotag := range out.GetList("RepoTags") {
 
-				repo, tag := utils.ParseRepositoryTag(repotag)
+				repo, tag := parsers.ParseRepositoryTag(repotag)
 				outID := out.Get("Id")
 				if !*noTrunc {
 					outID = utils.TruncateID(outID)
@@ -1594,7 +1595,7 @@ func (cli *DockerCli) CmdCommit(args ...string) error {
 
 	var (
 		name            = cmd.Arg(0)
-		repository, tag = utils.ParseRepositoryTag(cmd.Arg(1))
+		repository, tag = parsers.ParseRepositoryTag(cmd.Arg(1))
 	)
 
 	if name == "" || len(cmd.Args()) > 2 {
@@ -1918,7 +1919,7 @@ func (cli *DockerCli) CmdTag(args ...string) error {
 	}
 
 	var (
-		repository, tag = utils.ParseRepositoryTag(cmd.Arg(1))
+		repository, tag = parsers.ParseRepositoryTag(cmd.Arg(1))
 		v               = url.Values{}
 	)
 
@@ -1941,7 +1942,7 @@ func (cli *DockerCli) CmdTag(args ...string) error {
 
 func (cli *DockerCli) pullImage(image string) error {
 	v := url.Values{}
-	repos, tag := utils.ParseRepositoryTag(image)
+	repos, tag := parsers.ParseRepositoryTag(image)
 	// pull only the image tagged 'latest' if no tag was specified
 	if tag == "" {
 		tag = "latest"

+ 2 - 1
api/common.go

@@ -6,6 +6,7 @@ import (
 	"strings"
 
 	"github.com/docker/docker/engine"
+	"github.com/docker/docker/pkg/parsers"
 	"github.com/docker/docker/pkg/version"
 	"github.com/docker/docker/utils"
 )
@@ -17,7 +18,7 @@ const (
 )
 
 func ValidateHost(val string) (string, error) {
-	host, err := utils.ParseHost(DEFAULTHTTPHOST, DEFAULTUNIXSOCKET, val)
+	host, err := parsers.ParseHost(DEFAULTHTTPHOST, DEFAULTUNIXSOCKET, val)
 	if err != nil {
 		return val, err
 	}

+ 3 - 2
api/server/server.go

@@ -25,6 +25,7 @@ import (
 	"github.com/docker/docker/api"
 	"github.com/docker/docker/engine"
 	"github.com/docker/docker/pkg/listenbuffer"
+	"github.com/docker/docker/pkg/parsers"
 	"github.com/docker/docker/pkg/systemd"
 	"github.com/docker/docker/pkg/user"
 	"github.com/docker/docker/pkg/version"
@@ -484,7 +485,7 @@ func postImagesCreate(eng *engine.Engine, version version.Version, w http.Respon
 	}
 	if image != "" { //pull
 		if tag == "" {
-			image, tag = utils.ParseRepositoryTag(image)
+			image, tag = parsers.ParseRepositoryTag(image)
 		}
 		metaHeaders := map[string][]string{}
 		for k, v := range r.Header {
@@ -498,7 +499,7 @@ func postImagesCreate(eng *engine.Engine, version version.Version, w http.Respon
 		job.SetenvJson("authConfig", authConfig)
 	} else { //import
 		if tag == "" {
-			repo, tag = utils.ParseRepositoryTag(repo)
+			repo, tag = parsers.ParseRepositoryTag(repo)
 		}
 		job = eng.Job("import", r.Form.Get("fromSrc"), repo, tag)
 		job.Stdin.Add(r.Body)

+ 2 - 1
builder/builder.go

@@ -23,6 +23,7 @@ import (
 	"github.com/docker/docker/daemon"
 	"github.com/docker/docker/engine"
 	"github.com/docker/docker/nat"
+	"github.com/docker/docker/pkg/parsers"
 	"github.com/docker/docker/pkg/symlink"
 	"github.com/docker/docker/pkg/system"
 	"github.com/docker/docker/registry"
@@ -86,7 +87,7 @@ func (b *buildFile) CmdFrom(name string) error {
 	image, err := b.daemon.Repositories().LookupImage(name)
 	if err != nil {
 		if b.daemon.Graph().IsNotExist(err) {
-			remote, tag := utils.ParseRepositoryTag(name)
+			remote, tag := parsers.ParseRepositoryTag(name)
 			pullRegistryAuth := b.authConfig
 			if len(b.configFile.Configs) > 0 {
 				// The request came with a full auth config file, we prefer to use that

+ 2 - 2
builtins/builtins.go

@@ -8,9 +8,9 @@ import (
 	"github.com/docker/docker/daemon/networkdriver/bridge"
 	"github.com/docker/docker/dockerversion"
 	"github.com/docker/docker/engine"
+	"github.com/docker/docker/pkg/parsers/kernel"
 	"github.com/docker/docker/registry"
 	"github.com/docker/docker/server"
-	"github.com/docker/docker/utils"
 )
 
 func Register(eng *engine.Engine) error {
@@ -68,7 +68,7 @@ func dockerVersion(job *engine.Job) engine.Status {
 	v.Set("GoVersion", runtime.Version())
 	v.Set("Os", runtime.GOOS)
 	v.Set("Arch", runtime.GOARCH)
-	if kernelVersion, err := utils.GetKernelVersion(); err == nil {
+	if kernelVersion, err := kernel.GetKernelVersion(); err == nil {
 		v.Set("KernelVersion", kernelVersion.String())
 	}
 	if _, err := v.WriteTo(job.Stdout); err != nil {

+ 2 - 1
daemon/daemon.go

@@ -28,6 +28,7 @@ import (
 	"github.com/docker/docker/pkg/graphdb"
 	"github.com/docker/docker/pkg/namesgenerator"
 	"github.com/docker/docker/pkg/networkfs/resolvconf"
+	"github.com/docker/docker/pkg/parsers"
 	"github.com/docker/docker/pkg/sysinfo"
 	"github.com/docker/docker/pkg/truncindex"
 	"github.com/docker/docker/runconfig"
@@ -724,7 +725,7 @@ func (daemon *Daemon) RegisterLink(parent, child *Container, alias string) error
 func (daemon *Daemon) RegisterLinks(container *Container, hostConfig *runconfig.HostConfig) error {
 	if hostConfig != nil && hostConfig.Links != nil {
 		for _, l := range hostConfig.Links {
-			parts, err := utils.PartParser("name:alias", l)
+			parts, err := parsers.PartParser("name:alias", l)
 			if err != nil {
 				return err
 			}

+ 2 - 1
daemon/graphdriver/devmapper/deviceset.go

@@ -19,6 +19,7 @@ import (
 	"time"
 
 	"github.com/docker/docker/daemon/graphdriver"
+	"github.com/docker/docker/pkg/parsers"
 	"github.com/docker/docker/pkg/units"
 	"github.com/docker/docker/utils"
 	"github.com/docker/libcontainer/label"
@@ -1166,7 +1167,7 @@ func NewDeviceSet(root string, doInit bool, options []string) (*DeviceSet, error
 
 	foundBlkDiscard := false
 	for _, option := range options {
-		key, val, err := utils.ParseKeyValueOpt(option)
+		key, val, err := parsers.ParseKeyValueOpt(option)
 		if err != nil {
 			return nil, err
 		}

+ 2 - 1
daemon/networkdriver/bridge/driver.go

@@ -15,6 +15,7 @@ import (
 	"github.com/docker/docker/engine"
 	"github.com/docker/docker/pkg/iptables"
 	"github.com/docker/docker/pkg/networkfs/resolvconf"
+	"github.com/docker/docker/pkg/parsers/kernel"
 	"github.com/docker/docker/utils"
 	"github.com/docker/libcontainer/netlink"
 )
@@ -306,7 +307,7 @@ func createBridge(bridgeIP string) error {
 }
 
 func createBridgeIface(name string) error {
-	kv, err := utils.GetKernelVersion()
+	kv, err := kernel.GetKernelVersion()
 	// only set the bridge's mac address if the kernel version is > 3.3
 	// before that it was not supported
 	setBridgeMacAddr := err == nil && (kv.Kernel >= 3 && kv.Major >= 3)

+ 3 - 2
docker/docker.go

@@ -19,6 +19,7 @@ import (
 	"github.com/docker/docker/engine"
 	"github.com/docker/docker/opts"
 	flag "github.com/docker/docker/pkg/mflag"
+	"github.com/docker/docker/pkg/parsers/kernel"
 	"github.com/docker/docker/sysinit"
 	"github.com/docker/docker/utils"
 )
@@ -292,10 +293,10 @@ func checkKernelAndArch() error {
 	// without actually causing a kernel panic, so we need this workaround until
 	// the circumstances of pre-3.8 crashes are clearer.
 	// For details see http://github.com/docker/docker/issues/407
-	if k, err := utils.GetKernelVersion(); err != nil {
+	if k, err := kernel.GetKernelVersion(); err != nil {
 		log.Printf("WARNING: %s\n", err)
 	} else {
-		if utils.CompareKernelVersion(k, &utils.KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0}) < 0 {
+		if kernel.CompareKernelVersion(k, &kernel.KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0}) < 0 {
 			if os.Getenv("DOCKER_NOWARN_KERNEL_VERSION") == "" {
 				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())
 			}

+ 2 - 1
graph/service.go

@@ -5,6 +5,7 @@ import (
 
 	"github.com/docker/docker/engine"
 	"github.com/docker/docker/image"
+	"github.com/docker/docker/pkg/parsers"
 	"github.com/docker/docker/utils"
 )
 
@@ -78,7 +79,7 @@ func (s *TagStore) CmdTag(job *engine.Job) engine.Status {
 		newName = job.Args[0]
 		oldName = job.Args[1]
 	)
-	newRepo, newTag := utils.ParseRepositoryTag(newName)
+	newRepo, newTag := parsers.ParseRepositoryTag(newName)
 	// FIXME: Set should either parse both old and new name, or neither.
 	// 	the current prototype is inconsistent.
 	if err := s.Set(newRepo, newTag, oldName, true); err != nil {

+ 2 - 1
graph/tags.go

@@ -11,6 +11,7 @@ import (
 	"sync"
 
 	"github.com/docker/docker/image"
+	"github.com/docker/docker/pkg/parsers"
 	"github.com/docker/docker/utils"
 )
 
@@ -72,7 +73,7 @@ func (store *TagStore) reload() error {
 func (store *TagStore) LookupImage(name string) (*image.Image, error) {
 	// FIXME: standardize on returning nil when the image doesn't exist, and err for everything else
 	// (so we can pass all errors here)
-	repos, tag := utils.ParseRepositoryTag(name)
+	repos, tag := parsers.ParseRepositoryTag(name)
 	if tag == "" {
 		tag = DEFAULTTAG
 	}

+ 2 - 2
nat/nat.go

@@ -8,7 +8,7 @@ import (
 	"strconv"
 	"strings"
 
-	"github.com/docker/docker/utils"
+	"github.com/docker/docker/pkg/parsers"
 )
 
 const (
@@ -103,7 +103,7 @@ func ParsePortSpecs(ports []string) (map[Port]struct{}, map[Port][]PortBinding,
 			rawPort = fmt.Sprintf(":%s", rawPort)
 		}
 
-		parts, err := utils.PartParser(PortSpecTemplate, rawPort)
+		parts, err := parsers.PartParser(PortSpecTemplate, rawPort)
 		if err != nil {
 			return nil, nil, err
 		}

+ 2 - 2
opts/opts.go

@@ -8,7 +8,7 @@ import (
 	"regexp"
 	"strings"
 
-	"github.com/docker/docker/utils"
+	"github.com/docker/docker/pkg/parsers"
 )
 
 // ListOpts type
@@ -94,7 +94,7 @@ func ValidateAttach(val string) (string, error) {
 }
 
 func ValidateLink(val string) (string, error) {
-	if _, err := utils.PartParser("name:alias", val); err != nil {
+	if _, err := parsers.PartParser("name:alias", val); err != nil {
 		return val, err
 	}
 	return val, nil

+ 1 - 0
pkg/parsers/MAINTAINERS

@@ -0,0 +1 @@
+Erik Hollensbe <github@hollensbe.org> (@erikh)

+ 0 - 0
utils/filters/parse.go → pkg/parsers/filters/parse.go


+ 0 - 0
utils/filters/parse_test.go → pkg/parsers/filters/parse_test.go


+ 93 - 0
pkg/parsers/kernel/kernel.go

@@ -0,0 +1,93 @@
+package kernel
+
+import (
+	"bytes"
+	"errors"
+	"fmt"
+)
+
+type KernelVersionInfo struct {
+	Kernel int
+	Major  int
+	Minor  int
+	Flavor string
+}
+
+func (k *KernelVersionInfo) String() string {
+	return fmt.Sprintf("%d.%d.%d%s", k.Kernel, k.Major, k.Minor, k.Flavor)
+}
+
+// Compare two KernelVersionInfo struct.
+// Returns -1 if a < b, 0 if a == b, 1 it a > b
+func CompareKernelVersion(a, b *KernelVersionInfo) int {
+	if a.Kernel < b.Kernel {
+		return -1
+	} else if a.Kernel > b.Kernel {
+		return 1
+	}
+
+	if a.Major < b.Major {
+		return -1
+	} else if a.Major > b.Major {
+		return 1
+	}
+
+	if a.Minor < b.Minor {
+		return -1
+	} else if a.Minor > b.Minor {
+		return 1
+	}
+
+	return 0
+}
+
+func GetKernelVersion() (*KernelVersionInfo, error) {
+	var (
+		err error
+	)
+
+	uts, err := uname()
+	if err != nil {
+		return nil, err
+	}
+
+	release := make([]byte, len(uts.Release))
+
+	i := 0
+	for _, c := range uts.Release {
+		release[i] = byte(c)
+		i++
+	}
+
+	// Remove the \x00 from the release for Atoi to parse correctly
+	release = release[:bytes.IndexByte(release, 0)]
+
+	return ParseRelease(string(release))
+}
+
+func ParseRelease(release string) (*KernelVersionInfo, error) {
+	var (
+		kernel, major, minor, parsed int
+		flavor, partial              string
+	)
+
+	// Ignore error from Sscanf to allow an empty flavor.  Instead, just
+	// make sure we got all the version numbers.
+	parsed, _ = fmt.Sscanf(release, "%d.%d%s", &kernel, &major, &partial)
+	if parsed < 2 {
+		return nil, errors.New("Can't parse kernel version " + release)
+	}
+
+	// sometimes we have 3.12.25-gentoo, but sometimes we just have 3.12-1-amd64
+	parsed, _ = fmt.Sscanf(partial, ".%d%s", &minor, &flavor)
+	if parsed < 1 {
+		flavor = partial
+	}
+
+	return &KernelVersionInfo{
+		Kernel: kernel,
+		Major:  major,
+		Minor:  minor,
+		Flavor: flavor,
+	}, nil
+}

+ 61 - 0
pkg/parsers/kernel/kernel_test.go

@@ -0,0 +1,61 @@
+package kernel
+
+import (
+	"testing"
+)
+
+func assertParseRelease(t *testing.T, release string, b *KernelVersionInfo, result int) {
+	var (
+		a *KernelVersionInfo
+	)
+	a, _ = ParseRelease(release)
+
+	if r := CompareKernelVersion(a, b); r != result {
+		t.Fatalf("Unexpected kernel version comparison result. Found %d, expected %d", r, result)
+	}
+	if a.Flavor != b.Flavor {
+		t.Fatalf("Unexpected parsed kernel flavor.  Found %s, expected %s", a.Flavor, b.Flavor)
+	}
+}
+
+func TestParseRelease(t *testing.T) {
+	assertParseRelease(t, "3.8.0", &KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0}, 0)
+	assertParseRelease(t, "3.4.54.longterm-1", &KernelVersionInfo{Kernel: 3, Major: 4, Minor: 54, Flavor: ".longterm-1"}, 0)
+	assertParseRelease(t, "3.4.54.longterm-1", &KernelVersionInfo{Kernel: 3, Major: 4, Minor: 54, Flavor: ".longterm-1"}, 0)
+	assertParseRelease(t, "3.8.0-19-generic", &KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0, Flavor: "-19-generic"}, 0)
+	assertParseRelease(t, "3.12.8tag", &KernelVersionInfo{Kernel: 3, Major: 12, Minor: 8, Flavor: "tag"}, 0)
+	assertParseRelease(t, "3.12-1-amd64", &KernelVersionInfo{Kernel: 3, Major: 12, Minor: 0, Flavor: "-1-amd64"}, 0)
+}
+
+func assertKernelVersion(t *testing.T, a, b *KernelVersionInfo, result int) {
+	if r := CompareKernelVersion(a, b); r != result {
+		t.Fatalf("Unexpected kernel version comparison result. Found %d, expected %d", r, result)
+	}
+}
+
+func TestCompareKernelVersion(t *testing.T) {
+	assertKernelVersion(t,
+		&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
+		&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
+		0)
+	assertKernelVersion(t,
+		&KernelVersionInfo{Kernel: 2, Major: 6, Minor: 0},
+		&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
+		-1)
+	assertKernelVersion(t,
+		&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
+		&KernelVersionInfo{Kernel: 2, Major: 6, Minor: 0},
+		1)
+	assertKernelVersion(t,
+		&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
+		&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
+		0)
+	assertKernelVersion(t,
+		&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 5},
+		&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
+		1)
+	assertKernelVersion(t,
+		&KernelVersionInfo{Kernel: 3, Major: 0, Minor: 20},
+		&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
+		-1)
+}

+ 1 - 1
utils/uname_linux.go → pkg/parsers/kernel/uname_linux.go

@@ -1,6 +1,6 @@
 // +build amd64
 
-package utils
+package kernel
 
 import (
 	"syscall"

+ 1 - 1
utils/uname_unsupported.go → pkg/parsers/kernel/uname_unsupported.go

@@ -1,6 +1,6 @@
 // +build !linux !amd64
 
-package utils
+package kernel
 
 import (
 	"errors"

+ 110 - 0
pkg/parsers/parsers.go

@@ -0,0 +1,110 @@
+package parsers
+
+import (
+	"fmt"
+	"strconv"
+	"strings"
+)
+
+// FIXME: Change this not to receive default value as parameter
+func ParseHost(defaultHost string, defaultUnix, addr string) (string, error) {
+	var (
+		proto string
+		host  string
+		port  int
+	)
+	addr = strings.TrimSpace(addr)
+	switch {
+	case addr == "tcp://":
+		return "", fmt.Errorf("Invalid bind address format: %s", addr)
+	case strings.HasPrefix(addr, "unix://"):
+		proto = "unix"
+		addr = strings.TrimPrefix(addr, "unix://")
+		if addr == "" {
+			addr = defaultUnix
+		}
+	case strings.HasPrefix(addr, "tcp://"):
+		proto = "tcp"
+		addr = strings.TrimPrefix(addr, "tcp://")
+	case strings.HasPrefix(addr, "fd://"):
+		return addr, nil
+	case addr == "":
+		proto = "unix"
+		addr = defaultUnix
+	default:
+		if strings.Contains(addr, "://") {
+			return "", fmt.Errorf("Invalid bind address protocol: %s", addr)
+		}
+		proto = "tcp"
+	}
+
+	if proto != "unix" && strings.Contains(addr, ":") {
+		hostParts := strings.Split(addr, ":")
+		if len(hostParts) != 2 {
+			return "", fmt.Errorf("Invalid bind address format: %s", addr)
+		}
+		if hostParts[0] != "" {
+			host = hostParts[0]
+		} else {
+			host = defaultHost
+		}
+
+		if p, err := strconv.Atoi(hostParts[1]); err == nil && p != 0 {
+			port = p
+		} else {
+			return "", fmt.Errorf("Invalid bind address format: %s", addr)
+		}
+
+	} else if proto == "tcp" && !strings.Contains(addr, ":") {
+		return "", fmt.Errorf("Invalid bind address format: %s", addr)
+	} else {
+		host = addr
+	}
+	if proto == "unix" {
+		return fmt.Sprintf("%s://%s", proto, host), nil
+	}
+	return fmt.Sprintf("%s://%s:%d", proto, host, port), nil
+}
+
+// Get a repos name and returns the right reposName + tag
+// The tag can be confusing because of a port in a repository name.
+//     Ex: localhost.localdomain:5000/samalba/hipache:latest
+func ParseRepositoryTag(repos string) (string, string) {
+	n := strings.LastIndex(repos, ":")
+	if n < 0 {
+		return repos, ""
+	}
+	if tag := repos[n+1:]; !strings.Contains(tag, "/") {
+		return repos[:n], tag
+	}
+	return repos, ""
+}
+
+func PartParser(template, data string) (map[string]string, error) {
+	// ip:public:private
+	var (
+		templateParts = strings.Split(template, ":")
+		parts         = strings.Split(data, ":")
+		out           = make(map[string]string, len(templateParts))
+	)
+	if len(parts) != len(templateParts) {
+		return nil, fmt.Errorf("Invalid format to parse.  %s should match template %s", data, template)
+	}
+
+	for i, t := range templateParts {
+		value := ""
+		if len(parts) > i {
+			value = parts[i]
+		}
+		out[t] = value
+	}
+	return out, nil
+}
+
+func ParseKeyValueOpt(opt string) (string, string, error) {
+	parts := strings.SplitN(opt, "=", 2)
+	if len(parts) != 2 {
+		return "", "", fmt.Errorf("Unable to parse key/value option: %s", opt)
+	}
+	return strings.TrimSpace(parts[0]), strings.TrimSpace(parts[1]), nil
+}

+ 83 - 0
pkg/parsers/parsers_test.go

@@ -0,0 +1,83 @@
+package parsers
+
+import (
+	"testing"
+)
+
+func TestParseHost(t *testing.T) {
+	var (
+		defaultHttpHost = "127.0.0.1"
+		defaultUnix     = "/var/run/docker.sock"
+	)
+	if addr, err := ParseHost(defaultHttpHost, defaultUnix, "0.0.0.0"); err == nil {
+		t.Errorf("tcp 0.0.0.0 address expected error return, but err == nil, got %s", addr)
+	}
+	if addr, err := ParseHost(defaultHttpHost, defaultUnix, "tcp://"); err == nil {
+		t.Errorf("default tcp:// address expected error return, but err == nil, got %s", addr)
+	}
+	if addr, err := ParseHost(defaultHttpHost, defaultUnix, "0.0.0.1:5555"); err != nil || addr != "tcp://0.0.0.1:5555" {
+		t.Errorf("0.0.0.1:5555 -> expected tcp://0.0.0.1:5555, got %s", addr)
+	}
+	if addr, err := ParseHost(defaultHttpHost, defaultUnix, ":6666"); err != nil || addr != "tcp://127.0.0.1:6666" {
+		t.Errorf(":6666 -> expected tcp://127.0.0.1:6666, got %s", addr)
+	}
+	if addr, err := ParseHost(defaultHttpHost, defaultUnix, "tcp://:7777"); err != nil || addr != "tcp://127.0.0.1:7777" {
+		t.Errorf("tcp://:7777 -> expected tcp://127.0.0.1:7777, got %s", addr)
+	}
+	if addr, err := ParseHost(defaultHttpHost, defaultUnix, ""); err != nil || addr != "unix:///var/run/docker.sock" {
+		t.Errorf("empty argument -> expected unix:///var/run/docker.sock, got %s", addr)
+	}
+	if addr, err := ParseHost(defaultHttpHost, defaultUnix, "unix:///var/run/docker.sock"); err != nil || addr != "unix:///var/run/docker.sock" {
+		t.Errorf("unix:///var/run/docker.sock -> expected unix:///var/run/docker.sock, got %s", addr)
+	}
+	if addr, err := ParseHost(defaultHttpHost, defaultUnix, "unix://"); err != nil || addr != "unix:///var/run/docker.sock" {
+		t.Errorf("unix:///var/run/docker.sock -> expected unix:///var/run/docker.sock, got %s", addr)
+	}
+	if addr, err := ParseHost(defaultHttpHost, defaultUnix, "udp://127.0.0.1"); err == nil {
+		t.Errorf("udp protocol address expected error return, but err == nil. Got %s", addr)
+	}
+	if addr, err := ParseHost(defaultHttpHost, defaultUnix, "udp://127.0.0.1:2375"); err == nil {
+		t.Errorf("udp protocol address expected error return, but err == nil. Got %s", addr)
+	}
+}
+
+func TestParseRepositoryTag(t *testing.T) {
+	if repo, tag := ParseRepositoryTag("root"); repo != "root" || tag != "" {
+		t.Errorf("Expected repo: '%s' and tag: '%s', got '%s' and '%s'", "root", "", repo, tag)
+	}
+	if repo, tag := ParseRepositoryTag("root:tag"); repo != "root" || tag != "tag" {
+		t.Errorf("Expected repo: '%s' and tag: '%s', got '%s' and '%s'", "root", "tag", repo, tag)
+	}
+	if repo, tag := ParseRepositoryTag("user/repo"); repo != "user/repo" || tag != "" {
+		t.Errorf("Expected repo: '%s' and tag: '%s', got '%s' and '%s'", "user/repo", "", repo, tag)
+	}
+	if repo, tag := ParseRepositoryTag("user/repo:tag"); repo != "user/repo" || tag != "tag" {
+		t.Errorf("Expected repo: '%s' and tag: '%s', got '%s' and '%s'", "user/repo", "tag", repo, tag)
+	}
+	if repo, tag := ParseRepositoryTag("url:5000/repo"); repo != "url:5000/repo" || tag != "" {
+		t.Errorf("Expected repo: '%s' and tag: '%s', got '%s' and '%s'", "url:5000/repo", "", repo, tag)
+	}
+	if repo, tag := ParseRepositoryTag("url:5000/repo:tag"); repo != "url:5000/repo" || tag != "tag" {
+		t.Errorf("Expected repo: '%s' and tag: '%s', got '%s' and '%s'", "url:5000/repo", "tag", repo, tag)
+	}
+}
+
+func TestParsePortMapping(t *testing.T) {
+	data, err := PartParser("ip:public:private", "192.168.1.1:80:8080")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if len(data) != 3 {
+		t.FailNow()
+	}
+	if data["ip"] != "192.168.1.1" {
+		t.Fail()
+	}
+	if data["public"] != "80" {
+		t.Fail()
+	}
+	if data["private"] != "8080" {
+		t.Fail()
+	}
+}

+ 2 - 1
registry/registry.go

@@ -25,6 +25,7 @@ import (
 
 	"github.com/docker/docker/dockerversion"
 	"github.com/docker/docker/pkg/httputils"
+	"github.com/docker/docker/pkg/parsers/kernel"
 	"github.com/docker/docker/utils"
 )
 
@@ -956,7 +957,7 @@ func HTTPRequestFactory(metaHeaders map[string][]string) *utils.HTTPRequestFacto
 	httpVersion = append(httpVersion, &simpleVersionInfo{"docker", dockerversion.VERSION})
 	httpVersion = append(httpVersion, &simpleVersionInfo{"go", runtime.Version()})
 	httpVersion = append(httpVersion, &simpleVersionInfo{"git-commit", dockerversion.GITCOMMIT})
-	if kernelVersion, err := utils.GetKernelVersion(); err == nil {
+	if kernelVersion, err := kernel.GetKernelVersion(); err == nil {
 		httpVersion = append(httpVersion, &simpleVersionInfo{"kernel", kernelVersion.String()})
 	}
 	httpVersion = append(httpVersion, &simpleVersionInfo{"os", runtime.GOOS})

+ 2 - 1
runconfig/parse.go

@@ -9,6 +9,7 @@ import (
 	"github.com/docker/docker/nat"
 	"github.com/docker/docker/opts"
 	flag "github.com/docker/docker/pkg/mflag"
+	"github.com/docker/docker/pkg/parsers"
 	"github.com/docker/docker/pkg/sysinfo"
 	"github.com/docker/docker/pkg/units"
 	"github.com/docker/docker/utils"
@@ -306,7 +307,7 @@ func parseDriverOpts(opts opts.ListOpts) (map[string][]string, error) {
 func parseKeyValueOpts(opts opts.ListOpts) ([]utils.KeyValuePair, error) {
 	out := make([]utils.KeyValuePair, opts.Len())
 	for i, o := range opts.GetAll() {
-		k, v, err := utils.ParseKeyValueOpt(o)
+		k, v, err := parsers.ParseKeyValueOpt(o)
 		if err != nil {
 			return nil, err
 		}

+ 2 - 2
runconfig/parse_test.go

@@ -3,14 +3,14 @@ package runconfig
 import (
 	"testing"
 
-	"github.com/docker/docker/utils"
+	"github.com/docker/docker/pkg/parsers"
 )
 
 func TestParseLxcConfOpt(t *testing.T) {
 	opts := []string{"lxc.utsname=docker", "lxc.utsname = docker "}
 
 	for _, o := range opts {
-		k, v, err := utils.ParseKeyValueOpt(o)
+		k, v, err := parsers.ParseKeyValueOpt(o)
 		if err != nil {
 			t.FailNow()
 		}

+ 9 - 7
server/server.go

@@ -54,12 +54,14 @@ import (
 	"github.com/docker/docker/graph"
 	"github.com/docker/docker/image"
 	"github.com/docker/docker/pkg/graphdb"
+	"github.com/docker/docker/pkg/parsers"
+	"github.com/docker/docker/pkg/parsers/filters"
+	"github.com/docker/docker/pkg/parsers/kernel"
 	"github.com/docker/docker/pkg/signal"
 	"github.com/docker/docker/pkg/tailfile"
 	"github.com/docker/docker/registry"
 	"github.com/docker/docker/runconfig"
 	"github.com/docker/docker/utils"
-	"github.com/docker/docker/utils/filters"
 )
 
 func (srv *Server) handlerWrap(h engine.Handler) engine.Handler {
@@ -383,7 +385,7 @@ func (srv *Server) ImageExport(job *engine.Job) engine.Status {
 		}
 		if img != nil {
 			// This is a named image like 'busybox:latest'
-			repoName, repoTag := utils.ParseRepositoryTag(name)
+			repoName, repoTag := parsers.ParseRepositoryTag(name)
 			if err := srv.exportImage(job.Eng, img.ID, tempdir); err != nil {
 				return job.Error(err)
 			}
@@ -493,7 +495,7 @@ func (srv *Server) Build(job *engine.Job) engine.Status {
 	)
 	job.GetenvJson("authConfig", authConfig)
 	job.GetenvJson("configFile", configFile)
-	repoName, tag = utils.ParseRepositoryTag(repoName)
+	repoName, tag = parsers.ParseRepositoryTag(repoName)
 
 	if remoteURL == "" {
 		context = ioutil.NopCloser(job.Stdin)
@@ -789,7 +791,7 @@ func (srv *Server) DockerInfo(job *engine.Job) engine.Status {
 		imgcount = len(images)
 	}
 	kernelVersion := "<unknown>"
-	if kv, err := utils.GetKernelVersion(); err == nil {
+	if kv, err := kernel.GetKernelVersion(); err == nil {
 		kernelVersion = kv.String()
 	}
 
@@ -1746,7 +1748,7 @@ func (srv *Server) ContainerCreate(job *engine.Job) engine.Status {
 	container, buildWarnings, err := srv.daemon.Create(config, name)
 	if err != nil {
 		if srv.daemon.Graph().IsNotExist(err) {
-			_, tag := utils.ParseRepositoryTag(config.Image)
+			_, tag := parsers.ParseRepositoryTag(config.Image)
 			if tag == "" {
 				tag = graph.DEFAULTTAG
 			}
@@ -1924,7 +1926,7 @@ func (srv *Server) DeleteImage(name string, imgs *engine.Table, first, force, no
 		tagDeleted    bool
 	)
 
-	repoName, tag = utils.ParseRepositoryTag(name)
+	repoName, tag = parsers.ParseRepositoryTag(name)
 	if tag == "" {
 		tag = graph.DEFAULTTAG
 	}
@@ -1950,7 +1952,7 @@ func (srv *Server) DeleteImage(name string, imgs *engine.Table, first, force, no
 	//If delete by id, see if the id belong only to one repository
 	if repoName == "" {
 		for _, repoAndTag := range srv.daemon.Repositories().ByID()[img.ID] {
-			parsedRepo, parsedTag := utils.ParseRepositoryTag(repoAndTag)
+			parsedRepo, parsedTag := parsers.ParseRepositoryTag(repoAndTag)
 			if repoName == "" || repoName == parsedRepo {
 				repoName = parsedRepo
 				if parsedTag != "" {

+ 0 - 190
utils/utils.go

@@ -7,7 +7,6 @@ import (
 	"crypto/sha256"
 	"encoding/hex"
 	"encoding/json"
-	"errors"
 	"fmt"
 	"io"
 	"io/ioutil"
@@ -401,92 +400,6 @@ func HashData(src io.Reader) (string, error) {
 	return "sha256:" + hex.EncodeToString(h.Sum(nil)), nil
 }
 
-type KernelVersionInfo struct {
-	Kernel int
-	Major  int
-	Minor  int
-	Flavor string
-}
-
-func (k *KernelVersionInfo) String() string {
-	return fmt.Sprintf("%d.%d.%d%s", k.Kernel, k.Major, k.Minor, k.Flavor)
-}
-
-// Compare two KernelVersionInfo struct.
-// Returns -1 if a < b, 0 if a == b, 1 it a > b
-func CompareKernelVersion(a, b *KernelVersionInfo) int {
-	if a.Kernel < b.Kernel {
-		return -1
-	} else if a.Kernel > b.Kernel {
-		return 1
-	}
-
-	if a.Major < b.Major {
-		return -1
-	} else if a.Major > b.Major {
-		return 1
-	}
-
-	if a.Minor < b.Minor {
-		return -1
-	} else if a.Minor > b.Minor {
-		return 1
-	}
-
-	return 0
-}
-
-func GetKernelVersion() (*KernelVersionInfo, error) {
-	var (
-		err error
-	)
-
-	uts, err := uname()
-	if err != nil {
-		return nil, err
-	}
-
-	release := make([]byte, len(uts.Release))
-
-	i := 0
-	for _, c := range uts.Release {
-		release[i] = byte(c)
-		i++
-	}
-
-	// Remove the \x00 from the release for Atoi to parse correctly
-	release = release[:bytes.IndexByte(release, 0)]
-
-	return ParseRelease(string(release))
-}
-
-func ParseRelease(release string) (*KernelVersionInfo, error) {
-	var (
-		kernel, major, minor, parsed int
-		flavor, partial              string
-	)
-
-	// Ignore error from Sscanf to allow an empty flavor.  Instead, just
-	// make sure we got all the version numbers.
-	parsed, _ = fmt.Sscanf(release, "%d.%d%s", &kernel, &major, &partial)
-	if parsed < 2 {
-		return nil, errors.New("Can't parse kernel version " + release)
-	}
-
-	// sometimes we have 3.12.25-gentoo, but sometimes we just have 3.12-1-amd64
-	parsed, _ = fmt.Sscanf(partial, ".%d%s", &minor, &flavor)
-	if parsed < 1 {
-		flavor = partial
-	}
-
-	return &KernelVersionInfo{
-		Kernel: kernel,
-		Major:  major,
-		Minor:  minor,
-		Flavor: flavor,
-	}, nil
-}
-
 // FIXME: this is deprecated by CopyWithTar in archive.go
 func CopyDirectory(source, dest string) error {
 	if output, err := exec.Command("cp", "-ra", source, dest).CombinedOutput(); err != nil {
@@ -580,80 +493,6 @@ func GetLines(input []byte, commentMarker []byte) [][]byte {
 	return output
 }
 
-// FIXME: Change this not to receive default value as parameter
-func ParseHost(defaultHost string, defaultUnix, addr string) (string, error) {
-	var (
-		proto string
-		host  string
-		port  int
-	)
-	addr = strings.TrimSpace(addr)
-	switch {
-	case addr == "tcp://":
-		return "", fmt.Errorf("Invalid bind address format: %s", addr)
-	case strings.HasPrefix(addr, "unix://"):
-		proto = "unix"
-		addr = strings.TrimPrefix(addr, "unix://")
-		if addr == "" {
-			addr = defaultUnix
-		}
-	case strings.HasPrefix(addr, "tcp://"):
-		proto = "tcp"
-		addr = strings.TrimPrefix(addr, "tcp://")
-	case strings.HasPrefix(addr, "fd://"):
-		return addr, nil
-	case addr == "":
-		proto = "unix"
-		addr = defaultUnix
-	default:
-		if strings.Contains(addr, "://") {
-			return "", fmt.Errorf("Invalid bind address protocol: %s", addr)
-		}
-		proto = "tcp"
-	}
-
-	if proto != "unix" && strings.Contains(addr, ":") {
-		hostParts := strings.Split(addr, ":")
-		if len(hostParts) != 2 {
-			return "", fmt.Errorf("Invalid bind address format: %s", addr)
-		}
-		if hostParts[0] != "" {
-			host = hostParts[0]
-		} else {
-			host = defaultHost
-		}
-
-		if p, err := strconv.Atoi(hostParts[1]); err == nil && p != 0 {
-			port = p
-		} else {
-			return "", fmt.Errorf("Invalid bind address format: %s", addr)
-		}
-
-	} else if proto == "tcp" && !strings.Contains(addr, ":") {
-		return "", fmt.Errorf("Invalid bind address format: %s", addr)
-	} else {
-		host = addr
-	}
-	if proto == "unix" {
-		return fmt.Sprintf("%s://%s", proto, host), nil
-	}
-	return fmt.Sprintf("%s://%s:%d", proto, host, port), nil
-}
-
-// Get a repos name and returns the right reposName + tag
-// The tag can be confusing because of a port in a repository name.
-//     Ex: localhost.localdomain:5000/samalba/hipache:latest
-func ParseRepositoryTag(repos string) (string, string) {
-	n := strings.LastIndex(repos, ":")
-	if n < 0 {
-		return repos, ""
-	}
-	if tag := repos[n+1:]; !strings.Contains(tag, "/") {
-		return repos[:n], tag
-	}
-	return repos, ""
-}
-
 // An StatusError reports an unsuccessful exit by a command.
 type StatusError struct {
 	Status     string
@@ -699,27 +538,6 @@ func ShellQuoteArguments(args []string) string {
 	return buf.String()
 }
 
-func PartParser(template, data string) (map[string]string, error) {
-	// ip:public:private
-	var (
-		templateParts = strings.Split(template, ":")
-		parts         = strings.Split(data, ":")
-		out           = make(map[string]string, len(templateParts))
-	)
-	if len(parts) != len(templateParts) {
-		return nil, fmt.Errorf("Invalid format to parse.  %s should match template %s", data, template)
-	}
-
-	for i, t := range templateParts {
-		value := ""
-		if len(parts) > i {
-			value = parts[i]
-		}
-		out[t] = value
-	}
-	return out, nil
-}
-
 var globalTestID string
 
 // TestDirectory creates a new temporary directory and returns its path.
@@ -833,14 +651,6 @@ func ReadSymlinkedDirectory(path string) (string, error) {
 	return realPath, nil
 }
 
-func ParseKeyValueOpt(opt string) (string, string, error) {
-	parts := strings.SplitN(opt, "=", 2)
-	if len(parts) != 2 {
-		return "", "", fmt.Errorf("Unable to parse key/value option: %s", opt)
-	}
-	return strings.TrimSpace(parts[0]), strings.TrimSpace(parts[1]), nil
-}
-
 // TreeSize walks a directory tree and returns its total size in bytes.
 func TreeSize(dir string) (size int64, err error) {
 	data := make(map[uint64]struct{})

+ 0 - 135
utils/utils_test.go

@@ -34,97 +34,6 @@ func TestBufReader(t *testing.T) {
 	}
 }
 
-func assertKernelVersion(t *testing.T, a, b *KernelVersionInfo, result int) {
-	if r := CompareKernelVersion(a, b); r != result {
-		t.Fatalf("Unexpected kernel version comparison result. Found %d, expected %d", r, result)
-	}
-}
-
-func TestCompareKernelVersion(t *testing.T) {
-	assertKernelVersion(t,
-		&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
-		&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
-		0)
-	assertKernelVersion(t,
-		&KernelVersionInfo{Kernel: 2, Major: 6, Minor: 0},
-		&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
-		-1)
-	assertKernelVersion(t,
-		&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
-		&KernelVersionInfo{Kernel: 2, Major: 6, Minor: 0},
-		1)
-	assertKernelVersion(t,
-		&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
-		&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
-		0)
-	assertKernelVersion(t,
-		&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 5},
-		&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
-		1)
-	assertKernelVersion(t,
-		&KernelVersionInfo{Kernel: 3, Major: 0, Minor: 20},
-		&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
-		-1)
-}
-
-func TestParseHost(t *testing.T) {
-	var (
-		defaultHttpHost = "127.0.0.1"
-		defaultUnix     = "/var/run/docker.sock"
-	)
-	if addr, err := ParseHost(defaultHttpHost, defaultUnix, "0.0.0.0"); err == nil {
-		t.Errorf("tcp 0.0.0.0 address expected error return, but err == nil, got %s", addr)
-	}
-	if addr, err := ParseHost(defaultHttpHost, defaultUnix, "tcp://"); err == nil {
-		t.Errorf("default tcp:// address expected error return, but err == nil, got %s", addr)
-	}
-	if addr, err := ParseHost(defaultHttpHost, defaultUnix, "0.0.0.1:5555"); err != nil || addr != "tcp://0.0.0.1:5555" {
-		t.Errorf("0.0.0.1:5555 -> expected tcp://0.0.0.1:5555, got %s", addr)
-	}
-	if addr, err := ParseHost(defaultHttpHost, defaultUnix, ":6666"); err != nil || addr != "tcp://127.0.0.1:6666" {
-		t.Errorf(":6666 -> expected tcp://127.0.0.1:6666, got %s", addr)
-	}
-	if addr, err := ParseHost(defaultHttpHost, defaultUnix, "tcp://:7777"); err != nil || addr != "tcp://127.0.0.1:7777" {
-		t.Errorf("tcp://:7777 -> expected tcp://127.0.0.1:7777, got %s", addr)
-	}
-	if addr, err := ParseHost(defaultHttpHost, defaultUnix, ""); err != nil || addr != "unix:///var/run/docker.sock" {
-		t.Errorf("empty argument -> expected unix:///var/run/docker.sock, got %s", addr)
-	}
-	if addr, err := ParseHost(defaultHttpHost, defaultUnix, "unix:///var/run/docker.sock"); err != nil || addr != "unix:///var/run/docker.sock" {
-		t.Errorf("unix:///var/run/docker.sock -> expected unix:///var/run/docker.sock, got %s", addr)
-	}
-	if addr, err := ParseHost(defaultHttpHost, defaultUnix, "unix://"); err != nil || addr != "unix:///var/run/docker.sock" {
-		t.Errorf("unix:///var/run/docker.sock -> expected unix:///var/run/docker.sock, got %s", addr)
-	}
-	if addr, err := ParseHost(defaultHttpHost, defaultUnix, "udp://127.0.0.1"); err == nil {
-		t.Errorf("udp protocol address expected error return, but err == nil. Got %s", addr)
-	}
-	if addr, err := ParseHost(defaultHttpHost, defaultUnix, "udp://127.0.0.1:2375"); err == nil {
-		t.Errorf("udp protocol address expected error return, but err == nil. Got %s", addr)
-	}
-}
-
-func TestParseRepositoryTag(t *testing.T) {
-	if repo, tag := ParseRepositoryTag("root"); repo != "root" || tag != "" {
-		t.Errorf("Expected repo: '%s' and tag: '%s', got '%s' and '%s'", "root", "", repo, tag)
-	}
-	if repo, tag := ParseRepositoryTag("root:tag"); repo != "root" || tag != "tag" {
-		t.Errorf("Expected repo: '%s' and tag: '%s', got '%s' and '%s'", "root", "tag", repo, tag)
-	}
-	if repo, tag := ParseRepositoryTag("user/repo"); repo != "user/repo" || tag != "" {
-		t.Errorf("Expected repo: '%s' and tag: '%s', got '%s' and '%s'", "user/repo", "", repo, tag)
-	}
-	if repo, tag := ParseRepositoryTag("user/repo:tag"); repo != "user/repo" || tag != "tag" {
-		t.Errorf("Expected repo: '%s' and tag: '%s', got '%s' and '%s'", "user/repo", "tag", repo, tag)
-	}
-	if repo, tag := ParseRepositoryTag("url:5000/repo"); repo != "url:5000/repo" || tag != "" {
-		t.Errorf("Expected repo: '%s' and tag: '%s', got '%s' and '%s'", "url:5000/repo", "", repo, tag)
-	}
-	if repo, tag := ParseRepositoryTag("url:5000/repo:tag"); repo != "url:5000/repo" || tag != "tag" {
-		t.Errorf("Expected repo: '%s' and tag: '%s', got '%s' and '%s'", "url:5000/repo", "tag", repo, tag)
-	}
-}
-
 func TestCheckLocalDns(t *testing.T) {
 	for resolv, result := range map[string]bool{`# Dynamic
 nameserver 10.0.2.3
@@ -154,50 +63,6 @@ search docker.com`: true,
 		}
 	}
 }
-
-func assertParseRelease(t *testing.T, release string, b *KernelVersionInfo, result int) {
-	var (
-		a *KernelVersionInfo
-	)
-	a, _ = ParseRelease(release)
-
-	if r := CompareKernelVersion(a, b); r != result {
-		t.Fatalf("Unexpected kernel version comparison result. Found %d, expected %d", r, result)
-	}
-	if a.Flavor != b.Flavor {
-		t.Fatalf("Unexpected parsed kernel flavor.  Found %s, expected %s", a.Flavor, b.Flavor)
-	}
-}
-
-func TestParseRelease(t *testing.T) {
-	assertParseRelease(t, "3.8.0", &KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0}, 0)
-	assertParseRelease(t, "3.4.54.longterm-1", &KernelVersionInfo{Kernel: 3, Major: 4, Minor: 54, Flavor: ".longterm-1"}, 0)
-	assertParseRelease(t, "3.4.54.longterm-1", &KernelVersionInfo{Kernel: 3, Major: 4, Minor: 54, Flavor: ".longterm-1"}, 0)
-	assertParseRelease(t, "3.8.0-19-generic", &KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0, Flavor: "-19-generic"}, 0)
-	assertParseRelease(t, "3.12.8tag", &KernelVersionInfo{Kernel: 3, Major: 12, Minor: 8, Flavor: "tag"}, 0)
-	assertParseRelease(t, "3.12-1-amd64", &KernelVersionInfo{Kernel: 3, Major: 12, Minor: 0, Flavor: "-1-amd64"}, 0)
-}
-
-func TestParsePortMapping(t *testing.T) {
-	data, err := PartParser("ip:public:private", "192.168.1.1:80:8080")
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	if len(data) != 3 {
-		t.FailNow()
-	}
-	if data["ip"] != "192.168.1.1" {
-		t.Fail()
-	}
-	if data["public"] != "80" {
-		t.Fail()
-	}
-	if data["private"] != "8080" {
-		t.Fail()
-	}
-}
-
 func TestReplaceAndAppendEnvVars(t *testing.T) {
 	var (
 		d = []string{"HOME=/"}