diff --git a/.cirrus.yml b/.cirrus.yml index d5498eb5bf414ffca1cc86bdcd15c131dd9796ef..fcca28ba6ed2fd8d2b8fa3485e4f4cb6a1b2afbf 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -61,6 +61,8 @@ validate_task: validate_script: - make validate + - make vendor + - ./hack/tree_status.sh - make test_task: diff --git a/Makefile b/Makefile index ed2557ff2fca057de1029c3a221d3c6b3d66af06..4d1cf4ce81ad1a0375a490dbecac1f3cc638496a 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,5 @@ +export GOPROXY=https://proxy.golang.org + GO ?= go EPOCH_TEST_COMMIT ?= 394c06f491fe9f1c28a410e3b0b91916a5119406 DESTDIR ?= @@ -12,6 +14,11 @@ GOPKGBASEDIR ?= $(shell dirname "$(GOPKGDIR)") SELINUXOPT ?= $(shell test -x /usr/sbin/selinuxenabled && selinuxenabled && echo -Z) GO_BUILD=$(GO) build +# Go module support: set `-mod=vendor` to use the vendored sources +ifeq ($(shell go help mod >/dev/null 2>&1 && echo true), true) + GO_BUILD=GO111MODULE=on $(GO) build -mod=vendor +endif + GOBIN := $(shell $(GO) env GOBIN) ifeq ($(GOBIN),) GOBIN := $(FIRST_GOPATH)/bin @@ -37,7 +44,7 @@ binaries: install.tools: .install.gitvalidation .install.ginkgo .install.golangci-lint lint: .install.golangci-lint - $(GOBIN)/golangci-lint run --tests=false + $(GOBIN)/golangci-lint run define go-get env GO111MODULE=off \ @@ -69,9 +76,16 @@ clean: test: .install.ginkgo $(GO) test -v ./... +vendor: + export GO111MODULE=on \ + $(GO) mod tidy && \ + $(GO) mod vendor && \ + $(GO) mod verify + .PHONY: \ binaries \ test \ gofmt \ lint \ - validate + validate \ + vendor diff --git a/build_linux.sh b/build_linux.sh deleted file mode 100755 index 0225b70639f46ae738766337897f8b59e9047846..0000000000000000000000000000000000000000 --- a/build_linux.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env bash -set -e -cd $(dirname "$0") - -if [ "$(uname)" == "Darwin" ]; then - export GOOS="${GOOS:-linux}" -fi - -ORG_PATH="github.com/containers" -export REPO_PATH="${ORG_PATH}/dnsname" - -if [ ! -h gopath/src/${REPO_PATH} ]; then - mkdir -p gopath/src/${ORG_PATH} - ln -s ../../../.. gopath/src/${REPO_PATH} || exit 255 -fi - -export GOPATH=${PWD}/gopath -export GO="${GO:-go}" -export GOFLAGS="${GOFLAGS} -mod=vendor" - -mkdir -p "${PWD}/bin" - -echo "Building plugins ${GOOS}" -PLUGINS="plugins/meta/* plugins/main/* plugins/ipam/*" -for d in $PLUGINS; do - if [ -d "$d" ]; then - plugin="$(basename "$d")" - if [ $plugin != "windows" ]; then - echo " $plugin" - $GO build -o "${PWD}/bin/$plugin" "$@" "$REPO_PATH"/$d - fi - fi -done diff --git a/go.mod b/go.mod index aaccba68cfb354e6867cf2ac77d93c247aa8ac7b..b14fd95985aa69a1867b660c9f3a54552a25b667 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/coreos/go-iptables v0.4.2 github.com/onsi/ginkgo v1.10.1 github.com/onsi/gomega v1.7.0 + github.com/pkg/errors v0.8.1 github.com/sirupsen/logrus v1.4.2 github.com/vishvananda/netlink v1.0.0 golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3 diff --git a/go.sum b/go.sum index adc328b41dee41a62d804bb993d20f574e07dc67..0ae5238f1c19982fffaaf954d2cffcb36ac9ef47 100644 --- a/go.sum +++ b/go.sum @@ -16,10 +16,13 @@ github.com/d2g/dhcp4client v1.0.0/go.mod h1:j0hNfjhrt2SxUOw55nL0ATM/z4Yt3t2Kd1mW github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5/go.mod h1:Eo87+Kg/IX2hfWJfwxMzLyuSZyxSoAug2nGa1G2QAi8= github.com/d2g/hardwareaddr v0.0.0-20190221164911-e7d9fbe030e4/go.mod h1:bMl4RjIciD2oAxI7DmWRx6gbeqrkoLqv3MV0vzNad+I= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= @@ -29,8 +32,10 @@ github.com/juju/loggo v0.0.0-20190526231331-6e530bcce5d8/go.mod h1:vgyd7OREkbtVE github.com/juju/testing v0.0.0-20190613124551-e81189438503/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA= github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= github.com/onsi/ginkgo v0.0.0-20151202141238-7f8ab55aaf3b/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -40,6 +45,9 @@ github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+ github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4= github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= @@ -48,6 +56,7 @@ github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6Mwd github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk= github.com/vishvananda/netlink v1.0.0 h1:bqNY2lgheFIu1meHUFSH3d7vG93AFyqg3oGbJCOJgSM= @@ -68,6 +77,7 @@ golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= diff --git a/hack/tree_status.sh b/hack/tree_status.sh new file mode 100755 index 0000000000000000000000000000000000000000..ac874a3478fda0a6f8586391c1cbef14837c1baf --- /dev/null +++ b/hack/tree_status.sh @@ -0,0 +1,15 @@ +#!/bin/bash +set -e + +SUGGESTION="${SUGGESTION:-sync the vendor.conf and commit all changes.}" + +STATUS=$(git status --porcelain) +if [[ -z $STATUS ]] +then + echo "tree is clean" +else + echo "tree is dirty, please $SUGGESTION" + echo "" + echo "$STATUS" + exit 1 +fi diff --git a/plugins/meta/dnsname/dnsname_suite_test.go b/plugins/meta/dnsname/dnsname_suite_test.go index d2022b906ce855e02c97ced977feed46e1e79aaa..30a2158caf73ff0269571f053e0de5b33001b445 100644 --- a/plugins/meta/dnsname/dnsname_suite_test.go +++ b/plugins/meta/dnsname/dnsname_suite_test.go @@ -1,3 +1,4 @@ +// Copyright 2019 dnsname authors // Copyright 2017 CNI authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/plugins/meta/dnsname/dnsname_test.go b/plugins/meta/dnsname/dnsname_test.go index 9646d8bfd3d3f27a4301c4242dacfc49cd5bfa28..5bc4032741ae4177162f56fc2cd9c041a3d15a58 100644 --- a/plugins/meta/dnsname/dnsname_test.go +++ b/plugins/meta/dnsname/dnsname_test.go @@ -127,7 +127,7 @@ var _ = Describe("dnsname tests", func() { Expect(err).To(BeNil()) // Check that the dns masq instance is running - pid, err := d.getPidProcess() + pid, err := d.getProcess() Expect(err).To(BeNil()) // Send it a signal 0; if alive, error will be nil err = pid.Signal(syscall.Signal(0)) @@ -166,7 +166,7 @@ var _ = Describe("dnsname tests", func() { d, err := newDNSMasqFile("foobar.io", "dummy0", "test") Expect(err).To(BeNil()) - pid, err := d.getPidProcess() + pid, err := d.getProcess() Expect(err).To(BeNil()) err = pid.Signal(syscall.Signal(0)) Expect(err).To(BeNil()) diff --git a/plugins/meta/dnsname/files.go b/plugins/meta/dnsname/files.go index 70fdfe510e9a0ddaa38e7ca3d2b8fef509207028..16d781028843c6a7dcccde21cf7d091d1ba92656 100644 --- a/plugins/meta/dnsname/files.go +++ b/plugins/meta/dnsname/files.go @@ -4,7 +4,6 @@ import ( "bufio" "bytes" "fmt" - "github.com/coreos/go-iptables/iptables" "io/ioutil" "net" "os" @@ -12,6 +11,7 @@ import ( "text/template" "github.com/containernetworking/plugins/plugins/ipam/host-local/backend/disk" + "github.com/coreos/go-iptables/iptables" "github.com/sirupsen/logrus" ) @@ -20,7 +20,7 @@ type dnsNameLock struct { lock *disk.FileLock } -// release unlocks and closes the disk lock +// release unlocks and closes the disk lock. func (m *dnsNameLock) release() error { if err := m.lock.Unlock(); err != nil { return err @@ -28,16 +28,18 @@ func (m *dnsNameLock) release() error { return m.lock.Close() } -// getLock returns a dnsNameLock. the lock should be that of the configuration -// directory for the domain. +// acquire locks the disk lock. +func (m *dnsNameLock) acquire() error { + return m.lock.Lock() +} + +// getLock returns a dnsNameLock synchronizing the configuration directory for +// the domain. func getLock(path string) (*dnsNameLock, error) { l, err := disk.NewFileLock(path) if err != nil { return nil, err } - if err := l.Lock(); err != nil { - return nil, err - } return &dnsNameLock{l}, nil } @@ -92,7 +94,7 @@ func appendToFile(path, podname string, ips []*net.IPNet) error { } defer func() { if err := f.Close(); err != nil { - logrus.Errorf("failed to close file '%s': %q", path, err) + logrus.Errorf("failed to close file %q: %v", path, err) } }() for _, ip := range ips { @@ -124,7 +126,7 @@ func removeFromFile(path, podname string) (bool, error) { } defer func() { if err := f.Close(); err != nil { - logrus.Errorf("unable to close '%s': %q", backup, err) + logrus.Errorf("unable to close %q: %v", backup, err) } }() @@ -161,7 +163,7 @@ func removeFromFile(path, podname string) (bool, error) { // renameFile renames a file to backup func renameFile(oldpath, newpath string) { if renameError := os.Rename(oldpath, newpath); renameError != nil { - logrus.Errorf("unable to restore '%s' to '%s': %q", oldpath, newpath, renameError) + logrus.Errorf("unable to restore %q to %q: %v", oldpath, newpath, renameError) } } @@ -175,7 +177,7 @@ func writeFile(path string, content []string) (int, error) { } defer func() { if err := f.Close(); err != nil { - logrus.Errorf("unable to close '%s': %q", path, err) + logrus.Errorf("unable to close %q: %v", path, err) } }() diff --git a/plugins/meta/dnsname/main.go b/plugins/meta/dnsname/main.go index 79fde02413da243de24bffb3cd20a8cc5a7d0816..114b16b6bdeee8a2628ed155564abf9ae20bfd63 100644 --- a/plugins/meta/dnsname/main.go +++ b/plugins/meta/dnsname/main.go @@ -1,3 +1,4 @@ +// Copyright 2019 dnsname authors // Copyright 2017 CNI authors // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -22,13 +23,11 @@ // This has one notable limitation: it does not perform any kind of reservation // of the actual host port. If there is a service on the host, it will have all // its traffic captured by the container. If another container also claims a given -// port, it will caputure the traffic - it is last-write-wins. +// port, it will capture the traffic - it is last-write-wins. package main import ( "encoding/json" - "errors" - "fmt" "io/ioutil" "os" "os/exec" @@ -39,6 +38,7 @@ import ( "github.com/containernetworking/cni/pkg/types/current" "github.com/containernetworking/cni/pkg/version" bv "github.com/containernetworking/plugins/pkg/utils/buildversion" + "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -48,10 +48,10 @@ func cmdAdd(args *skel.CmdArgs) error { } netConf, result, podname, err := parseConfig(args.StdinData, args.Args) if err != nil { - return fmt.Errorf("failed to parse config: %v", err) + return errors.Wrap(err, "failed to parse config") } if netConf.PrevResult == nil { - return fmt.Errorf("must be called as chained plugin") + return errors.Errorf("must be called as chained plugin") } ips, err := getIPs(result) if err != nil { @@ -74,9 +74,12 @@ func cmdAdd(args *skel.CmdArgs) error { if err != nil { return err } + if err := lock.acquire(); err != nil { + return err + } defer func() { if err := lock.release(); err != nil { - logrus.Errorf("unable to release lock for '%s': %q", dnsNameConf.AddOnHostsFile, err) + logrus.Errorf("unable to release lock for %q: %v", dnsNameConf.AddOnHostsFile, err) } }() if err := checkForDNSMasqConfFile(dnsNameConf); err != nil { @@ -106,9 +109,8 @@ func cmdDel(args *skel.CmdArgs) error { } netConf, result, podname, err := parseConfig(args.StdinData, args.Args) if err != nil { - return fmt.Errorf("failed to parse config: %v", err) - } - if result == nil { + return errors.Wrap(err, "failed to parse config") + } else if result == nil { return nil } dnsNameConf, err := newDNSMasqFile(netConf.DomainName, result.Interfaces[0].Name, netConf.Name) @@ -120,10 +122,13 @@ func cmdDel(args *skel.CmdArgs) error { if err != nil { return err } + if err := lock.acquire(); err != nil { + return err + } defer func() { // if the lock isn't given up by another process if err := lock.release(); err != nil { - logrus.Errorf("unable to release lock for '%s': %q", domainBaseDir, err) + logrus.Errorf("unable to release lock for %q: %v", domainBaseDir, err) } }() shouldHUP, err := removeFromFile(filepath.Join(domainBaseDir, hostsFileName), podname) @@ -150,16 +155,14 @@ func cmdCheck(args *skel.CmdArgs) error { if err := findDNSMasq(); err != nil { return ErrBinaryNotFound } - netConf, result, podname, err := parseConfig(args.StdinData, args.Args) + netConf, result, _, err := parseConfig(args.StdinData, args.Args) if err != nil { - return fmt.Errorf("failed to parse config: %v", err) + return errors.Wrap(err, "failed to parse config") } - _ = podname - // Ensure we have previous result. if result == nil { - return fmt.Errorf("Required prevResult missing") + return errors.Errorf("Required prevResult missing") } dnsNameConf, err := newDNSMasqFile(netConf.DomainName, result.Interfaces[0].Name, netConf.Name) if err != nil { @@ -170,21 +173,24 @@ func cmdCheck(args *skel.CmdArgs) error { if err != nil { return err } + if err := lock.acquire(); err != nil { + return err + } defer func() { // if the lock isn't given up by another process if err := lock.release(); err != nil { - logrus.Errorf("unable to release lock for '%s': %q", domainBaseDir, err) + logrus.Errorf("unable to release lock for %q: %v", domainBaseDir, err) } }() - pid, err := dnsNameConf.getPidProcess() + pid, err := dnsNameConf.getProcess() if err != nil { return err } // Ensure the dnsmasq instance is running if !isRunning(pid) { - return errors.New("dnsmasq instance not running") + return errors.Errorf("dnsmasq instance not running") } // Above will make sure the pidfile exists files, err := ioutil.ReadDir(dnsNameConfPath) @@ -195,10 +201,10 @@ func cmdCheck(args *skel.CmdArgs) error { conffiles = append(conffiles, f.Name()) } if !stringInSlice("addnhosts", conffiles) { - return errors.New("addnhost file missing from configuration") + return errors.Errorf("addnhost file missing from configuration") } if !stringInSlice("dnsmasq.conf", conffiles) { - return errors.New("dnsmasq.conf file missing from configuration") + return errors.Errorf("dnsmasq.conf file missing from configuration") } return nil } @@ -223,18 +229,18 @@ type podname struct { func parseConfig(stdin []byte, args string) (*DNSNameConf, *current.Result, string, error) { conf := DNSNameConf{} if err := json.Unmarshal(stdin, &conf); err != nil { - return nil, nil, "", fmt.Errorf("failed to parse network configuration: %v", err) + return nil, nil, "", errors.Wrap(err, "failed to parse network configuration") } // Parse previous result. var result *current.Result if conf.RawPrevResult != nil { var err error if err = version.ParsePrevResult(&conf.NetConf); err != nil { - return nil, nil, "", fmt.Errorf("could not parse prevResult: %v", err) + return nil, nil, "", errors.Wrap(err, "could not parse prevResult") } result, err = current.NewResultFromResult(conf.PrevResult) if err != nil { - return nil, nil, "", fmt.Errorf("could not convert result to current version: %v", err) + return nil, nil, "", errors.Wrap(err, "could not convert result to current version") } } e := podname{} diff --git a/plugins/meta/dnsname/result.go b/plugins/meta/dnsname/result.go index 115f69a1480198c23344c4c60703413d6c32d797..3d46029d10f9e02b2a355c1ce1b0130978803ebb 100644 --- a/plugins/meta/dnsname/result.go +++ b/plugins/meta/dnsname/result.go @@ -1,10 +1,10 @@ package main import ( - "errors" "net" "github.com/containernetworking/cni/pkg/types/current" + "github.com/pkg/errors" ) // getIPs iterates a result and returns all the IP addresses @@ -24,7 +24,7 @@ func getIPs(r *current.Result) ([]*net.IPNet, error) { if isInterfaceIndexSandox(*ip.Interface, r) { ips = append(ips, &ip.Address) } else { - return nil, errors.New("unable to check if interface has a sandbox due to index being out of range") + return nil, errors.Errorf("unable to check if interface has a sandbox due to index being out of range") } } } diff --git a/plugins/meta/dnsname/service.go b/plugins/meta/dnsname/service.go index f569f7324347645bcbe5b57f5f22feb226ec619b..c4b8b0f5f741e6e443585295f0d62d8d533a7358 100644 --- a/plugins/meta/dnsname/service.go +++ b/plugins/meta/dnsname/service.go @@ -1,7 +1,6 @@ package main import ( - "errors" "fmt" "io/ioutil" "os" @@ -11,6 +10,7 @@ import ( "strings" "syscall" + "github.com/pkg/errors" "golang.org/x/sys/unix" ) @@ -18,7 +18,7 @@ import ( func newDNSMasqFile(domainName, networkInterface, networkName string) (dnsNameFile, error) { dnsMasqBinary, err := exec.LookPath("dnsmasq") if err != nil { - return dnsNameFile{}, errors.New("the dnsmasq cni plugin requires the dnsmasq binary be in PATH") + return dnsNameFile{}, errors.Errorf("the dnsmasq cni plugin requires the dnsmasq binary be in PATH") } masqConf := dnsNameFile{ ConfigFile: makePath(networkName, confFileName), @@ -39,7 +39,7 @@ func (d dnsNameFile) hup() error { if _, err := os.Stat(d.PidFile); os.IsNotExist(err) { return d.start() } - pid, err := d.getPidProcess() + pid, err := d.getProcess() if err != nil { return err } @@ -58,6 +58,7 @@ func isRunning(pid *os.Process) bool { return true } +// start starts the dnsmasq instance. func (d dnsNameFile) start() error { args := []string{ "-u", @@ -68,17 +69,18 @@ func (d dnsNameFile) start() error { return cmd.Run() } +// stop stops the dnsmasq instance. func (d dnsNameFile) stop() error { - pid, err := d.getPidProcess() + pid, err := d.getProcess() if err != nil { return err } return pid.Kill() } -// getPidProcess reads the PID for the dnsmasq instance and returns it in the -// form of an int -func (d dnsNameFile) getPidProcess() (*os.Process, error) { +// getProcess reads the PID for the dnsmasq instance and returns an +// *os.Process. Returns an error if the PID does not exist. +func (d dnsNameFile) getProcess() (*os.Process, error) { pidFileContents, err := ioutil.ReadFile(d.PidFile) if err != nil { return nil, err diff --git a/vendor/github.com/pkg/errors/.gitignore b/vendor/github.com/pkg/errors/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..daf913b1b347aae6de6f48d599bc89ef8c8693d6 --- /dev/null +++ b/vendor/github.com/pkg/errors/.gitignore @@ -0,0 +1,24 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe +*.test +*.prof diff --git a/vendor/github.com/pkg/errors/.travis.yml b/vendor/github.com/pkg/errors/.travis.yml new file mode 100644 index 0000000000000000000000000000000000000000..d4b92663bacfbb101cda87c41711b9d54d3a87cb --- /dev/null +++ b/vendor/github.com/pkg/errors/.travis.yml @@ -0,0 +1,15 @@ +language: go +go_import_path: github.com/pkg/errors +go: + - 1.4.x + - 1.5.x + - 1.6.x + - 1.7.x + - 1.8.x + - 1.9.x + - 1.10.x + - 1.11.x + - tip + +script: + - go test -v ./... diff --git a/vendor/github.com/pkg/errors/LICENSE b/vendor/github.com/pkg/errors/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..835ba3e755cef8c0dde475f1ebfd41e4ba0c79bf --- /dev/null +++ b/vendor/github.com/pkg/errors/LICENSE @@ -0,0 +1,23 @@ +Copyright (c) 2015, Dave Cheney <dave@cheney.net> +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/pkg/errors/README.md b/vendor/github.com/pkg/errors/README.md new file mode 100644 index 0000000000000000000000000000000000000000..6483ba2afb51278516423dc013fcfa275ee597a9 --- /dev/null +++ b/vendor/github.com/pkg/errors/README.md @@ -0,0 +1,52 @@ +# errors [](https://travis-ci.org/pkg/errors) [](https://ci.appveyor.com/project/davecheney/errors/branch/master) [](http://godoc.org/github.com/pkg/errors) [](https://goreportcard.com/report/github.com/pkg/errors) [](https://sourcegraph.com/github.com/pkg/errors?badge) + +Package errors provides simple error handling primitives. + +`go get github.com/pkg/errors` + +The traditional error handling idiom in Go is roughly akin to +```go +if err != nil { + return err +} +``` +which applied recursively up the call stack results in error reports without context or debugging information. The errors package allows programmers to add context to the failure path in their code in a way that does not destroy the original value of the error. + +## Adding context to an error + +The errors.Wrap function returns a new error that adds context to the original error. For example +```go +_, err := ioutil.ReadAll(r) +if err != nil { + return errors.Wrap(err, "read failed") +} +``` +## Retrieving the cause of an error + +Using `errors.Wrap` constructs a stack of errors, adding context to the preceding error. Depending on the nature of the error it may be necessary to reverse the operation of errors.Wrap to retrieve the original error for inspection. Any error value which implements this interface can be inspected by `errors.Cause`. +```go +type causer interface { + Cause() error +} +``` +`errors.Cause` will recursively retrieve the topmost error which does not implement `causer`, which is assumed to be the original cause. For example: +```go +switch err := errors.Cause(err).(type) { +case *MyError: + // handle specifically +default: + // unknown error +} +``` + +[Read the package documentation for more information](https://godoc.org/github.com/pkg/errors). + +## Contributing + +We welcome pull requests, bug fixes and issue reports. With that said, the bar for adding new symbols to this package is intentionally set high. + +Before proposing a change, please discuss your change by raising an issue. + +## License + +BSD-2-Clause diff --git a/vendor/github.com/pkg/errors/appveyor.yml b/vendor/github.com/pkg/errors/appveyor.yml new file mode 100644 index 0000000000000000000000000000000000000000..a932eade0240aa2b5f9f5347b695ab173da0236a --- /dev/null +++ b/vendor/github.com/pkg/errors/appveyor.yml @@ -0,0 +1,32 @@ +version: build-{build}.{branch} + +clone_folder: C:\gopath\src\github.com\pkg\errors +shallow_clone: true # for startup speed + +environment: + GOPATH: C:\gopath + +platform: + - x64 + +# http://www.appveyor.com/docs/installed-software +install: + # some helpful output for debugging builds + - go version + - go env + # pre-installed MinGW at C:\MinGW is 32bit only + # but MSYS2 at C:\msys64 has mingw64 + - set PATH=C:\msys64\mingw64\bin;%PATH% + - gcc --version + - g++ --version + +build_script: + - go install -v ./... + +test_script: + - set PATH=C:\gopath\bin;%PATH% + - go test -v ./... + +#artifacts: +# - path: '%GOPATH%\bin\*.exe' +deploy: off diff --git a/vendor/github.com/pkg/errors/errors.go b/vendor/github.com/pkg/errors/errors.go new file mode 100644 index 0000000000000000000000000000000000000000..7421f326ffe8402b17f4b064d33a862d786a6ef1 --- /dev/null +++ b/vendor/github.com/pkg/errors/errors.go @@ -0,0 +1,282 @@ +// Package errors provides simple error handling primitives. +// +// The traditional error handling idiom in Go is roughly akin to +// +// if err != nil { +// return err +// } +// +// which when applied recursively up the call stack results in error reports +// without context or debugging information. The errors package allows +// programmers to add context to the failure path in their code in a way +// that does not destroy the original value of the error. +// +// Adding context to an error +// +// The errors.Wrap function returns a new error that adds context to the +// original error by recording a stack trace at the point Wrap is called, +// together with the supplied message. For example +// +// _, err := ioutil.ReadAll(r) +// if err != nil { +// return errors.Wrap(err, "read failed") +// } +// +// If additional control is required, the errors.WithStack and +// errors.WithMessage functions destructure errors.Wrap into its component +// operations: annotating an error with a stack trace and with a message, +// respectively. +// +// Retrieving the cause of an error +// +// Using errors.Wrap constructs a stack of errors, adding context to the +// preceding error. Depending on the nature of the error it may be necessary +// to reverse the operation of errors.Wrap to retrieve the original error +// for inspection. Any error value which implements this interface +// +// type causer interface { +// Cause() error +// } +// +// can be inspected by errors.Cause. errors.Cause will recursively retrieve +// the topmost error that does not implement causer, which is assumed to be +// the original cause. For example: +// +// switch err := errors.Cause(err).(type) { +// case *MyError: +// // handle specifically +// default: +// // unknown error +// } +// +// Although the causer interface is not exported by this package, it is +// considered a part of its stable public interface. +// +// Formatted printing of errors +// +// All error values returned from this package implement fmt.Formatter and can +// be formatted by the fmt package. The following verbs are supported: +// +// %s print the error. If the error has a Cause it will be +// printed recursively. +// %v see %s +// %+v extended format. Each Frame of the error's StackTrace will +// be printed in detail. +// +// Retrieving the stack trace of an error or wrapper +// +// New, Errorf, Wrap, and Wrapf record a stack trace at the point they are +// invoked. This information can be retrieved with the following interface: +// +// type stackTracer interface { +// StackTrace() errors.StackTrace +// } +// +// The returned errors.StackTrace type is defined as +// +// type StackTrace []Frame +// +// The Frame type represents a call site in the stack trace. Frame supports +// the fmt.Formatter interface that can be used for printing information about +// the stack trace of this error. For example: +// +// if err, ok := err.(stackTracer); ok { +// for _, f := range err.StackTrace() { +// fmt.Printf("%+s:%d", f) +// } +// } +// +// Although the stackTracer interface is not exported by this package, it is +// considered a part of its stable public interface. +// +// See the documentation for Frame.Format for more details. +package errors + +import ( + "fmt" + "io" +) + +// New returns an error with the supplied message. +// New also records the stack trace at the point it was called. +func New(message string) error { + return &fundamental{ + msg: message, + stack: callers(), + } +} + +// Errorf formats according to a format specifier and returns the string +// as a value that satisfies error. +// Errorf also records the stack trace at the point it was called. +func Errorf(format string, args ...interface{}) error { + return &fundamental{ + msg: fmt.Sprintf(format, args...), + stack: callers(), + } +} + +// fundamental is an error that has a message and a stack, but no caller. +type fundamental struct { + msg string + *stack +} + +func (f *fundamental) Error() string { return f.msg } + +func (f *fundamental) Format(s fmt.State, verb rune) { + switch verb { + case 'v': + if s.Flag('+') { + io.WriteString(s, f.msg) + f.stack.Format(s, verb) + return + } + fallthrough + case 's': + io.WriteString(s, f.msg) + case 'q': + fmt.Fprintf(s, "%q", f.msg) + } +} + +// WithStack annotates err with a stack trace at the point WithStack was called. +// If err is nil, WithStack returns nil. +func WithStack(err error) error { + if err == nil { + return nil + } + return &withStack{ + err, + callers(), + } +} + +type withStack struct { + error + *stack +} + +func (w *withStack) Cause() error { return w.error } + +func (w *withStack) Format(s fmt.State, verb rune) { + switch verb { + case 'v': + if s.Flag('+') { + fmt.Fprintf(s, "%+v", w.Cause()) + w.stack.Format(s, verb) + return + } + fallthrough + case 's': + io.WriteString(s, w.Error()) + case 'q': + fmt.Fprintf(s, "%q", w.Error()) + } +} + +// Wrap returns an error annotating err with a stack trace +// at the point Wrap is called, and the supplied message. +// If err is nil, Wrap returns nil. +func Wrap(err error, message string) error { + if err == nil { + return nil + } + err = &withMessage{ + cause: err, + msg: message, + } + return &withStack{ + err, + callers(), + } +} + +// Wrapf returns an error annotating err with a stack trace +// at the point Wrapf is called, and the format specifier. +// If err is nil, Wrapf returns nil. +func Wrapf(err error, format string, args ...interface{}) error { + if err == nil { + return nil + } + err = &withMessage{ + cause: err, + msg: fmt.Sprintf(format, args...), + } + return &withStack{ + err, + callers(), + } +} + +// WithMessage annotates err with a new message. +// If err is nil, WithMessage returns nil. +func WithMessage(err error, message string) error { + if err == nil { + return nil + } + return &withMessage{ + cause: err, + msg: message, + } +} + +// WithMessagef annotates err with the format specifier. +// If err is nil, WithMessagef returns nil. +func WithMessagef(err error, format string, args ...interface{}) error { + if err == nil { + return nil + } + return &withMessage{ + cause: err, + msg: fmt.Sprintf(format, args...), + } +} + +type withMessage struct { + cause error + msg string +} + +func (w *withMessage) Error() string { return w.msg + ": " + w.cause.Error() } +func (w *withMessage) Cause() error { return w.cause } + +func (w *withMessage) Format(s fmt.State, verb rune) { + switch verb { + case 'v': + if s.Flag('+') { + fmt.Fprintf(s, "%+v\n", w.Cause()) + io.WriteString(s, w.msg) + return + } + fallthrough + case 's', 'q': + io.WriteString(s, w.Error()) + } +} + +// Cause returns the underlying cause of the error, if possible. +// An error value has a cause if it implements the following +// interface: +// +// type causer interface { +// Cause() error +// } +// +// If the error does not implement Cause, the original error will +// be returned. If the error is nil, nil will be returned without further +// investigation. +func Cause(err error) error { + type causer interface { + Cause() error + } + + for err != nil { + cause, ok := err.(causer) + if !ok { + break + } + err = cause.Cause() + } + return err +} diff --git a/vendor/github.com/pkg/errors/stack.go b/vendor/github.com/pkg/errors/stack.go new file mode 100644 index 0000000000000000000000000000000000000000..2874a048cf3e6f03a74179e408aaeedd6b2951b4 --- /dev/null +++ b/vendor/github.com/pkg/errors/stack.go @@ -0,0 +1,147 @@ +package errors + +import ( + "fmt" + "io" + "path" + "runtime" + "strings" +) + +// Frame represents a program counter inside a stack frame. +type Frame uintptr + +// pc returns the program counter for this frame; +// multiple frames may have the same PC value. +func (f Frame) pc() uintptr { return uintptr(f) - 1 } + +// file returns the full path to the file that contains the +// function for this Frame's pc. +func (f Frame) file() string { + fn := runtime.FuncForPC(f.pc()) + if fn == nil { + return "unknown" + } + file, _ := fn.FileLine(f.pc()) + return file +} + +// line returns the line number of source code of the +// function for this Frame's pc. +func (f Frame) line() int { + fn := runtime.FuncForPC(f.pc()) + if fn == nil { + return 0 + } + _, line := fn.FileLine(f.pc()) + return line +} + +// Format formats the frame according to the fmt.Formatter interface. +// +// %s source file +// %d source line +// %n function name +// %v equivalent to %s:%d +// +// Format accepts flags that alter the printing of some verbs, as follows: +// +// %+s function name and path of source file relative to the compile time +// GOPATH separated by \n\t (<funcname>\n\t<path>) +// %+v equivalent to %+s:%d +func (f Frame) Format(s fmt.State, verb rune) { + switch verb { + case 's': + switch { + case s.Flag('+'): + pc := f.pc() + fn := runtime.FuncForPC(pc) + if fn == nil { + io.WriteString(s, "unknown") + } else { + file, _ := fn.FileLine(pc) + fmt.Fprintf(s, "%s\n\t%s", fn.Name(), file) + } + default: + io.WriteString(s, path.Base(f.file())) + } + case 'd': + fmt.Fprintf(s, "%d", f.line()) + case 'n': + name := runtime.FuncForPC(f.pc()).Name() + io.WriteString(s, funcname(name)) + case 'v': + f.Format(s, 's') + io.WriteString(s, ":") + f.Format(s, 'd') + } +} + +// StackTrace is stack of Frames from innermost (newest) to outermost (oldest). +type StackTrace []Frame + +// Format formats the stack of Frames according to the fmt.Formatter interface. +// +// %s lists source files for each Frame in the stack +// %v lists the source file and line number for each Frame in the stack +// +// Format accepts flags that alter the printing of some verbs, as follows: +// +// %+v Prints filename, function, and line number for each Frame in the stack. +func (st StackTrace) Format(s fmt.State, verb rune) { + switch verb { + case 'v': + switch { + case s.Flag('+'): + for _, f := range st { + fmt.Fprintf(s, "\n%+v", f) + } + case s.Flag('#'): + fmt.Fprintf(s, "%#v", []Frame(st)) + default: + fmt.Fprintf(s, "%v", []Frame(st)) + } + case 's': + fmt.Fprintf(s, "%s", []Frame(st)) + } +} + +// stack represents a stack of program counters. +type stack []uintptr + +func (s *stack) Format(st fmt.State, verb rune) { + switch verb { + case 'v': + switch { + case st.Flag('+'): + for _, pc := range *s { + f := Frame(pc) + fmt.Fprintf(st, "\n%+v", f) + } + } + } +} + +func (s *stack) StackTrace() StackTrace { + f := make([]Frame, len(*s)) + for i := 0; i < len(f); i++ { + f[i] = Frame((*s)[i]) + } + return f +} + +func callers() *stack { + const depth = 32 + var pcs [depth]uintptr + n := runtime.Callers(3, pcs[:]) + var st stack = pcs[0:n] + return &st +} + +// funcname removes the path prefix component of a function's name reported by func.Name(). +func funcname(name string) string { + i := strings.LastIndex(name, "/") + name = name[i+1:] + i = strings.Index(name, ".") + return name[i+1:] +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 90c8276c2334f23473346c8fd3f4c71537893cc1..8478f282ff41658e8df293a21785cacef1754f10 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -54,6 +54,8 @@ github.com/onsi/gomega/matchers/support/goraph/bipartitegraph github.com/onsi/gomega/matchers/support/goraph/edge github.com/onsi/gomega/matchers/support/goraph/node github.com/onsi/gomega/matchers/support/goraph/util +# github.com/pkg/errors v0.8.1 +github.com/pkg/errors # github.com/sirupsen/logrus v1.4.2 github.com/sirupsen/logrus # github.com/vishvananda/netlink v1.0.0