From 23602de816b9ee3e92a8cbac295e955ba43fa283 Mon Sep 17 00:00:00 2001 From: Brent Baude Date: Fri, 5 Apr 2019 19:49:36 -0500 Subject: [PATCH] Revert "Switch to golangci-lint" Signed-off-by: baude --- .cirrus.yml | 1 + .golangci.yml | 35 ----------- .tool/lint | 48 ++++++++++++++ Makefile | 16 +++-- cmd/podman/common.go | 6 +- cmd/podman/common_test.go | 15 +++++ cmd/podman/pod_ps.go | 1 + cmd/podman/pod_stats.go | 14 +++++ cmd/podman/ps.go | 117 ++++++++++++++++++++++++++++++----- cmd/podman/run_test.go | 1 + cmd/podman/search.go | 5 ++ cmd/podman/shared/create.go | 5 ++ cmd/podman/trust_set_show.go | 5 ++ cmd/podman/utils.go | 42 +++++++++++++ test/e2e/common_test.go | 17 ++--- 15 files changed, 261 insertions(+), 67 deletions(-) delete mode 100644 .golangci.yml create mode 100755 .tool/lint create mode 100644 cmd/podman/common_test.go diff --git a/.cirrus.yml b/.cirrus.yml index ee83ffeba8..3251761798 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -121,6 +121,7 @@ gating_task: gate_script: # N/B: entrypoint.sh resets $GOSRC (same as make clean) + - '/usr/local/bin/entrypoint.sh install.tools' - '/usr/local/bin/entrypoint.sh validate' - '/usr/local/bin/entrypoint.sh lint' - '${CIRRUS_WORKING_DIR}/${SCRIPT_BASE}/test/test_dot_cirrus_yaml.py' diff --git a/.golangci.yml b/.golangci.yml deleted file mode 100644 index 8fde162c4e..0000000000 --- a/.golangci.yml +++ /dev/null @@ -1,35 +0,0 @@ ---- -run: - concurrency: 6 - deadline: 5m -linters: - disable-all: true - enable: - - deadcode - - depguard - - gofmt - - typecheck - - varcheck - # - dupl - # - errcheck - # - gochecknoglobals - # - gochecknoinits - # - goconst - # - gocritic - # - gocyclo - # - goimports - # - golint - # - gosec - # - govet - # - ineffassign - # - interfacer - # - lll - # - maligned - # - misspell - # - nakedret - # - prealloc - # - scopelint - # - staticcheck - # - structcheck - # - unconvert - # - unparam diff --git a/.tool/lint b/.tool/lint new file mode 100755 index 0000000000..f7bf81c1d0 --- /dev/null +++ b/.tool/lint @@ -0,0 +1,48 @@ +#!/usr/bin/env bash + +set -o errexit +set -o nounset +set -o pipefail + +# Create the linter path for use later +LINTER=${GOPATH}/bin/gometalinter + +# Make sure gometalinter is installed +if [ ! -f ${LINTER} ]; then + echo >&2 "gometalinter must be installed. Please run 'make install.tools' and try again" + exit 1 +fi + +PKGS=$(find . -type d -not -path . -a -not -iwholename '*.git*' -a -not -iname '.tool' -a -not -iwholename '*vendor*' -a -not -iname 'hack' -a -not -iwholename '*.artifacts*' -a -not -iwholename '*contrib*' -a -not -iwholename '*test*' -a -not -iwholename '*logo*' -a -not -iwholename '*conmon*' -a -not -iwholename '*completions*' -a -not -iwholename '*docs*' -a -not -iwholename '*pause*' -a -not -iwholename './_output*' -a -not -iwholename '*ioprojectatomicpodman.go') + +echo $PKGS + +# Execute the linter +${LINTER} \ + --concurrency=4\ + --enable-gc\ + --vendored-linters\ + --deadline=600s --disable-all\ + --enable=deadcode\ + --enable=errcheck\ + --enable=goconst\ + --enable=gofmt\ + --enable=golint\ + --enable=ineffassign\ + --enable=megacheck\ + --enable=misspell\ + --enable=structcheck\ + --enable=varcheck\ + --enable=vet\ + --enable=vetshadow\ + --exclude='error return value not checked.*\(errcheck\)$'\ + --exclude='declaration of.*err.*shadows declaration.*\(vetshadow\)$'\ + --exclude='.*_test\.go:.*error return value not checked.*\(errcheck\)$'\ + --exclude='duplicate of.*_test.go.*\(dupl\)$'\ + --exclude='cmd\/client\/.*\.go.*\(dupl\)$'\ + --exclude='libpod\/.*_easyjson.go:.*'\ + --exclude='.* other occurrence\(s\) of "(container|host|tmpfs|unknown)" found in: .*\(goconst\)$'\ + --exclude='vendor\/.*'\ + --exclude='podman\/.*'\ + --exclude='server\/seccomp\/.*\.go.*$'\ + ${PKGS[@]} diff --git a/Makefile b/Makefile index 86e3bfba07..1f4a7f6e75 100644 --- a/Makefile +++ b/Makefile @@ -98,7 +98,8 @@ endif touch $@ lint: .gopathok varlink_generate ## Execute the source code linter - golangci-lint run --build-tags="$(BUILDTAGS)" + @echo "checking lint" + @./.tool/lint gofmt: ## Verify the source code gofmt find . -name '*.go' ! -path './vendor/*' -exec gofmt -s -w {} \+ @@ -279,7 +280,7 @@ uninstall: .PHONY: install.tools -install.tools: .install.gitvalidation .install.golangci-lint .install.md2man .install.ginkgo ## Install needed tools +install.tools: .install.gitvalidation .install.gometalinter .install.md2man .install.ginkgo ## Install needed tools .install.vndr: .gopathok $(GO) get -u github.com/LK4D4/vndr @@ -294,10 +295,13 @@ install.tools: .install.gitvalidation .install.golangci-lint .install.md2man .in $(GO) get -u github.com/vbatts/git-validation; \ fi -.install.golangci-lint: .gopathok - if [ ! -x "$(GOBIN)/golangci-lint" ]; then \ - curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh |\ - sh -s -- -b $(GOBIN) v1.15.0 ;\ +.install.gometalinter: .gopathok + if [ ! -x "$(GOBIN)/gometalinter" ]; then \ + $(GO) get -u github.com/alecthomas/gometalinter; \ + cd $(FIRST_GOPATH)/src/github.com/alecthomas/gometalinter; \ + git checkout e8d801238da6f0dfd14078d68f9b53fa50a7eeb5; \ + $(GO) install github.com/alecthomas/gometalinter; \ + $(GOBIN)/gometalinter --install; \ fi .install.md2man: .gopathok diff --git a/cmd/podman/common.go b/cmd/podman/common.go index f4d128df27..10fed053e1 100644 --- a/cmd/podman/common.go +++ b/cmd/podman/common.go @@ -10,13 +10,17 @@ import ( "github.com/containers/libpod/cmd/podman/cliconfig" "github.com/containers/libpod/libpod" "github.com/containers/libpod/pkg/rootless" + "github.com/containers/storage" "github.com/fatih/camelcase" jsoniter "github.com/json-iterator/go" "github.com/pkg/errors" "github.com/spf13/cobra" ) -var json = jsoniter.ConfigCompatibleWithStandardLibrary +var ( + stores = make(map[storage.Store]struct{}) + json = jsoniter.ConfigCompatibleWithStandardLibrary +) const ( idTruncLength = 12 diff --git a/cmd/podman/common_test.go b/cmd/podman/common_test.go new file mode 100644 index 0000000000..a241730030 --- /dev/null +++ b/cmd/podman/common_test.go @@ -0,0 +1,15 @@ +package main + +import ( + "os/user" + "testing" +) + +func skipTestIfNotRoot(t *testing.T) { + u, err := user.Current() + if err != nil { + t.Skip("Could not determine user. Running without root may cause tests to fail") + } else if u.Uid != "0" { + t.Skip("tests will fail unless run as root") + } +} diff --git a/cmd/podman/pod_ps.go b/cmd/podman/pod_ps.go index d0cc6aa125..a956882cfc 100644 --- a/cmd/podman/pod_ps.go +++ b/cmd/podman/pod_ps.go @@ -20,6 +20,7 @@ import ( ) const ( + STOPPED = "Stopped" RUNNING = "Running" PAUSED = "Paused" EXITED = "Exited" diff --git a/cmd/podman/pod_stats.go b/cmd/podman/pod_stats.go index 7446022685..36b0b95ed7 100644 --- a/cmd/podman/pod_stats.go +++ b/cmd/podman/pod_stats.go @@ -298,3 +298,17 @@ func outputJson(stats []*adapter.PodContainerStats) error { fmt.Println(string(b)) return nil } + +func getPodsByList(podList []string, r *libpod.Runtime) ([]*libpod.Pod, error) { + var ( + pods []*libpod.Pod + ) + for _, p := range podList { + pod, err := r.LookupPod(p) + if err != nil { + return nil, err + } + pods = append(pods, pod) + } + return pods, nil +} diff --git a/cmd/podman/ps.go b/cmd/podman/ps.go index 232cf4b773..759a03b86b 100644 --- a/cmd/podman/ps.go +++ b/cmd/podman/ps.go @@ -18,31 +18,35 @@ import ( "github.com/containers/libpod/cmd/podman/shared" "github.com/containers/libpod/libpod" "github.com/containers/libpod/pkg/util" + "github.com/cri-o/ocicni/pkg/ocicni" "github.com/docker/go-units" "github.com/opentracing/opentracing-go" "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/spf13/cobra" + "k8s.io/apimachinery/pkg/fields" ) const ( - hid = "CONTAINER ID" - himage = "IMAGE" - hcommand = "COMMAND" - hcreated = "CREATED" - hstatus = "STATUS" - hports = "PORTS" - hnames = "NAMES" - hsize = "SIZE" - hpod = "POD" - nspid = "PID" - nscgroup = "CGROUPNS" - nsipc = "IPC" - nsmnt = "MNT" - nsnet = "NET" - nspidns = "PIDNS" - nsuserns = "USERNS" - nsuts = "UTS" + mountTruncLength = 12 + hid = "CONTAINER ID" + himage = "IMAGE" + hcommand = "COMMAND" + hcreated = "CREATED" + hstatus = "STATUS" + hports = "PORTS" + hnames = "NAMES" + hsize = "SIZE" + hinfra = "IS INFRA" + hpod = "POD" + nspid = "PID" + nscgroup = "CGROUPNS" + nsipc = "IPC" + nsmnt = "MNT" + nsnet = "NET" + nspidns = "PIDNS" + nsuserns = "USERNS" + nsuts = "UTS" ) type psTemplateParams struct { @@ -69,6 +73,34 @@ type psTemplateParams struct { IsInfra bool } +// psJSONParams is used as a base structure for the psParams +// If template output is requested, psJSONParams will be converted to +// psTemplateParams. +// psJSONParams will be populated by data from libpod.Container, +// the members of the struct are the sama data types as their sources. +type psJSONParams struct { + ID string `json:"id"` + Image string `json:"image"` + ImageID string `json:"image_id"` + Command []string `json:"command"` + ExitCode int32 `json:"exitCode"` + Exited bool `json:"exited"` + CreatedAt time.Time `json:"createdAt"` + StartedAt time.Time `json:"startedAt"` + ExitedAt time.Time `json:"exitedAt"` + Status string `json:"status"` + PID int `json:"PID"` + Ports []ocicni.PortMapping `json:"ports"` + Size *shared.ContainerSize `json:"size,omitempty"` + Names string `json:"names"` + Labels fields.Set `json:"labels"` + Mounts []string `json:"mounts"` + ContainerRunning bool `json:"ctrRunning"` + Namespaces *shared.Namespace `json:"namespace,omitempty"` + Pod string `json:"pod,omitempty"` + IsInfra bool `json:"infra"` +} + // Type declaration and functions for sorting the PS output type psSorted []shared.PsContainerOutput @@ -411,6 +443,57 @@ func sortPsOutput(sortBy string, psOutput psSorted) (psSorted, error) { return psOutput, nil } +// getLabels converts the labels to a string of the form "key=value, key2=value2" +func formatLabels(labels map[string]string) string { + var arr []string + if len(labels) > 0 { + for key, val := range labels { + temp := key + "=" + val + arr = append(arr, temp) + } + return strings.Join(arr, ",") + } + return "" +} + +// getMounts converts the volumes mounted to a string of the form "mount1, mount2" +// it truncates it if noTrunc is false +func getMounts(mounts []string, noTrunc bool) string { + return strings.Join(getMountsArray(mounts, noTrunc), ",") +} + +func getMountsArray(mounts []string, noTrunc bool) []string { + var arr []string + if len(mounts) == 0 { + return mounts + } + for _, mount := range mounts { + splitArr := strings.Split(mount, ":") + if len(splitArr[0]) > mountTruncLength && !noTrunc { + arr = append(arr, splitArr[0][:mountTruncLength]+"...") + continue + } + arr = append(arr, splitArr[0]) + } + return arr +} + +// portsToString converts the ports used to a string of the from "port1, port2" +func portsToString(ports []ocicni.PortMapping) string { + var portDisplay []string + if len(ports) == 0 { + return "" + } + for _, v := range ports { + hostIP := v.HostIP + if hostIP == "" { + hostIP = "0.0.0.0" + } + portDisplay = append(portDisplay, fmt.Sprintf("%s:%d->%d/%s", hostIP, v.HostPort, v.ContainerPort, v.Protocol)) + } + return strings.Join(portDisplay, ", ") +} + func printFormat(format string, containers []shared.PsContainerOutput) error { // return immediately if no containers are present if len(containers) == 0 { diff --git a/cmd/podman/run_test.go b/cmd/podman/run_test.go index dea8eb7a27..0bf9cb4d96 100644 --- a/cmd/podman/run_test.go +++ b/cmd/podman/run_test.go @@ -18,6 +18,7 @@ import ( var ( sysInfo = sysinfo.New(true) + cmd = []string{"podman", "test", "alpine"} CLI *cliconfig.PodmanCommand ) diff --git a/cmd/podman/search.go b/cmd/podman/search.go index f72c82b434..e614887fc3 100644 --- a/cmd/podman/search.go +++ b/cmd/podman/search.go @@ -12,6 +12,11 @@ import ( "github.com/spf13/cobra" ) +const ( + descriptionTruncLength = 44 + maxQueries = 25 +) + var ( searchCommand cliconfig.SearchValues searchDescription = `Search registries for a given image. Can search all the default registries or a specific registry. diff --git a/cmd/podman/shared/create.go b/cmd/podman/shared/create.go index 57e509c2a1..cd82e4f1c3 100644 --- a/cmd/podman/shared/create.go +++ b/cmd/podman/shared/create.go @@ -34,6 +34,11 @@ import ( "github.com/sirupsen/logrus" ) +// getContext returns a non-nil, empty context +func getContext() context.Context { + return context.TODO() +} + func CreateContainer(ctx context.Context, c *cliconfig.PodmanCommand, runtime *libpod.Runtime) (*libpod.Container, *cc.CreateConfig, error) { var ( healthCheck *manifest.Schema2HealthConfig diff --git a/cmd/podman/trust_set_show.go b/cmd/podman/trust_set_show.go index cd6c4897ec..626d27aaed 100644 --- a/cmd/podman/trust_set_show.go +++ b/cmd/podman/trust_set_show.go @@ -7,6 +7,7 @@ import ( "strings" "github.com/containers/buildah/pkg/formats" + "github.com/containers/image/types" "github.com/containers/libpod/cmd/podman/cliconfig" "github.com/containers/libpod/cmd/podman/libpodruntime" "github.com/containers/libpod/libpod/image" @@ -236,6 +237,10 @@ func isValidTrustType(t string) bool { return false } +func getDefaultPolicyPath() string { + return trust.DefaultPolicyPath(&types.SystemContext{}) +} + func getPolicyJSON(policyContentStruct trust.PolicyContent, systemRegistriesDirPath string) (map[string]map[string]interface{}, error) { registryConfigs, err := trust.LoadAndMergeConfig(systemRegistriesDirPath) if err != nil { diff --git a/cmd/podman/utils.go b/cmd/podman/utils.go index 2327a943ad..45d081512f 100644 --- a/cmd/podman/utils.go +++ b/cmd/podman/utils.go @@ -7,6 +7,7 @@ import ( "os" gosignal "os/signal" + "github.com/containers/libpod/cmd/podman/cliconfig" "github.com/containers/libpod/libpod" "github.com/docker/docker/pkg/signal" "github.com/docker/docker/pkg/term" @@ -158,6 +159,47 @@ func (f *RawTtyFormatter) Format(entry *logrus.Entry) ([]byte, error) { return bytes, err } +// For pod commands that have a latest and all flag, getPodsFromContext gets +// pods the user specifies. If there's an error before getting pods, the pods slice +// will be empty and error will be not nil. If an error occured after, the pod slice +// will hold all of the successful pods, and error will hold the last error. +// The remaining errors will be logged. On success, pods will hold all pods and +// error will be nil. +func getPodsFromContext(c *cliconfig.PodmanCommand, r *libpod.Runtime) ([]*libpod.Pod, error) { + args := c.InputArgs + var pods []*libpod.Pod + var lastError error + var err error + + if c.Bool("all") { + pods, err = r.GetAllPods() + if err != nil { + return nil, errors.Wrapf(err, "unable to get running pods") + } + } + + if c.Bool("latest") { + pod, err := r.GetLatestPod() + if err != nil { + return nil, errors.Wrapf(err, "unable to get latest pod") + } + pods = append(pods, pod) + } + + for _, i := range args { + pod, err := r.LookupPod(i) + if err != nil { + if lastError != nil { + logrus.Errorf("%q", lastError) + } + lastError = errors.Wrapf(err, "unable to find pod %s", i) + continue + } + pods = append(pods, pod) + } + return pods, lastError +} + //printParallelOutput takes the map of parallel worker results and outputs them // to stdout func printParallelOutput(m map[string]error, errCount int) error { diff --git a/test/e2e/common_test.go b/test/e2e/common_test.go index 0b3db32f4b..b20b3b37ed 100644 --- a/test/e2e/common_test.go +++ b/test/e2e/common_test.go @@ -22,14 +22,15 @@ import ( ) var ( - PODMAN_BINARY string - CONMON_BINARY string - CNI_CONFIG_DIR string - RUNC_BINARY string - INTEGRATION_ROOT string - CGROUP_MANAGER = "systemd" - ARTIFACT_DIR = "/tmp/.artifacts" - RESTORE_IMAGES = []string{ALPINE, BB} + PODMAN_BINARY string + CONMON_BINARY string + CNI_CONFIG_DIR string + RUNC_BINARY string + INTEGRATION_ROOT string + CGROUP_MANAGER = "systemd" + ARTIFACT_DIR = "/tmp/.artifacts" + RESTORE_IMAGES = []string{ALPINE, BB} + defaultWaitTimeout = 90 ) // PodmanTestIntegration struct for command line options