From 76e40248a232aa6b6d01fceede5821d8480c3256 Mon Sep 17 00:00:00 2001 From: Tim Allclair Date: Thu, 8 Aug 2019 13:03:49 -0700 Subject: [PATCH] Add static analysis verify script --- hack/.staticcheck_failures | 304 +++++++++++++++++++++++++++++++++++++ hack/verify-staticcheck.sh | 154 +++++++++++++++++++ 2 files changed, 458 insertions(+) create mode 100644 hack/.staticcheck_failures create mode 100755 hack/verify-staticcheck.sh diff --git a/hack/.staticcheck_failures b/hack/.staticcheck_failures new file mode 100644 index 00000000000..f4036458c03 --- /dev/null +++ b/hack/.staticcheck_failures @@ -0,0 +1,304 @@ +cluster/images/conformance/go-runner +cluster/images/etcd-version-monitor +cluster/images/etcd/migrate +cmd/controller-manager/app +cmd/kube-controller-manager/app +cmd/kube-proxy/app +cmd/kube-scheduler/app +cmd/kubeadm/app/cmd/upgrade +cmd/kubeadm/app/phases/certs/renewal +cmd/kubeadm/app/preflight +cmd/kubeadm/app/util/system +cmd/linkcheck +cmd/preferredimports +hack/make-rules/helpers/go2make/testdata/dir-with-gofiles +pkg/apis/scheduling/v1alpha1 +pkg/apis/scheduling/v1beta1 +pkg/client/tests +pkg/controller/daemon +pkg/controller/deployment +pkg/controller/disruption +pkg/controller/garbagecollector +pkg/controller/namespace/deletion +pkg/controller/nodeipam +pkg/controller/nodeipam/ipam/cidrset +pkg/controller/podautoscaler +pkg/controller/podgc +pkg/controller/replicaset +pkg/controller/resourcequota +pkg/controller/statefulset +pkg/controller/volume/persistentvolume/testing +pkg/controller/volume/scheduling +pkg/credentialprovider +pkg/credentialprovider/aws +pkg/credentialprovider/azure +pkg/kubeapiserver/admission +pkg/kubectl/cmd/get +pkg/kubelet +pkg/kubelet/apis/config +pkg/kubelet/apis/stats/v1alpha1 +pkg/kubelet/checkpoint +pkg/kubelet/cm +pkg/kubelet/cm/cpumanager +pkg/kubelet/cm/cpumanager/state +pkg/kubelet/cm/devicemanager +pkg/kubelet/config +pkg/kubelet/container/testing +pkg/kubelet/dockershim/libdocker +pkg/kubelet/dockershim/network/cni +pkg/kubelet/dockershim/network/kubenet +pkg/kubelet/eviction +pkg/kubelet/kubeletconfig/checkpoint +pkg/kubelet/kuberuntime +pkg/kubelet/kuberuntime/logs +pkg/kubelet/lifecycle +pkg/kubelet/network/dns +pkg/kubelet/pluginmanager +pkg/kubelet/pluginmanager/metrics +pkg/kubelet/pluginmanager/pluginwatcher +pkg/kubelet/pluginmanager/reconciler +pkg/kubelet/remote/fake +pkg/kubelet/server +pkg/kubelet/server/streaming +pkg/kubelet/stats +pkg/kubelet/status +pkg/kubelet/types +pkg/kubelet/util/format +pkg/kubelet/volumemanager/cache +pkg/kubelet/volumemanager/reconciler +pkg/master +pkg/printers +pkg/printers/internalversion +pkg/probe/http +pkg/proxy/healthcheck +pkg/proxy/iptables +pkg/proxy/ipvs +pkg/proxy/userspace +pkg/proxy/winkernel +pkg/proxy/winuserspace +pkg/registry/autoscaling/horizontalpodautoscaler/storage +pkg/registry/core/namespace/storage +pkg/registry/core/persistentvolumeclaim/storage +pkg/registry/core/resourcequota/storage +pkg/registry/core/service/ipallocator +pkg/registry/core/service/portallocator +pkg/registry/core/service/storage +pkg/registry/extensions/controller/storage +pkg/scheduler +pkg/scheduler/algorithm/predicates +pkg/scheduler/algorithm/priorities +pkg/scheduler/api/v1 +pkg/scheduler/apis/config/v1alpha1 +pkg/scheduler/internal/queue +pkg/security/podsecuritypolicy/sysctl +pkg/util/coverage +pkg/util/ebtables +pkg/util/ipconfig +pkg/util/iptables +pkg/util/ipvs/testing +pkg/util/mount +pkg/util/netsh +pkg/volume +pkg/volume/awsebs +pkg/volume/azure_dd +pkg/volume/azure_file +pkg/volume/cephfs +pkg/volume/cinder +pkg/volume/csi +pkg/volume/emptydir +pkg/volume/fc +pkg/volume/flexvolume +pkg/volume/flocker +pkg/volume/hostpath +pkg/volume/iscsi +pkg/volume/local +pkg/volume/portworx +pkg/volume/quobyte +pkg/volume/rbd +pkg/volume/scaleio +pkg/volume/storageos +pkg/volume/util +pkg/volume/util/fsquota +pkg/volume/util/fsquota/common +pkg/volume/util/nsenter +pkg/volume/util/operationexecutor +pkg/volume/util/subpath +pkg/volume/vsphere_volume +plugin/pkg/admission/imagepolicy +plugin/pkg/admission/podnodeselector +test/e2e/apimachinery +test/e2e/apps +test/e2e/auth +test/e2e/autoscaling +test/e2e/common +test/e2e/framework +test/e2e/framework/ingress +test/e2e/framework/kubelet +test/e2e/framework/node +test/e2e/framework/pod +test/e2e/framework/podlogs +test/e2e/framework/providers/aws +test/e2e/framework/providers/gce +test/e2e/framework/psp +test/e2e/framework/service +test/e2e/framework/volume +test/e2e/instrumentation/logging/stackdriver +test/e2e/instrumentation/monitoring +test/e2e/lifecycle +test/e2e/lifecycle/bootstrap +test/e2e/manifest +test/e2e/network +test/e2e/node +test/e2e/scalability +test/e2e/scheduling +test/e2e/storage +test/e2e/storage/drivers +test/e2e/storage/testsuites +test/e2e/storage/utils +test/e2e/storage/vsphere +test/e2e/upgrades +test/e2e/upgrades/storage +test/e2e/windows +test/e2e_node +test/e2e_node/environment +test/e2e_node/remote +test/e2e_node/runner/remote +test/images/agnhost/dns +test/images/agnhost/inclusterclient +test/images/agnhost/net/nat +test/images/agnhost/netexec +test/images/agnhost/pause +test/images/agnhost/serve-hostname +test/images/agnhost/webhook +test/images/pets/peer-finder +test/instrumentation +test/integration/apiserver +test/integration/apiserver/admissionwebhook +test/integration/auth +test/integration/client +test/integration/deployment +test/integration/disruption +test/integration/etcd +test/integration/examples +test/integration/framework +test/integration/garbagecollector +test/integration/kubelet +test/integration/master +test/integration/replicationcontroller +test/integration/scale +test/integration/scheduler +test/integration/scheduler_perf +test/integration/serviceaccount +test/integration/serving +test/integration/ttlcontroller +test/integration/volume +test/integration/volumescheduling +test/utils +vendor/k8s.io/api/events/v1beta1 +vendor/k8s.io/apiextensions-apiserver/pkg/apiserver +vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/conversion +vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema +vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/objectmeta +vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/pruning +vendor/k8s.io/apiextensions-apiserver/pkg/controller/finalizer +vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresource +vendor/k8s.io/apiextensions-apiserver/test/integration +vendor/k8s.io/apiextensions-apiserver/test/integration/conversion +vendor/k8s.io/apiextensions-apiserver/test/integration/fixtures +vendor/k8s.io/apimachinery/pkg/api/meta +vendor/k8s.io/apimachinery/pkg/api/resource +vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured +vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/unstructuredscheme +vendor/k8s.io/apimachinery/pkg/apis/meta/v1/validation +vendor/k8s.io/apimachinery/pkg/conversion +vendor/k8s.io/apimachinery/pkg/labels +vendor/k8s.io/apimachinery/pkg/runtime +vendor/k8s.io/apimachinery/pkg/runtime/serializer +vendor/k8s.io/apimachinery/pkg/runtime/serializer/json +vendor/k8s.io/apimachinery/pkg/runtime/serializer/versioning +vendor/k8s.io/apimachinery/pkg/util/framer +vendor/k8s.io/apimachinery/pkg/util/httpstream/spdy +vendor/k8s.io/apimachinery/pkg/util/net +vendor/k8s.io/apimachinery/pkg/util/sets/types +vendor/k8s.io/apimachinery/pkg/util/strategicpatch +vendor/k8s.io/apimachinery/pkg/util/wait +vendor/k8s.io/apiserver/pkg/admission/initializer +vendor/k8s.io/apiserver/pkg/authentication/request/x509 +vendor/k8s.io/apiserver/pkg/endpoints +vendor/k8s.io/apiserver/pkg/endpoints/filters +vendor/k8s.io/apiserver/pkg/endpoints/handlers +vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager +vendor/k8s.io/apiserver/pkg/endpoints/handlers/responsewriters +vendor/k8s.io/apiserver/pkg/endpoints/metrics +vendor/k8s.io/apiserver/pkg/endpoints/request +vendor/k8s.io/apiserver/pkg/registry/generic/registry +vendor/k8s.io/apiserver/pkg/registry/generic/rest +vendor/k8s.io/apiserver/pkg/registry/rest/resttest +vendor/k8s.io/apiserver/pkg/server +vendor/k8s.io/apiserver/pkg/server/filters +vendor/k8s.io/apiserver/pkg/server/healthz +vendor/k8s.io/apiserver/pkg/server/httplog +vendor/k8s.io/apiserver/pkg/server/options +vendor/k8s.io/apiserver/pkg/server/options/encryptionconfig +vendor/k8s.io/apiserver/pkg/server/routes +vendor/k8s.io/apiserver/pkg/server/storage +vendor/k8s.io/apiserver/pkg/storage +vendor/k8s.io/apiserver/pkg/storage/cacher +vendor/k8s.io/apiserver/pkg/storage/etcd3 +vendor/k8s.io/apiserver/pkg/storage/tests +vendor/k8s.io/apiserver/pkg/storage/value/encrypt/aes +vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope +vendor/k8s.io/apiserver/pkg/storage/value/encrypt/secretbox +vendor/k8s.io/apiserver/pkg/util/webhook +vendor/k8s.io/apiserver/pkg/util/wsstream +vendor/k8s.io/apiserver/plugin/pkg/authenticator/token/oidc +vendor/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook +vendor/k8s.io/apiserver/plugin/pkg/authorizer/webhook +vendor/k8s.io/cli-runtime/pkg/resource +vendor/k8s.io/client-go/discovery/cached/memory +vendor/k8s.io/client-go/dynamic/fake +vendor/k8s.io/client-go/metadata/fake +vendor/k8s.io/client-go/rest +vendor/k8s.io/client-go/rest/watch +vendor/k8s.io/client-go/restmapper +vendor/k8s.io/client-go/testing +vendor/k8s.io/client-go/tools/cache +vendor/k8s.io/client-go/tools/clientcmd +vendor/k8s.io/client-go/tools/leaderelection +vendor/k8s.io/client-go/tools/portforward +vendor/k8s.io/client-go/tools/watch +vendor/k8s.io/client-go/transport +vendor/k8s.io/client-go/util/jsonpath +vendor/k8s.io/cloud-provider/service/helpers +vendor/k8s.io/code-generator/cmd/client-gen/generators/fake +vendor/k8s.io/code-generator/cmd/client-gen/generators/util +vendor/k8s.io/code-generator/cmd/go-to-protobuf/protobuf +vendor/k8s.io/component-base/metrics +vendor/k8s.io/kube-aggregator/pkg/apis/apiregistration +vendor/k8s.io/kube-aggregator/pkg/apis/apiregistration/v1/helper +vendor/k8s.io/kube-aggregator/pkg/controllers/autoregister +vendor/k8s.io/kube-aggregator/pkg/controllers/openapi/aggregator +vendor/k8s.io/kubectl/pkg/cmd/annotate +vendor/k8s.io/kubectl/pkg/cmd/apply +vendor/k8s.io/kubectl/pkg/cmd/certificates +vendor/k8s.io/kubectl/pkg/cmd/config +vendor/k8s.io/kubectl/pkg/cmd/cp +vendor/k8s.io/kubectl/pkg/cmd/edit +vendor/k8s.io/kubectl/pkg/cmd/exec +vendor/k8s.io/kubectl/pkg/cmd/label +vendor/k8s.io/kubectl/pkg/cmd/proxy +vendor/k8s.io/kubectl/pkg/cmd/rollingupdate +vendor/k8s.io/kubectl/pkg/cmd/scale +vendor/k8s.io/kubectl/pkg/cmd/set +vendor/k8s.io/kubectl/pkg/cmd/testing +vendor/k8s.io/kubectl/pkg/cmd/top +vendor/k8s.io/kubectl/pkg/cmd/util/editor +vendor/k8s.io/kubectl/pkg/cmd/wait +vendor/k8s.io/kubectl/pkg/describe/versioned +vendor/k8s.io/kubectl/pkg/scale +vendor/k8s.io/legacy-cloud-providers/aws +vendor/k8s.io/legacy-cloud-providers/azure +vendor/k8s.io/legacy-cloud-providers/gce +vendor/k8s.io/legacy-cloud-providers/vsphere +vendor/k8s.io/metrics/pkg/client/custom_metrics +vendor/k8s.io/sample-controller diff --git a/hack/verify-staticcheck.sh b/hack/verify-staticcheck.sh new file mode 100755 index 00000000000..e05de41ae9c --- /dev/null +++ b/hack/verify-staticcheck.sh @@ -0,0 +1,154 @@ +#!/usr/bin/env bash + +# Copyright 2014 The Kubernetes Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -o errexit +set -o nounset +set -o pipefail + +KUBE_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. +source "${KUBE_ROOT}/hack/lib/init.sh" +source "${KUBE_ROOT}/hack/lib/util.sh" + +kube::golang::verify_go_version + +FOCUS="${1:-}" + +# See https://staticcheck.io/docs/checks +CHECKS=( + "all" + "-S1*" # Omit code simplifications for now. + "-ST1*" # Mostly stylistic, redundant w/ golint +) +export IFS=','; checks="${CHECKS[*]}"; unset IFS + +# Packages to ignore due to bugs in staticcheck +# NOTE: To ignore issues detected a package, add it to the .staticcheck_failures blacklist +IGNORE=( + "vendor/k8s.io/kubectl/pkg/cmd/edit/testdata" # golang/go#24854, dominikh/go-tools#565 +) +export IFS='|'; ignore_pattern="^(${IGNORE[*]})\$"; unset IFS + +# Ensure that we find the binaries we build before anything else. +export GOBIN="${KUBE_OUTPUT_BINPATH}" +PATH="${GOBIN}:${PATH}" + +# Install staticcheck from vendor +echo 'installing staticcheck from vendor' +go install k8s.io/kubernetes/vendor/honnef.co/go/tools/cmd/staticcheck + +cd "${KUBE_ROOT}" + +# Check that the file is in alphabetical order +failure_file="${KUBE_ROOT}/hack/.staticcheck_failures" +kube::util::check-file-in-alphabetical-order "${failure_file}" + +export IFS=$'\n' +# NOTE: when "go list -e ./..." is run within GOPATH, it turns the k8s.io/kubernetes +# as the prefix, however if we run it outside it returns the full path of the file +# with a leading underscore. We'll need to support both scenarios for all_packages. +all_packages=() +while IFS='' read -r line; do + all_packages+=("./$line") +done < <( hack/make-rules/helpers/cache_go_dirs.sh "${KUBE_ROOT}/_tmp/all_go_dirs" | + grep "^${FOCUS:-.}" | + grep -vE "(third_party|generated|clientset_generated|/_)" | + grep -vE "$ignore_pattern" ) + +failing_packages=() +if [[ -z $FOCUS ]]; then # Ignore failing_packages in FOCUS mode + while IFS='' read -r line; do failing_packages+=("$line"); done < <(cat "$failure_file") +fi +unset IFS +errors=() +not_failing=() + +while read -r error; do + # Ignore compile errors caused by lack of files due to build tags. + # TODO: Add verification for these directories. + ignore_no_files="^-: build constraints exclude all Go files in .* \(compile\)" + if [[ $error =~ $ignore_no_files ]]; then + continue + fi + + file="${error%%:*}" + pkg="$(dirname "$file")" + kube::util::array_contains "$pkg" "${failing_packages[@]}" && in_failing=$? || in_failing=$? + if [[ "${in_failing}" -ne "0" ]]; then + errors+=( "${error}" ) + elif [[ "${in_failing}" -eq "0" ]]; then + really_failing+=( "$pkg" ) + fi +done < <(staticcheck -checks "${checks}" "${all_packages[@]}" 2>/dev/null || true) + +export IFS=$'\n' +mapfile -t really_failing < <(sort -u <<<"${really_failing[*]}") +unset IFS +for pkg in "${failing_packages[@]}"; do + if ! kube::util::array_contains "$pkg" "${really_failing[@]}"; then + not_failing+=( "$pkg" ) + fi +done + +# Check that all failing_packages actually still exist +gone=() +for p in "${failing_packages[@]}"; do + if ! kube::util::array_contains "./$p" "${all_packages[@]}"; then + gone+=( "$p" ) + fi +done + +# Check to be sure all the packages that should pass check are. +if [ ${#errors[@]} -eq 0 ]; then + echo 'Congratulations! All Go source files have been checked.' +else + { + echo "Errors from staticcheck:" + for err in "${errors[@]}"; do + echo "$err" + done + echo + echo 'Please review the above warnings. You can test via:' + echo " staticcheck -checks \"${checks}\"" + echo 'If the above warnings do not make sense, you can exempt the line or file. See:' + echo ' https://staticcheck.io/docs/#ignoring-problems' + echo + } >&2 + exit 1 +fi + +if [[ ${#not_failing[@]} -gt 0 ]]; then + { + echo "Some packages in hack/.staticcheck_failures are passing staticcheck. Please remove them." + echo + for p in "${not_failing[@]}"; do + echo " $p" + done + echo + } >&2 + exit 1 +fi + +if [[ ${#gone[@]} -gt 0 ]]; then + { + echo "Some packages in hack/.staticcheck_failures do not exist anymore. Please remove them." + echo + for p in "${gone[@]}"; do + echo " $p" + done + echo + } >&2 + exit 1 +fi