mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-03 19:58:17 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			347 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			347 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
#!/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
 | 
						|
 | 
						|
# Go tools really don't like it if you have a symlink in `pwd`.
 | 
						|
cd "$(pwd -P)"
 | 
						|
 | 
						|
KUBE_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
 | 
						|
source "${KUBE_ROOT}/hack/lib/init.sh"
 | 
						|
 | 
						|
# Get all the default Go environment.
 | 
						|
kube::golang::setup_env
 | 
						|
 | 
						|
# Turn off workspaces until we are ready for them later
 | 
						|
export GOWORK=off
 | 
						|
# Explicitly opt into go modules
 | 
						|
export GO111MODULE=on
 | 
						|
# Explicitly set GOFLAGS to ignore vendor, since GOFLAGS=-mod=vendor breaks dependency resolution while rebuilding vendor
 | 
						|
export GOFLAGS=-mod=mod
 | 
						|
# Ensure sort order doesn't depend on locale
 | 
						|
export LANG=C
 | 
						|
export LC_ALL=C
 | 
						|
# Detect problematic GOPROXY settings that prevent lookup of dependencies
 | 
						|
if [[ "${GOPROXY:-}" == "off" ]]; then
 | 
						|
  kube::log::error "Cannot run hack/update-vendor.sh with \$GOPROXY=off"
 | 
						|
  exit 1
 | 
						|
fi
 | 
						|
 | 
						|
kube::util::require-jq
 | 
						|
 | 
						|
TMP_DIR="${TMP_DIR:-$(mktemp -d /tmp/update-vendor.XXXX)}"
 | 
						|
LOG_FILE="${LOG_FILE:-${TMP_DIR}/update-vendor.log}"
 | 
						|
kube::log::status "logfile at ${LOG_FILE}"
 | 
						|
 | 
						|
# Set up some FDs for this script to use, while capturing everything else to
 | 
						|
# the log. NOTHING ELSE should write to $LOG_FILE directly.
 | 
						|
exec 11>&1            # Real stdout, use this explicitly
 | 
						|
exec 22>&2            # Real stderr, use this explicitly
 | 
						|
exec 1>"${LOG_FILE}"  # Automatic stdout
 | 
						|
exec 2>&1             # Automatic stderr
 | 
						|
set -x                # Trace this script to stderr
 | 
						|
go env                # For the log
 | 
						|
 | 
						|
function finish {
 | 
						|
  ret=$?
 | 
						|
  if [[ ${ret} != 0 ]]; then
 | 
						|
    echo "An error has occurred. Please see more details in ${LOG_FILE}" >&22
 | 
						|
  fi
 | 
						|
  exit ${ret}
 | 
						|
}
 | 
						|
trap finish EXIT
 | 
						|
 | 
						|
function print_go_mod_section() {
 | 
						|
  local directive="$1"
 | 
						|
  local file="$2"
 | 
						|
 | 
						|
  if [ -s "${file}" ]; then
 | 
						|
      echo "${directive} ("
 | 
						|
      cat "$file"
 | 
						|
      echo ")"
 | 
						|
  fi
 | 
						|
}
 | 
						|
 | 
						|
function group_directives() {
 | 
						|
  local local_tmp_dir
 | 
						|
  local_tmp_dir=$(mktemp -d "${TMP_DIR}/group_replace.XXXX")
 | 
						|
  local go_mod_require_direct="${local_tmp_dir}/go.mod.require_direct.tmp"
 | 
						|
  local go_mod_require_indirect="${local_tmp_dir}/go.mod.require_indirect.tmp"
 | 
						|
  local go_mod_replace="${local_tmp_dir}/go.mod.replace.tmp"
 | 
						|
  local go_mod_other="${local_tmp_dir}/go.mod.other.tmp"
 | 
						|
  # separate replace and non-replace directives
 | 
						|
  awk "
 | 
						|
     # print lines between 'require (' ... ')' lines
 | 
						|
     /^require [(]/          { inrequire=1; next                            }
 | 
						|
     inrequire && /^[)]/     { inrequire=0; next                            }
 | 
						|
     inrequire && /\/\/ indirect/ { print > \"${go_mod_require_indirect}\"; next }
 | 
						|
     inrequire               { print > \"${go_mod_require_direct}\";   next }
 | 
						|
 | 
						|
     # 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 }
 | 
						|
 | 
						|
     # print ungrouped require directives with the require directive trimmed
 | 
						|
     /^require [^(].*\/\/ indirect/ { sub(/^require /,\"\"); print > \"${go_mod_require_indirect}\"; next }
 | 
						|
     /^require [^(]/ { sub(/^require /,\"\"); print > \"${go_mod_require_direct}\"; next }
 | 
						|
 | 
						|
     # otherwise print to the other file
 | 
						|
     { print > \"${go_mod_other}\" }
 | 
						|
  " < go.mod
 | 
						|
  {
 | 
						|
    cat "${go_mod_other}";
 | 
						|
    print_go_mod_section "require" "${go_mod_require_direct}"
 | 
						|
    print_go_mod_section "require" "${go_mod_require_indirect}"
 | 
						|
    print_go_mod_section "replace" "${go_mod_replace}"
 | 
						|
  } > go.mod
 | 
						|
 | 
						|
  go mod edit -fmt
 | 
						|
}
 | 
						|
 | 
						|
function add_generated_comments() {
 | 
						|
  local local_tmp_dir
 | 
						|
  local_tmp_dir=$(mktemp -d "${TMP_DIR}/add_generated_comments.XXXX")
 | 
						|
  local go_mod_nocomments="${local_tmp_dir}/go.mod.nocomments.tmp"
 | 
						|
 | 
						|
  # drop comments before the module directive
 | 
						|
  awk "
 | 
						|
     BEGIN           { dropcomments=1 }
 | 
						|
     /^module /      { dropcomments=0 }
 | 
						|
     dropcomments && /^\/\// { next }
 | 
						|
     { print }
 | 
						|
  " < go.mod > "${go_mod_nocomments}"
 | 
						|
 | 
						|
  # Add the specified comments
 | 
						|
  local comments="${1}"
 | 
						|
  {
 | 
						|
    echo "${comments}"
 | 
						|
    echo ""
 | 
						|
    cat "${go_mod_nocomments}"
 | 
						|
   } > go.mod
 | 
						|
 | 
						|
  # Format
 | 
						|
  go mod edit -fmt
 | 
						|
}
 | 
						|
 | 
						|
function add_staging_replace_directives() {
 | 
						|
  local path_to_staging_k8s_io="$1"
 | 
						|
  # Prune
 | 
						|
  go mod edit -json \
 | 
						|
      | jq -r '.Require[]? | select(.Version == "v0.0.0")                 | "-droprequire \(.Path)"' \
 | 
						|
      | xargs -L 100 go mod edit -fmt
 | 
						|
  go mod edit -json \
 | 
						|
      | jq -r '.Replace[]? | select(.New.Path | startswith("'"${path_to_staging_k8s_io}"'")) | "-dropreplace \(.Old.Path)"' \
 | 
						|
      | xargs -L 100 go mod edit -fmt
 | 
						|
  # Re-add
 | 
						|
  kube::util::list_staging_repos \
 | 
						|
      | while read -r X; do echo "-require k8s.io/${X}@v0.0.0"; done \
 | 
						|
      | xargs -L 100 go mod edit -fmt
 | 
						|
  kube::util::list_staging_repos \
 | 
						|
      | while read -r X; do echo "-replace k8s.io/${X}=${path_to_staging_k8s_io}/${X}"; done \
 | 
						|
      | xargs -L 100 go mod edit -fmt
 | 
						|
}
 | 
						|
 | 
						|
# === Capture go / godebug directives from root go.mod
 | 
						|
go_directive_value=$(grep '^go 1.' go.mod | awk '{print $2}' || true)
 | 
						|
if [[ -z "${go_directive_value}" ]]; then
 | 
						|
  kube::log::error "root go.mod must have 'go 1.x.y' directive" >&22 2>&1
 | 
						|
  exit 1
 | 
						|
fi
 | 
						|
godebug_directive_value=$(grep 'godebug default=go' go.mod | awk '{print $2}' || true)
 | 
						|
if [[ -z "${godebug_directive_value}" ]]; then
 | 
						|
  kube::log::error "root go.mod must have 'godebug default=go1.x' directive" >&22 2>&1
 | 
						|
  exit 1
 | 
						|
fi
 | 
						|
 | 
						|
# === Ensure staging go.mod files exist
 | 
						|
for repo in $(kube::util::list_staging_repos); do
 | 
						|
  (
 | 
						|
    cd "staging/src/k8s.io/${repo}"
 | 
						|
 | 
						|
    if [[ ! -f go.mod ]]; then
 | 
						|
      kube::log::status "go.mod: initialize ${repo}" >&11
 | 
						|
      go mod init "k8s.io/${repo}"
 | 
						|
    fi
 | 
						|
    go mod edit -go "${go_directive_value}" -godebug "${godebug_directive_value}"
 | 
						|
  )
 | 
						|
done
 | 
						|
 | 
						|
# === Ensure root and staging go.mod files refer to each other using v0.0.0 and local path replaces
 | 
						|
kube::log::status "go.mod: update staging module references" >&11
 | 
						|
add_staging_replace_directives "./staging/src/k8s.io"
 | 
						|
for repo in $(kube::util::list_staging_repos); do
 | 
						|
  (
 | 
						|
    cd "staging/src/k8s.io/${repo}"
 | 
						|
    add_staging_replace_directives ".."
 | 
						|
  )
 | 
						|
done
 | 
						|
 | 
						|
# === Ensure all root and staging modules are included in go.work
 | 
						|
kube::log::status "go.mod: go work use" >&11
 | 
						|
(
 | 
						|
  cd "${KUBE_ROOT}"
 | 
						|
  unset GOWORK
 | 
						|
  unset GOFLAGS
 | 
						|
  if [[ ! -f go.work ]]; then
 | 
						|
    kube::log::status "go.work: initialize" >&11
 | 
						|
    go work init
 | 
						|
  fi
 | 
						|
  # Prune use directives
 | 
						|
  go work edit -json \
 | 
						|
      | jq -r '.Use[]? | "-dropuse \(.DiskPath)"' \
 | 
						|
      | xargs -L 100 go work edit -fmt
 | 
						|
  # Ensure go and godebug directives
 | 
						|
  go work edit -go "${go_directive_value}" -godebug "${godebug_directive_value}"
 | 
						|
  # Re-add use directives
 | 
						|
  go work use .
 | 
						|
  for repo in $(kube::util::list_staging_repos); do
 | 
						|
    go work use "./staging/src/k8s.io/${repo}"
 | 
						|
  done
 | 
						|
)
 | 
						|
 | 
						|
# === Propagate MVS across all root / staging modules (calculated by `go work`) back into root / staging modules
 | 
						|
kube::log::status "go.mod: go work sync" >&11
 | 
						|
(
 | 
						|
  cd "${KUBE_ROOT}"
 | 
						|
  unset GOWORK
 | 
						|
  unset GOFLAGS
 | 
						|
  go work sync
 | 
						|
)
 | 
						|
 | 
						|
# === Tidy
 | 
						|
kube::log::status "go.mod: tidy" >&11
 | 
						|
for repo in $(kube::util::list_staging_repos); do
 | 
						|
  (
 | 
						|
    echo "=== tidying k8s.io/${repo}"
 | 
						|
    cd "staging/src/k8s.io/${repo}"
 | 
						|
    go mod tidy -v
 | 
						|
    group_directives
 | 
						|
  )
 | 
						|
done
 | 
						|
echo "=== tidying root"
 | 
						|
go mod tidy -v
 | 
						|
group_directives
 | 
						|
 | 
						|
# === Prune unused replace directives, format modules
 | 
						|
kube::log::status "go.mod: prune" >&11
 | 
						|
for repo in $(kube::util::list_staging_repos); do
 | 
						|
  (
 | 
						|
    echo "=== pruning k8s.io/${repo}"
 | 
						|
    cd "staging/src/k8s.io/${repo}"
 | 
						|
 | 
						|
    # drop all unused replace directives
 | 
						|
    comm -23 \
 | 
						|
      <(go mod edit -json | jq -r '.Replace[] | .Old.Path' | sort) \
 | 
						|
      <(go list -m -json all | jq -r 'select(.Main | not) | .Path' | sort) |
 | 
						|
    while read -r X; do echo "-dropreplace=${X}"; done |
 | 
						|
    xargs -L 100 go mod edit -fmt
 | 
						|
 | 
						|
    group_directives
 | 
						|
  )
 | 
						|
done
 | 
						|
 | 
						|
echo "=== pruning root"
 | 
						|
# drop unused replace directives other than to local paths
 | 
						|
comm -23 \
 | 
						|
  <(go mod edit -json | jq -r '.Replace[] | select(.New.Path | startswith("./") | not) | .Old.Path' | sort) \
 | 
						|
  <(go list -m -json all | jq -r 'select(.Main | not) | .Path' | sort) |
 | 
						|
while read -r X; do echo "-dropreplace=${X}"; done |
 | 
						|
xargs -L 100 go mod edit -fmt
 | 
						|
 | 
						|
group_directives
 | 
						|
 | 
						|
# === Add generated comments to go.mod files
 | 
						|
kube::log::status "go.mod: adding generated comments" >&11
 | 
						|
add_generated_comments "
 | 
						|
// This is a generated file. Do not edit directly.
 | 
						|
// Ensure you've carefully read
 | 
						|
// https://git.k8s.io/community/contributors/devel/sig-architecture/vendor.md
 | 
						|
// Run hack/pin-dependency.sh to change pinned dependency versions.
 | 
						|
// Run hack/update-vendor.sh to update go.mod files and the vendor directory.
 | 
						|
"
 | 
						|
for repo in $(kube::util::list_staging_repos); do
 | 
						|
  (
 | 
						|
    cd "staging/src/k8s.io/${repo}"
 | 
						|
    add_generated_comments "// This is a generated file. Do not edit directly."
 | 
						|
  )
 | 
						|
done
 | 
						|
 | 
						|
# === Update internal modules
 | 
						|
kube::log::status "vendor: updating internal modules" >&11
 | 
						|
hack/update-internal-modules.sh
 | 
						|
 | 
						|
 | 
						|
# === Rebuild vendor directory
 | 
						|
(
 | 
						|
  kube::log::status "vendor: running 'go work vendor'" >&11
 | 
						|
  unset GOWORK
 | 
						|
  unset GOFLAGS
 | 
						|
  # rebuild go.work.sum
 | 
						|
  rm -f go.work.sum
 | 
						|
  go mod download
 | 
						|
  # rebuild vendor
 | 
						|
  go work vendor
 | 
						|
)
 | 
						|
 | 
						|
kube::log::status "vendor: updating vendor/LICENSES" >&11
 | 
						|
hack/update-vendor-licenses.sh
 | 
						|
 | 
						|
kube::log::status "vendor: creating OWNERS file" >&11
 | 
						|
rm -f "vendor/OWNERS"
 | 
						|
cat <<__EOF__ > "vendor/OWNERS"
 | 
						|
# See the OWNERS docs at https://go.k8s.io/owners
 | 
						|
 | 
						|
options:
 | 
						|
  # make root approval non-recursive
 | 
						|
  no_parent_owners: true
 | 
						|
approvers:
 | 
						|
- dep-approvers
 | 
						|
reviewers:
 | 
						|
- dep-reviewers
 | 
						|
__EOF__
 | 
						|
 | 
						|
# === Disallow transitive dependencies on k8s.io/kubernetes
 | 
						|
kube::log::status "go.mod: prevent staging --> k8s.io/kubernetes dep" >&11
 | 
						|
for repo in $(kube::util::list_staging_repos); do
 | 
						|
  (
 | 
						|
    echo "=== checking k8s.io/${repo}"
 | 
						|
    cd "staging/src/k8s.io/${repo}"
 | 
						|
    loopback_deps=()
 | 
						|
    kube::util::read-array loopback_deps < <(go list all 2>/dev/null | grep k8s.io/kubernetes/ || true)
 | 
						|
    if (( "${#loopback_deps[@]}" > 0 )); then
 | 
						|
      kube::log::error "${#loopback_deps[@]} disallowed ${repo} -> k8s.io/kubernetes dependencies exist via the following imports: $(go mod why "${loopback_deps[@]}")" >&22 2>&1
 | 
						|
      exit 1
 | 
						|
    fi
 | 
						|
  )
 | 
						|
done
 | 
						|
 | 
						|
kube::log::status "go.mod: prevent k8s.io/kubernetes --> * --> k8s.io/kubernetes dep" >&11
 | 
						|
loopback_deps=()
 | 
						|
kube::util::read-array loopback_deps < <(go mod graph | grep ' k8s.io/kubernetes' || true)
 | 
						|
if (( "${#loopback_deps[@]}" > 0 )); then
 | 
						|
  kube::log::error "${#loopback_deps[@]} disallowed transitive k8s.io/kubernetes dependencies exist via the following imports:" >&22 2>&1
 | 
						|
  kube::log::error "${loopback_deps[@]}" >&22 2>&1
 | 
						|
  exit 1
 | 
						|
fi
 | 
						|
 | 
						|
kube::log::status "NOTE: don't forget to handle vendor/* and LICENSE/* files that were added or removed" >&11
 |