Lint on pkg/* packages

- pkg/useragent
- pkg/units
- pkg/ulimit
- pkg/truncindex
- pkg/timeoutconn
- pkg/term
- pkg/tarsum
- pkg/tailfile
- pkg/systemd
- pkg/stringutils
- pkg/stringid
- pkg/streamformatter
- pkg/sockets
- pkg/signal
- pkg/proxy
- pkg/progressreader
- pkg/pools
- pkg/plugins
- pkg/pidfile
- pkg/parsers
- pkg/parsers/filters
- pkg/parsers/kernel
- pkg/parsers/operatingsystem

Signed-off-by: Vincent Demeester <vincent@sbr.pm>
This commit is contained in:
Vincent Demeester 2015-07-25 10:35:07 +02:00
parent a922d62168
commit 9bcb3cba83
56 changed files with 455 additions and 195 deletions

View file

@ -1,3 +1,5 @@
// Package filters provides helper function to parse and handle command line
// filter, used for example in docker ps or docker images commands.
package filters
import (
@ -7,16 +9,22 @@ import (
"strings"
)
// Args stores filter arguments as map key:{array of values}.
// It contains a aggregation of the list of arguments (which are in the form
// of -f 'key=value') based on the key, and store values for the same key
// in an slice.
// e.g given -f 'label=label1=1' -f 'label=label2=2' -f 'image.name=ubuntu'
// the args will be {'label': {'label1=1','label2=2'}, 'image.name', {'ubuntu'}}
type Args map[string][]string
// Parse the argument to the filter flag. Like
// ParseFlag parses the argument to the filter flag. Like
//
// `docker ps -f 'created=today' -f 'image.name=ubuntu*'`
//
// If prev map is provided, then it is appended to, and returned. By default a new
// map is created.
func ParseFlag(arg string, prev Args) (Args, error) {
var filters Args = prev
filters := prev
if prev == nil {
filters = Args{}
}
@ -25,7 +33,7 @@ func ParseFlag(arg string, prev Args) (Args, error) {
}
if !strings.Contains(arg, "=") {
return filters, ErrorBadFormat
return filters, ErrBadFormat
}
f := strings.SplitN(arg, "=", 2)
@ -36,9 +44,10 @@ func ParseFlag(arg string, prev Args) (Args, error) {
return filters, nil
}
var ErrorBadFormat = errors.New("bad format of filter (expected name=value)")
// ErrBadFormat is an error returned in case of bad format for a filter.
var ErrBadFormat = errors.New("bad format of filter (expected name=value)")
// packs the Args into an string for easy transport from client to server
// ToParam packs the Args into an string for easy transport from client to server.
func ToParam(a Args) (string, error) {
// this way we don't URL encode {}, just empty space
if len(a) == 0 {
@ -52,7 +61,7 @@ func ToParam(a Args) (string, error) {
return string(buf), nil
}
// unpacks the filter Args
// FromParam unpacks the filter Args.
func FromParam(p string) (Args, error) {
args := Args{}
if len(p) == 0 {
@ -64,6 +73,11 @@ func FromParam(p string) (Args, error) {
return args, nil
}
// MatchKVList returns true if the values for the specified field maches the ones
// from the sources.
// e.g. given Args are {'label': {'label1=1','label2=1'}, 'image.name', {'ubuntu'}},
// field is 'label' and sources are {'label':{'label1=1','label2=2','label3=3'}}
// it returns true.
func (filters Args) MatchKVList(field string, sources map[string]string) bool {
fieldValues := filters[field]
@ -96,6 +110,10 @@ outer:
return true
}
// Match returns true if the values for the specified field matches the source string
// e.g. given Args are {'label': {'label1=1','label2=1'}, 'image.name', {'ubuntu'}},
// field is 'image.name' and source is 'ubuntu'
// it returns true.
func (filters Args) Match(field, source string) bool {
fieldValues := filters[field]

View file

@ -39,8 +39,8 @@ func TestParseArgsEdgeCase(t *testing.T) {
if args == nil || len(args) != 0 {
t.Fatalf("Expected an empty Args (map), got %v", args)
}
if args, err = ParseFlag("anything", args); err == nil || err != ErrorBadFormat {
t.Fatalf("Expected ErrorBadFormat, got %v", err)
if args, err = ParseFlag("anything", args); err == nil || err != ErrBadFormat {
t.Fatalf("Expected ErrBadFormat, got %v", err)
}
}

View file

@ -1,5 +1,7 @@
// +build !windows
// Package kernel provides helper function to get, parse and compare kernel
// versions for different platforms.
package kernel
import (
@ -8,20 +10,21 @@ import (
"fmt"
)
type KernelVersionInfo struct {
Kernel int
Major int
Minor int
Flavor string
// VersionInfo holds information about the kernel.
type VersionInfo struct {
Kernel int // Version of the kernel (e.g. 4.1.2-generic -> 4)
Major int // Major part of the kernel version (e.g. 4.1.2-generic -> 1)
Minor int // Minor part of the kernel version (e.g. 4.1.2-generic -> 2)
Flavor string // Flavor of the kernel version (e.g. 4.1.2-generic -> generic)
}
func (k *KernelVersionInfo) String() string {
func (k *VersionInfo) String() string {
return fmt.Sprintf("%d.%d.%d%s", k.Kernel, k.Major, k.Minor, k.Flavor)
}
// Compare two KernelVersionInfo struct.
// CompareKernelVersion compares two kernel.VersionInfo structs.
// Returns -1 if a < b, 0 if a == b, 1 it a > b
func CompareKernelVersion(a, b *KernelVersionInfo) int {
func CompareKernelVersion(a, b VersionInfo) int {
if a.Kernel < b.Kernel {
return -1
} else if a.Kernel > b.Kernel {
@ -43,7 +46,8 @@ func CompareKernelVersion(a, b *KernelVersionInfo) int {
return 0
}
func GetKernelVersion() (*KernelVersionInfo, error) {
// GetKernelVersion gets the current kernel version.
func GetKernelVersion() (*VersionInfo, error) {
var (
err error
)
@ -67,7 +71,8 @@ func GetKernelVersion() (*KernelVersionInfo, error) {
return ParseRelease(string(release))
}
func ParseRelease(release string) (*KernelVersionInfo, error) {
// ParseRelease parses a string and creates a VersionInfo based on it.
func ParseRelease(release string) (*VersionInfo, error) {
var (
kernel, major, minor, parsed int
flavor, partial string
@ -86,7 +91,7 @@ func ParseRelease(release string) (*KernelVersionInfo, error) {
flavor = partial
}
return &KernelVersionInfo{
return &VersionInfo{
Kernel: kernel,
Major: major,
Minor: minor,

View file

@ -5,13 +5,13 @@ import (
"testing"
)
func assertParseRelease(t *testing.T, release string, b *KernelVersionInfo, result int) {
func assertParseRelease(t *testing.T, release string, b *VersionInfo, result int) {
var (
a *KernelVersionInfo
a *VersionInfo
)
a, _ = ParseRelease(release)
if r := CompareKernelVersion(a, b); r != result {
if r := CompareKernelVersion(*a, *b); r != result {
t.Fatalf("Unexpected kernel version comparison result for (%v,%v). Found %d, expected %d", release, b, r, result)
}
if a.Flavor != b.Flavor {
@ -20,13 +20,13 @@ func assertParseRelease(t *testing.T, release string, b *KernelVersionInfo, resu
}
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)
assertParseRelease(t, "3.8.0", &KernelVersionInfo{Kernel: 4, Major: 8, Minor: 0}, -1)
assertParseRelease(t, "3.8.0", &VersionInfo{Kernel: 3, Major: 8, Minor: 0}, 0)
assertParseRelease(t, "3.4.54.longterm-1", &VersionInfo{Kernel: 3, Major: 4, Minor: 54, Flavor: ".longterm-1"}, 0)
assertParseRelease(t, "3.4.54.longterm-1", &VersionInfo{Kernel: 3, Major: 4, Minor: 54, Flavor: ".longterm-1"}, 0)
assertParseRelease(t, "3.8.0-19-generic", &VersionInfo{Kernel: 3, Major: 8, Minor: 0, Flavor: "-19-generic"}, 0)
assertParseRelease(t, "3.12.8tag", &VersionInfo{Kernel: 3, Major: 12, Minor: 8, Flavor: "tag"}, 0)
assertParseRelease(t, "3.12-1-amd64", &VersionInfo{Kernel: 3, Major: 12, Minor: 0, Flavor: "-1-amd64"}, 0)
assertParseRelease(t, "3.8.0", &VersionInfo{Kernel: 4, Major: 8, Minor: 0}, -1)
// Errors
invalids := []string{
"3",
@ -42,7 +42,7 @@ func TestParseRelease(t *testing.T) {
}
}
func assertKernelVersion(t *testing.T, a, b *KernelVersionInfo, result int) {
func assertKernelVersion(t *testing.T, a, b VersionInfo, result int) {
if r := CompareKernelVersion(a, b); r != result {
t.Fatalf("Unexpected kernel version comparison result. Found %d, expected %d", r, result)
}
@ -50,43 +50,43 @@ func assertKernelVersion(t *testing.T, a, b *KernelVersionInfo, result int) {
func TestCompareKernelVersion(t *testing.T) {
assertKernelVersion(t,
&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
VersionInfo{Kernel: 3, Major: 8, Minor: 0},
VersionInfo{Kernel: 3, Major: 8, Minor: 0},
0)
assertKernelVersion(t,
&KernelVersionInfo{Kernel: 2, Major: 6, Minor: 0},
&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
VersionInfo{Kernel: 2, Major: 6, Minor: 0},
VersionInfo{Kernel: 3, Major: 8, Minor: 0},
-1)
assertKernelVersion(t,
&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
&KernelVersionInfo{Kernel: 2, Major: 6, Minor: 0},
VersionInfo{Kernel: 3, Major: 8, Minor: 0},
VersionInfo{Kernel: 2, Major: 6, Minor: 0},
1)
assertKernelVersion(t,
&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
VersionInfo{Kernel: 3, Major: 8, Minor: 0},
VersionInfo{Kernel: 3, Major: 8, Minor: 0},
0)
assertKernelVersion(t,
&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 5},
&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
VersionInfo{Kernel: 3, Major: 8, Minor: 5},
VersionInfo{Kernel: 3, Major: 8, Minor: 0},
1)
assertKernelVersion(t,
&KernelVersionInfo{Kernel: 3, Major: 0, Minor: 20},
&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
VersionInfo{Kernel: 3, Major: 0, Minor: 20},
VersionInfo{Kernel: 3, Major: 8, Minor: 0},
-1)
assertKernelVersion(t,
&KernelVersionInfo{Kernel: 3, Major: 7, Minor: 20},
&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
VersionInfo{Kernel: 3, Major: 7, Minor: 20},
VersionInfo{Kernel: 3, Major: 8, Minor: 0},
-1)
assertKernelVersion(t,
&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 20},
&KernelVersionInfo{Kernel: 3, Major: 7, Minor: 0},
VersionInfo{Kernel: 3, Major: 8, Minor: 20},
VersionInfo{Kernel: 3, Major: 7, Minor: 0},
1)
assertKernelVersion(t,
&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 20},
&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
VersionInfo{Kernel: 3, Major: 8, Minor: 20},
VersionInfo{Kernel: 3, Major: 8, Minor: 0},
1)
assertKernelVersion(t,
&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0},
&KernelVersionInfo{Kernel: 3, Major: 8, Minor: 20},
VersionInfo{Kernel: 3, Major: 8, Minor: 0},
VersionInfo{Kernel: 3, Major: 8, Minor: 20},
-1)
}

View file

@ -6,18 +6,20 @@ import (
"unsafe"
)
type KernelVersionInfo struct {
kvi string
major int
minor int
build int
// VersionInfo holds information about the kernel.
type VersionInfo struct {
kvi string // Version of the kernel (e.g. 6.1.7601.17592 -> 6)
major int // Major part of the kernel version (e.g. 6.1.7601.17592 -> 1)
minor int // Minor part of the kernel version (e.g. 6.1.7601.17592 -> 7601)
build int // Build number of the kernel version (e.g. 6.1.7601.17592 -> 17592)
}
func (k *KernelVersionInfo) String() string {
func (k *VersionInfo) String() string {
return fmt.Sprintf("%d.%d %d (%s)", k.major, k.minor, k.build, k.kvi)
}
func GetKernelVersion() (*KernelVersionInfo, error) {
// GetKernelVersion gets the current kernel version.
func GetKernelVersion() (*VersionInfo, error) {
var (
h syscall.Handle
@ -25,7 +27,7 @@ func GetKernelVersion() (*KernelVersionInfo, error) {
err error
)
KVI := &KernelVersionInfo{"Unknown", 0, 0, 0}
KVI := &VersionInfo{"Unknown", 0, 0, 0}
if err = syscall.RegOpenKeyEx(syscall.HKEY_LOCAL_MACHINE,
syscall.StringToUTF16Ptr(`SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\`),

View file

@ -4,6 +4,9 @@ import (
"syscall"
)
// Utsname represents the system name structure.
// It is passthgrouh for syscall.Utsname in order to make it portable with
// other platforms where it is not available.
type Utsname syscall.Utsname
func uname() (*syscall.Utsname, error) {

View file

@ -6,6 +6,9 @@ import (
"errors"
)
// Utsname represents the system name structure.
// It is defined here to make it portable as it is available on linux but not
// on windows.
type Utsname struct {
Release [65]byte
}

View file

@ -1,3 +1,5 @@
// Package operatingsystem provides helper function to get the operating system
// name for different platforms.
package operatingsystem
import (
@ -14,6 +16,7 @@ var (
etcOsRelease = "/etc/os-release"
)
// GetOperatingSystem gets the name of the current operating system.
func GetOperatingSystem() (string, error) {
b, err := ioutil.ReadFile(etcOsRelease)
if err != nil {
@ -26,6 +29,7 @@ func GetOperatingSystem() (string, error) {
return "", errors.New("PRETTY_NAME not found")
}
// IsContainerized returns true if we are running inside a container.
func IsContainerized() (bool, error) {
b, err := ioutil.ReadFile(proc1Cgroup)
if err != nil {

View file

@ -8,6 +8,7 @@ import (
// See https://code.google.com/p/go/source/browse/src/pkg/mime/type_windows.go?r=d14520ac25bf6940785aabb71f5be453a286f58c
// for a similar sample
// GetOperatingSystem gets the name of the current operating system.
func GetOperatingSystem() (string, error) {
var h syscall.Handle
@ -41,7 +42,8 @@ func GetOperatingSystem() (string, error) {
return ret, nil
}
// No-op on Windows
// IsContainerized returns true if we are running inside a container.
// No-op on Windows, always returns false.
func IsContainerized() (bool, error) {
return false, nil
}

View file

@ -1,3 +1,6 @@
// Package parsers provides helper functions to parse and validate different type
// of string. It can be hosts, unix addresses, tcp addresses, filters, kernel
// operating system versions.
package parsers
import (
@ -9,6 +12,8 @@ import (
"strings"
)
// ParseHost parses the specified address and returns an address that will be used as the host.
// Depending of the address specified, will use the defaultTCPAddr or defaultUnixAddr
// FIXME: Change this not to receive default value as parameter
func ParseHost(defaultTCPAddr, defaultUnixAddr, addr string) (string, error) {
addr = strings.TrimSpace(addr)
@ -17,7 +22,7 @@ func ParseHost(defaultTCPAddr, defaultUnixAddr, addr string) (string, error) {
addr = fmt.Sprintf("unix://%s", defaultUnixAddr)
} else {
// Note - defaultTCPAddr already includes tcp:// prefix
addr = fmt.Sprintf("%s", defaultTCPAddr)
addr = defaultTCPAddr
}
}
addrParts := strings.Split(addr, "://")
@ -37,6 +42,10 @@ func ParseHost(defaultTCPAddr, defaultUnixAddr, addr string) (string, error) {
}
}
// ParseUnixAddr parses and validates that the specified address is a valid UNIX
// socket address. It returns a formatted UNIX socket address, either using the
// address parsed from addr, or the contents of defaultAddr if addr is a blank
// string.
func ParseUnixAddr(addr string, defaultAddr string) (string, error) {
addr = strings.TrimPrefix(addr, "unix://")
if strings.Contains(addr, "://") {
@ -48,6 +57,9 @@ func ParseUnixAddr(addr string, defaultAddr string) (string, error) {
return fmt.Sprintf("unix://%s", addr), nil
}
// ParseTCPAddr parses and validates that the specified address is a valid TCP
// address. It returns a formatted TCP address, either using the address parsed
// from addr, or the contents of defaultAddr if addr is a blank string.
func ParseTCPAddr(addr string, defaultAddr string) (string, error) {
addr = strings.TrimPrefix(addr, "tcp://")
if strings.Contains(addr, "://") || addr == "" {
@ -74,7 +86,7 @@ func ParseTCPAddr(addr string, defaultAddr string) (string, error) {
return fmt.Sprintf("tcp://%s:%d%s", host, p, u.Path), nil
}
// Get a repos name and returns the right reposName + tag|digest
// ParseRepositoryTag gets a repos name and returns the right reposName + tag|digest
// The tag can be confusing because of a port in a repository name.
// Ex: localhost.localdomain:5000/samalba/hipache:latest
// Digest ex: localhost:5000/foo/bar@sha256:bc8813ea7b3603864987522f02a76101c17ad122e1c46d790efc0fca78ca7bfb
@ -94,6 +106,8 @@ func ParseRepositoryTag(repos string) (string, string) {
return repos, ""
}
// PartParser parses and validates the specified string (data) using the specified template
// e.g. ip:public:private -> 192.168.0.1:80:8000
func PartParser(template, data string) (map[string]string, error) {
// ip:public:private
var (
@ -115,6 +129,7 @@ func PartParser(template, data string) (map[string]string, error) {
return out, nil
}
// ParseKeyValueOpt parses and validates the specified string as a key/value pair (key=value)
func ParseKeyValueOpt(opt string) (string, string, error) {
parts := strings.SplitN(opt, "=", 2)
if len(parts) != 2 {
@ -123,6 +138,7 @@ func ParseKeyValueOpt(opt string) (string, string, error) {
return strings.TrimSpace(parts[0]), strings.TrimSpace(parts[1]), nil
}
// ParsePortRange parses and validates the specified string as a port-range (8000-9000)
func ParsePortRange(ports string) (uint64, uint64, error) {
if ports == "" {
return 0, 0, fmt.Errorf("Empty string specified for ports.")
@ -148,6 +164,7 @@ func ParsePortRange(ports string) (uint64, uint64, error) {
return start, end, nil
}
// ParseLink parses and validates the specified string as a link format (name:alias)
func ParseLink(val string) (string, string, error) {
if val == "" {
return "", "", fmt.Errorf("empty string specified for links")

View file

@ -7,7 +7,7 @@ import (
func TestParseHost(t *testing.T) {
var (
defaultHttpHost = "127.0.0.1"
defaultHTTPHost = "127.0.0.1"
defaultUnix = "/var/run/docker.sock"
)
invalids := map[string]string{
@ -32,12 +32,12 @@ func TestParseHost(t *testing.T) {
"fd://something": "fd://something",
}
for invalidAddr, expectedError := range invalids {
if addr, err := ParseHost(defaultHttpHost, defaultUnix, invalidAddr); err == nil || err.Error() != expectedError {
if addr, err := ParseHost(defaultHTTPHost, defaultUnix, invalidAddr); err == nil || err.Error() != expectedError {
t.Errorf("tcp %v address expected error %v return, got %s and addr %v", invalidAddr, expectedError, err, addr)
}
}
for validAddr, expectedAddr := range valids {
if addr, err := ParseHost(defaultHttpHost, defaultUnix, validAddr); err != nil || addr != expectedAddr {
if addr, err := ParseHost(defaultHTTPHost, defaultUnix, validAddr); err != nil || addr != expectedAddr {
t.Errorf("%v -> expected %v, got %v", validAddr, expectedAddr, addr)
}
}