diff --git a/.github/workflows/linux.yaml b/.github/workflows/linux.yaml index 057b765d..cc8ada77 100644 --- a/.github/workflows/linux.yaml +++ b/.github/workflows/linux.yaml @@ -1,4 +1,4 @@ -name: Sanity tests +name: Linux basic tests on: pull_request: {} push: {} @@ -27,3 +27,7 @@ jobs: make echo "is running in github actions: $GITHUB_ACTIONS" make sanity-test + + - name: Verification test + run: | + ./hack/verify-all.sh diff --git a/examples/kubernetes/pv.yaml b/examples/kubernetes/pv.yaml index e7c452ae..57bcc8c3 100644 --- a/examples/kubernetes/pv.yaml +++ b/examples/kubernetes/pv.yaml @@ -16,7 +16,7 @@ spec: volumeAttributes: targetPortal: "192.168.122.145:3260" portals: "[]" - iqn: "iqn.2003-01.org.linux-iscsi.example:targetd" + iqn: "iqn.2003-01.org.linux-iscsi.example:targeted" lun: "0" iscsiInterface: "default" discoveryCHAPAuth: "false" diff --git a/hack/boilerplate/boilerplate.Dockerfile.txt b/hack/boilerplate/boilerplate.Dockerfile.txt new file mode 100644 index 00000000..34cb349c --- /dev/null +++ b/hack/boilerplate/boilerplate.Dockerfile.txt @@ -0,0 +1,13 @@ +# Copyright YEAR 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. diff --git a/hack/boilerplate/boilerplate.Makefile.txt b/hack/boilerplate/boilerplate.Makefile.txt new file mode 100644 index 00000000..d0d52652 --- /dev/null +++ b/hack/boilerplate/boilerplate.Makefile.txt @@ -0,0 +1,13 @@ +# Copyright YEAR 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. \ No newline at end of file diff --git a/hack/boilerplate/boilerplate.bzl.txt b/hack/boilerplate/boilerplate.bzl.txt new file mode 100644 index 00000000..d0d52652 --- /dev/null +++ b/hack/boilerplate/boilerplate.bzl.txt @@ -0,0 +1,13 @@ +# Copyright YEAR 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. \ No newline at end of file diff --git a/hack/boilerplate/boilerplate.go.txt b/hack/boilerplate/boilerplate.go.txt new file mode 100644 index 00000000..3249913b --- /dev/null +++ b/hack/boilerplate/boilerplate.go.txt @@ -0,0 +1,15 @@ +/* +Copyright YEAR 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. +*/ \ No newline at end of file diff --git a/hack/boilerplate/boilerplate.py b/hack/boilerplate/boilerplate.py new file mode 100755 index 00000000..63f74963 --- /dev/null +++ b/hack/boilerplate/boilerplate.py @@ -0,0 +1,202 @@ +#!/usr/bin/env python + +# Copyright 2019 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. + +from __future__ import print_function + +import argparse +import difflib +import glob +import json +import mmap +import os +import re +import sys +from datetime import date + +parser = argparse.ArgumentParser() +parser.add_argument( + "filenames", + help="list of files to check, all files if unspecified", + nargs='*') + +# Rootdir defaults to the directory **above** the repo-infra dir. +rootdir = os.path.dirname(__file__) + "./../../../" +rootdir = os.path.abspath(rootdir) +parser.add_argument( + "--rootdir", default=rootdir, help="root directory to examine") + +default_boilerplate_dir = os.path.join(rootdir, "csi-driver-nfs/hack/boilerplate") + +parser.add_argument( + "--boilerplate-dir", default=default_boilerplate_dir) + +parser.add_argument( + "-v", "--verbose", + help="give verbose output regarding why a file does not pass", + action="store_true") + +args = parser.parse_args() + +verbose_out = sys.stderr if args.verbose else open("/dev/null", "w") + +def get_refs(): + refs = {} + + for path in glob.glob(os.path.join(args.boilerplate_dir, "boilerplate.*.txt")): + extension = os.path.basename(path).split(".")[1] + + ref_file = open(path, 'r') + ref = ref_file.read().splitlines() + ref_file.close() + refs[extension] = ref + + return refs + +def file_passes(filename, refs, regexs): + try: + f = open(filename, 'r') + except Exception as exc: + print("Unable to open %s: %s" % (filename, exc), file=verbose_out) + return False + + data = f.read() + f.close() + + basename = os.path.basename(filename) + extension = file_extension(filename) + if extension != "": + ref = refs[extension] + else: + ref = refs[basename] + + # remove build tags from the top of Go files + if extension == "go": + p = regexs["go_build_constraints"] + (data, found) = p.subn("", data, 1) + + # remove shebang from the top of shell files + if extension == "sh" or extension == "py": + p = regexs["shebang"] + (data, found) = p.subn("", data, 1) + + data = data.splitlines() + + # if our test file is smaller than the reference it surely fails! + if len(ref) > len(data): + print('File %s smaller than reference (%d < %d)' % + (filename, len(data), len(ref)), + file=verbose_out) + return False + + # trim our file to the same number of lines as the reference file + data = data[:len(ref)] + + p = regexs["year"] + for d in data: + if p.search(d): + print('File %s is missing the year' % filename, file=verbose_out) + return False + + # Replace all occurrences of the regex "CURRENT_YEAR|...|2016|2015|2014" with "YEAR" + p = regexs["date"] + for i, d in enumerate(data): + (data[i], found) = p.subn('YEAR', d) + if found != 0: + break + + # if we don't match the reference at this point, fail + if ref != data: + print("Header in %s does not match reference, diff:" % filename, file=verbose_out) + if args.verbose: + print(file=verbose_out) + for line in difflib.unified_diff(ref, data, 'reference', filename, lineterm=''): + print(line, file=verbose_out) + print(file=verbose_out) + return False + + return True + +def file_extension(filename): + return os.path.splitext(filename)[1].split(".")[-1].lower() + +skipped_dirs = ['Godeps', 'third_party', '_gopath', '_output', '.git', + 'cluster/env.sh', 'vendor', 'test/e2e/generated/bindata.go', + 'repo-infra/verify/boilerplate/test', '.glide'] + +def normalize_files(files): + newfiles = [] + for pathname in files: + if any(x in pathname for x in skipped_dirs): + continue + newfiles.append(pathname) + return newfiles + +def get_files(extensions): + files = [] + if len(args.filenames) > 0: + files = args.filenames + else: + for root, dirs, walkfiles in os.walk(args.rootdir): + # don't visit certain dirs. This is just a performance improvement + # as we would prune these later in normalize_files(). But doing it + # cuts down the amount of filesystem walking we do and cuts down + # the size of the file list + for d in skipped_dirs: + if d in dirs: + dirs.remove(d) + + for name in walkfiles: + pathname = os.path.join(root, name) + files.append(pathname) + + files = normalize_files(files) + + outfiles = [] + for pathname in files: + basename = os.path.basename(pathname) + extension = file_extension(pathname) + if extension in extensions or basename in extensions: + outfiles.append(pathname) + return outfiles + +def get_regexs(): + regexs = {} + # Search for "YEAR" which exists in the boilerplate, but shouldn't in the real thing + regexs["year"] = re.compile( 'YEAR' ) + # dates can be 2014, 2015, 2016, ..., CURRENT_YEAR, company holder names can be anything + years = range(2014, date.today().year + 1) + regexs["date"] = re.compile( '(%s)' % "|".join(map(lambda l: str(l), years)) ) + # strip // +build \n\n build constraints + regexs["go_build_constraints"] = re.compile(r"^(// \+build.*\n)+\n", re.MULTILINE) + # strip #!.* from shell scripts + regexs["shebang"] = re.compile(r"^(#!.*\n)\n*", re.MULTILINE) + return regexs + + + +def main(): + regexs = get_regexs() + refs = get_refs() + filenames = get_files(refs.keys()) + + for filename in filenames: + if not file_passes(filename, refs, regexs): + print(filename, file=sys.stdout) + + return 0 + +if __name__ == "__main__": + sys.exit(main()) \ No newline at end of file diff --git a/hack/boilerplate/boilerplate.py.txt b/hack/boilerplate/boilerplate.py.txt new file mode 100644 index 00000000..34cb349c --- /dev/null +++ b/hack/boilerplate/boilerplate.py.txt @@ -0,0 +1,13 @@ +# Copyright YEAR 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. diff --git a/hack/boilerplate/boilerplate.sh.txt b/hack/boilerplate/boilerplate.sh.txt new file mode 100644 index 00000000..d0d52652 --- /dev/null +++ b/hack/boilerplate/boilerplate.sh.txt @@ -0,0 +1,13 @@ +# Copyright YEAR 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. \ No newline at end of file diff --git a/hack/release-image.sh b/hack/release-image.sh new file mode 100755 index 00000000..9c026371 --- /dev/null +++ b/hack/release-image.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +# Copyright 2020 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 -euo pipefail + +if [[ "$#" -lt 1 ]]; then + echo "please provide a registry name" + exit 1 +fi + +export REGISTRY_NAME="$1" +export REGISTRY=$REGISTRY_NAME.azurecr.io +export IMAGENAME=public/k8s/csi/nfs-csi +export CI=1 +export PUBLISH=1 +az acr login --name $REGISTRY_NAME +make container push push-latest + +echo "sleep 60s ..." +sleep 60 +image="mcr.microsoft.com/k8s/csi/nfs-csi:latest" +docker pull $image +docker inspect $image | grep Created diff --git a/hack/update-dependencies.sh b/hack/update-dependencies.sh new file mode 100755 index 00000000..83c51808 --- /dev/null +++ b/hack/update-dependencies.sh @@ -0,0 +1,108 @@ +#!/bin/bash +# Copyright 2019 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 nounset +set -o errexit +set -o pipefail + +# Explicitly opt into go modules, even though we're inside a GOPATH directory +export GO111MODULE=on +# Explicitly clear GOPATH, to ensure nothing this script calls makes use of that path info +export GOPATH= +# Explicitly clear GOFLAGS, since GOFLAGS=-mod=vendor breaks dependency resolution while rebuilding vendor +export GOFLAGS= + +cd "$(git rev-parse --show-toplevel)" +trap 'echo "FAILED" >&2' ERR +TMP_DIR="${TMP_DIR:-$(mktemp -d /tmp/update-vendor.XXXX)}" + +prune-vendor() { + find vendor -type f \ + -not -iname "*.c" \ + -not -iname "*.go" \ + -not -iname "*.h" \ + -not -iname "*.proto" \ + -not -iname "*.s" \ + -not -iname "AUTHORS*" \ + -not -iname "CONTRIBUTORS*" \ + -not -iname "COPYING*" \ + -not -iname "LICENSE*" \ + -not -iname "NOTICE*" \ + -delete +} + +# ensure_require_replace_directives_for_all_dependencies: +# - ensures all existing 'require' directives have an associated 'replace' directive pinning a version +# - adds explicit 'require' directives for all transitive dependencies +# - adds explicit 'replace' directives for all require directives (existing 'replace' directives take precedence) +function ensure_require_replace_directives_for_all_dependencies() { + local local_tmp_dir + local_tmp_dir=$(mktemp -d "${TMP_DIR}/pin_replace.XXXX") + + # collect 'require' directives that actually specify a version + local require_filter='(.Version != null) and (.Version != "v0.0.0") and (.Version != "v0.0.0-00010101000000-000000000000")' + # collect 'replace' directives that unconditionally pin versions (old=new@version) + local replace_filter='(.Old.Version == null) and (.New.Version != null)' + + # Capture local require/replace directives before running any go commands that can modify the go.mod file + local require_json="${local_tmp_dir}/require.json" + local replace_json="${local_tmp_dir}/replace.json" + go mod edit -json | jq -r ".Require // [] | sort | .[] | select(${require_filter})" > "${require_json}" + go mod edit -json | jq -r ".Replace // [] | sort | .[] | select(${replace_filter})" > "${replace_json}" + + # 1. Ensure require directives have a corresponding replace directive pinning a version + cat "${require_json}" | jq -r '"-replace \(.Path)=\(.Path)@\(.Version)"' | xargs -L 100 go mod edit -fmt + cat "${replace_json}" | jq -r '"-replace \(.Old.Path)=\(.New.Path)@\(.New.Version)"'| xargs -L 100 go mod edit -fmt + + # 2. Add explicit require directives for indirect dependencies + go list -m -json all | jq -r 'select(.Main != true) | select(.Indirect == true) | "-require \(.Path)@\(.Version)"' | xargs -L 100 go mod edit -fmt + + # 3. Add explicit replace directives pinning dependencies that aren't pinned yet + go list -m -json all | jq -r 'select(.Main != true) | select(.Replace == null) | "-replace \(.Path)=\(.Path)@\(.Version)"' | xargs -L 100 go mod edit -fmt +} + +function group_replace_directives() { + local local_tmp_dir + local_tmp_dir=$(mktemp -d "${TMP_DIR}/group_replace.XXXX") + local go_mod_replace="${local_tmp_dir}/go.mod.replace.tmp" + local go_mod_noreplace="${local_tmp_dir}/go.mod.noreplace.tmp" + # separate replace and non-replace directives + cat go.mod | awk " + # print lines between 'replace (' ... ')' lines + /^replace [(]/ { inreplace=1; next } + inreplace && /^[)]/ { inreplace=0; next } + inreplace { print > \"${go_mod_replace}\"; next } + + # print ungrouped replace directives with the replace directive trimmed + /^replace [^(]/ { sub(/^replace /,\"\"); print > \"${go_mod_replace}\"; next } + + # otherwise print to the noreplace file + { print > \"${go_mod_noreplace}\" } + " + cat "${go_mod_noreplace}" > go.mod + echo "replace (" >> go.mod + cat "${go_mod_replace}" >> go.mod + echo ")" >> go.mod + + go mod edit -fmt +} + +ensure_require_replace_directives_for_all_dependencies +go mod tidy +ensure_require_replace_directives_for_all_dependencies +group_replace_directives +go mod vendor +#prune-vendor +echo SUCCESS diff --git a/hack/update-gofmt.sh b/hack/update-gofmt.sh new file mode 100755 index 00000000..0f2f694f --- /dev/null +++ b/hack/update-gofmt.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +# Copyright 2018 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 -euo pipefail + +find . -name "*.go" | grep -v "\/vendor\/" | xargs gofmt -s -w diff --git a/hack/update-gomod.sh b/hack/update-gomod.sh new file mode 100755 index 00000000..964105d1 --- /dev/null +++ b/hack/update-gomod.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +# Copyright 2020 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 -euo pipefail + +VERSION=${1#"v"} +if [ -z "$VERSION" ]; then + echo "Must specify version!" + exit 1 +fi +MODS=($( + curl -sS https://raw.githubusercontent.com/kubernetes/kubernetes/v${VERSION}/go.mod | + sed -n 's|.*k8s.io/\(.*\) => ./staging/src/k8s.io/.*|k8s.io/\1|p' +)) +for MOD in "${MODS[@]}"; do + echo $MOD + V=$( + go mod download -json "${MOD}@kubernetes-${VERSION}" | + sed -n 's|.*"Version": "\(.*\)".*|\1|p' + ) + echo ${V} + go mod edit "-replace=${MOD}=${MOD}@${V}" +done diff --git a/hack/verify-all.sh b/hack/verify-all.sh new file mode 100755 index 00000000..0c0bca08 --- /dev/null +++ b/hack/verify-all.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +# Copyright 2018 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 -euo pipefail + +readonly PKG_ROOT="$(git rev-parse --show-toplevel)" + +${PKG_ROOT}/hack/verify-gofmt.sh +${PKG_ROOT}/hack/verify-govet.sh +#${PKG_ROOT}/hack/verify-golint.sh +#${PKG_ROOT}/hack/verify-yamllint.sh +#${PKG_ROOT}/hack/verify-boilerplate.sh +${PKG_ROOT}/hack/verify-spelling.sh +${PKG_ROOT}/hack/verify-gomod.sh diff --git a/hack/verify-boilerplate.sh b/hack/verify-boilerplate.sh new file mode 100755 index 00000000..70aa0d22 --- /dev/null +++ b/hack/verify-boilerplate.sh @@ -0,0 +1,51 @@ +#!/bin/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 + +echo "Verifying boilerplate" + +if [[ -z "$(command -v python)" ]]; then + echo "Cannot find python. Make link to python3..." + update-alternatives --install /usr/bin/python python /usr/bin/python3 1 +fi + +REPO_ROOT=$(dirname "${BASH_SOURCE}")/.. + +boilerDir="${REPO_ROOT}/hack/boilerplate" +boiler="${boilerDir}/boilerplate.py" + +files_need_boilerplate=($(${boiler} --rootdir=${REPO_ROOT} --verbose)) + +# Run boilerplate.py unit tests +unitTestOut="$(mktemp)" +trap cleanup EXIT +cleanup() { + rm "${unitTestOut}" +} + +# Run boilerplate check +if [[ ${#files_need_boilerplate[@]} -gt 0 ]]; then + for file in "${files_need_boilerplate[@]}"; do + echo "Boilerplate header is wrong for: ${file}" + done + + exit 1 +fi + +echo "Done" diff --git a/hack/verify-examples.sh b/hack/verify-examples.sh new file mode 100755 index 00000000..aac53e58 --- /dev/null +++ b/hack/verify-examples.sh @@ -0,0 +1,49 @@ +#!/bin/bash +# Copyright 2020 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 -euo pipefail + +rollout_and_wait() { + echo "Applying config \"$1\"" + trap "echo \"Failed to apply config \\\"$1\\\"\" >&2" err + + APPNAME=$(kubectl apply -f $1 | grep -E "^(:?daemonset|deployment|statefulset|pod)" | awk '{printf $1}') + if [[ -n $(expr "${APPNAME}" : "\(daemonset\|deployment\|statefulset\)" || true) ]]; then + kubectl rollout status $APPNAME --watch --timeout=5m + else + kubectl wait "${APPNAME}" --for condition=ready --timeout=5m + fi +} + +echo "begin to create deployment examples ..." + +kubectl apply -f ./deploy/example/storageclass-nfs.yaml + +EXAMPLES+=(\ + deploy/example/deployment.yaml \ + deploy/example/statefulset.yaml \ +) + +if [[ "$#" -gt 0 ]]&&[[ "$1" == *"ephemeral"* ]]; then + EXAMPLES+=(\ + deploy/example/daemonset-nfs-ephemeral.yaml \ + ) +fi + +for EXAMPLE in "${EXAMPLES[@]}"; do + rollout_and_wait $EXAMPLE +done + +echo "deployment examples running completed." diff --git a/hack/verify-gofmt.sh b/hack/verify-gofmt.sh new file mode 100755 index 00000000..8fcb6f0d --- /dev/null +++ b/hack/verify-gofmt.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +# Copyright 2018 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 -euo pipefail + +echo "Verifying gofmt" + +readonly diff=$(find . -name "*.go" | grep -v "\/vendor\/" | xargs gofmt -s -d 2>&1) +if [[ -n "${diff}" ]]; then + echo "${diff}" + echo + echo "Please run hack/update-gofmt.sh to fix the issue(s)" + exit 1 +fi +echo "No issue found" diff --git a/hack/verify-golint.sh b/hack/verify-golint.sh new file mode 100755 index 00000000..81fc83fb --- /dev/null +++ b/hack/verify-golint.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +# Copyright 2018 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 -euo pipefail + +if [[ -z "$(command -v golangci-lint)" ]]; then + echo "Cannot find golangci-lint. Installing golangci-lint..." + curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.31.0 + export PATH=$PATH:$(go env GOPATH)/bin +fi + +echo "Verifying golint" + +golangci-lint run --no-config --enable=golint --disable=typecheck --deadline=10m + +echo "Congratulations! Lint check completed for all Go source files." diff --git a/hack/verify-gomod.sh b/hack/verify-gomod.sh new file mode 100755 index 00000000..d45a265d --- /dev/null +++ b/hack/verify-gomod.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +# Copyright 2020 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 -euo pipefail + +echo "Verifying gomod" +export GO111MODULE=on +echo "go mod tidy" +go mod tidy +echo "go mod vendor" +go mod vendor +diff=`git diff` +if [[ -n "${diff}" ]]; then + echo "${diff}" + echo + echo "error" + exit 1 +fi +echo "Done" diff --git a/hack/verify-govet.sh b/hack/verify-govet.sh new file mode 100755 index 00000000..03d95996 --- /dev/null +++ b/hack/verify-govet.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +# Copyright 2018 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 -euo pipefail + +echo "Verifying govet" + +go vet $(go list ./... | grep -v vendor) + +echo "Done" diff --git a/hack/verify-spelling.sh b/hack/verify-spelling.sh new file mode 100755 index 00000000..9a41c931 --- /dev/null +++ b/hack/verify-spelling.sh @@ -0,0 +1,57 @@ +#!/usr/bin/env bash + +# Copyright 2019 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 + +TOOL_VERSION="v0.3.4" + +# cd to the root path +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)" +cd "${ROOT}" + +# create a temporary directory +TMP_DIR=$(mktemp -d) + +# cleanup +exitHandler() ( + echo "Cleaning up..." + rm -rf "${TMP_DIR}" +) +trap exitHandler EXIT + +if [[ -z "$(command -v misspell)" ]]; then + echo "Cannot find misspell. Installing misspell..." + # perform go get in a temp dir as we are not tracking this version in a go module + # if we do the go get in the repo, it will create / update a go.mod and go.sum + cd "${TMP_DIR}" + GO111MODULE=on GOBIN="${TMP_DIR}" go get "github.com/client9/misspell/cmd/misspell@${TOOL_VERSION}" + export PATH="${TMP_DIR}:${PATH}" +fi +cd "${ROOT}" + +# check spelling +RES=0 +echo "Checking spelling..." +ERROR_LOG="${TMP_DIR}/errors.log" +git ls-files | grep -v vendor | xargs misspell > "${ERROR_LOG}" +if [[ -s "${ERROR_LOG}" ]]; then + sed 's/^/error: /' "${ERROR_LOG}" # add 'error' to each line to highlight in e2e status + echo "Found spelling errors!" + RES=1 +fi +exit "${RES}" diff --git a/hack/verify-update.sh b/hack/verify-update.sh new file mode 100755 index 00000000..fc7f26f3 --- /dev/null +++ b/hack/verify-update.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +# Copyright 2018 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 -euo pipefail + +echo 'Verifying dependency update' + +if [[ -n "$(git diff --shortstat)" ]]; then + echo 'Some files got changed after dependencies update' + git --no-pager diff + exit 1 +fi + +echo 'Done' diff --git a/hack/verify-yamllint.sh b/hack/verify-yamllint.sh new file mode 100755 index 00000000..634f384f --- /dev/null +++ b/hack/verify-yamllint.sh @@ -0,0 +1,54 @@ +#!/bin/bash + +# Copyright 2020 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. + +if [[ -z "$(command -v yamllint)" ]]; then + apt update && apt install yamllint -y +fi + +LOG=/tmp/yamllint.log +helmPath=charts/latest/csi-driver-nfs/templates + +echo "checking yaml files num ..." +deployDirNum=`ls deploy/*.yaml | wc -l` +helmDirNum=`ls $helmPath/*.yaml | grep -v serviceaccount | wc -l` +if [[ "${deployDirNum}" != "${helmDirNum}" ]]; then + echo "yaml file num($deployDirNum) under deploy/ not equal to num($helmDirNum) under $helmPath" + exit 1 +fi + +for path in "deploy/*.yaml" "deploy/example/*.yaml" "deploy/example/nfs-provisioner/*.yaml" +do + echo "checking yamllint under path: $path ..." + yamllint -f parsable $path | grep -v "line too long" > $LOG + cat $LOG + linecount=`cat $LOG | grep -v "line too long" | wc -l` + if [ $linecount -gt 0 ]; then + echo "yaml files under $path are not linted, failed with: " + cat $LOG + exit 1 + fi +done + +echo "checking yamllint under path: $helmPath ..." +yamllint -f parsable $helmPath/*.yaml | grep -v "line too long" | grep -v "too many spaces inside braces" | grep -v "missing document start" | grep -v "syntax error" > $LOG +linecount=`cat $LOG | wc -l` +if [ $linecount -gt 0 ]; then + echo "yaml files under $helmPath/ are not linted, failed with: " + cat $LOG + exit 1 +fi + +echo "Congratulations! All Yaml files have been linted."