github.com/cilium/cilium@v1.16.2/Documentation/check-crd-compat-table.sh (about)

     1  #!/usr/bin/env bash
     2  
     3  dir=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
     4  dst_file="${PWD}/$(basename ${dir})/network/kubernetes/compatibility-table.rst"
     5  # Cilium 1.12 and earlier had a different path for the compatibility table.
     6  if [ ! -e "$dst_file" ]; then
     7     dst_file="${PWD}/$(basename ${dir})/concepts/kubernetes/compatibility-table.rst"
     8  fi
     9  
    10  . "${dir}/../contrib/backporting/common.sh"
    11  remote="$(get_remote "${ORG:-}" "${REPO:-}")"
    12  
    13  set -e
    14  set -o nounset
    15  set -o pipefail
    16  
    17  # Ensure sort order doesn't depend on locale
    18  export LANG=C
    19  export LC_ALL=C
    20  
    21  get_schema_of_tag(){
    22     tag="${1}"
    23     set +o pipefail
    24     git grep -o 'CustomResourceDefinitionSchemaVersion =.*' ${tag} -- pkg/k8s | head -n1 | sed 's/.*=\ "//;s/"//'
    25     set -o pipefail
    26  }
    27  
    28  get_line_of_schema_version(){
    29     tag="${1}"
    30     git grep -H 'CustomResourceDefinitionSchemaVersion =.*' ${remote}/${tag} -- pkg/k8s | sed "s+${remote}/${tag}:++;s+.go:.*+.go+;s+^+${PWD}/+"
    31  }
    32  
    33  get_schema_of_branch(){
    34     stable_branch="${1}"
    35     set +o pipefail
    36     git grep -o 'CustomResourceDefinitionSchemaVersion =.*' ${remote}/${stable_branch} -- pkg/k8s | sed 's/.*=\ "//;s/"//' | uniq  | head -n1
    37     set -o pipefail
    38  }
    39  
    40  get_stable_branches(){
    41     git grep -o -E 'tree\/v[^>]+' -- README.rst | sed 's+.*tree/++' | sort -V
    42  }
    43  
    44  get_stable_tags_for_minor(){
    45     minor_ver="${1}"
    46     git ls-remote --refs --tags ${remote} v\* \
    47         | awk '{ print $2 }' \
    48         | grep "${minor_ver}" \
    49         | grep -v '\-' \
    50         | sed 's+refs/tags/++' \
    51         | sort -V \
    52     || echo ""
    53  }
    54  
    55  get_rc_tags_for_minor(){
    56     minor_ver="${1}"
    57     git ls-remote --refs --tags ${remote} v\* \
    58         | awk '{ print $2 }' \
    59         | grep "${minor_ver}.*\-" \
    60         | sed 's+refs/tags/++' \
    61         | sort -V
    62  }
    63  
    64  upstream_branches() {
    65     git ls-remote --refs ${remote} ${@} \
    66         | awk '{ print $2 }' \
    67         | sed 's+refs/heads/++'
    68  }
    69  
    70  branch_or_main() {
    71     echo "$(upstream_branches ${1}) main" \
    72         | awk '{ print $1 }'
    73  }
    74  
    75  filter_out_oldest() {
    76      echo "${@}" | cut -d' ' -f2- -
    77  }
    78  
    79  target_version() {
    80      stable_branch="${1}"
    81      target_branch="${2}"
    82      if [[ "$stable_branch" == "${target_branch}" ]]; then
    83          echo $stable_branch
    84      else
    85          echo "v$(cat VERSION)"
    86      fi
    87  }
    88  
    89  create_file(){
    90    release_version="${1}"
    91    dst_file="${2}"
    92    git fetch --tags
    93    echo   "+--------------------+----------------+" > "${dst_file}"
    94    echo   "| Cilium             | CNP and CCNP   |" >> "${dst_file}"
    95    echo   "| Version            | Schema Version |" >> "${dst_file}"
    96    echo   "+--------------------+----------------+" >> "${dst_file}"
    97    stable_branches=$(get_stable_branches)
    98    if [[ ${stable_branches} != *"${release_version}"* ]]; then
    99        stable_branches="$(filter_out_oldest ${stable_branches} ${release_version})"
   100    fi
   101    for stable_branch in ${stable_branches}; do
   102        >&2 echo -n "Checking stable branch ${stable_branch} schema version... "
   103        rc_tags=$(get_rc_tags_for_minor "${stable_branch}")
   104        stable_tags=$(get_stable_tags_for_minor "${stable_branch}")
   105        for tag in ${rc_tags} ${stable_tags}; do
   106            schema_version=$(get_schema_of_tag "${tag}")
   107            printf "| %-18s | %-14s |\n" ${tag} ${schema_version} >> "${dst_file}"
   108            echo   "+--------------------+----------------+" >> "${dst_file}"
   109        done
   110        branch=$(branch_or_main "${stable_branch}")
   111        branch_version=$(target_version "${stable_branch}" "${branch}")
   112        schema_version=$(get_schema_of_branch "${branch}")
   113        >&2 echo "${schema_version}"
   114        printf "| %-18s | %-14s |\n" ${branch_version} ${schema_version} >> "${dst_file}"
   115        echo   "+--------------------+----------------+" >> "${dst_file}"
   116    done
   117  
   118    schema_version=$(get_schema_of_branch "main")
   119    >&2 echo "Checking latest branch schema version... ${schema_version}"
   120    printf "| %-18s | %-14s |\n" "latest / main" ${schema_version} >> "${dst_file}"
   121    echo   "+--------------------+----------------+" >> "${dst_file}"
   122  }
   123  
   124  # From https://github.com/cloudflare/semver_bash/blob/master/semver.sh
   125  semverParseInto() {
   126      local RE='[^0-9]*\([0-9]*\)[.]\([0-9]*\)[.]\([0-9]*\)\([0-9A-Za-z-]*\)'
   127      #MAJOR
   128      eval $2=`echo $1 | sed -e "s#$RE#\1#"`
   129      #MINOR
   130      eval $3=`echo $1 | sed -e "s#$RE#\2#"`
   131      #MINOR
   132      eval $4=`echo $1 | sed -e "s#$RE#\3#"`
   133      #SPECIAL
   134      eval $5=`echo $1 | sed -e "s#$RE#\4#"`
   135  }
   136  
   137  # From https://github.com/cloudflare/semver_bash/blob/master/semver.sh
   138  semverEQ() {
   139      local MAJOR_A=0
   140      local MINOR_A=0
   141      local PATCH_A=0
   142      local SPECIAL_A=0
   143  
   144      local MAJOR_B=0
   145      local MINOR_B=0
   146      local PATCH_B=0
   147      local SPECIAL_B=0
   148  
   149      semverParseInto $1 MAJOR_A MINOR_A PATCH_A SPECIAL_A
   150      semverParseInto $2 MAJOR_B MINOR_B PATCH_B SPECIAL_B
   151  
   152      if [ $MAJOR_A -ne $MAJOR_B ]; then
   153          return 4
   154      fi
   155  
   156      if [ $MINOR_A -ne $MINOR_B ]; then
   157          return 3
   158      fi
   159  
   160      if [ $PATCH_A -ne $PATCH_B ]; then
   161          return 2
   162      fi
   163  
   164      if [[ "_$SPECIAL_A" != "_$SPECIAL_B" ]]; then
   165          return 1
   166      fi
   167  
   168  
   169      return 0
   170  }
   171  
   172  if [[ "$#" -lt 1 ]] || [[ "$#" -gt 2 ]]; then
   173    echo "Usage: $0 <v1.X> [--update]"
   174    exit 1
   175  fi
   176  
   177  release_ersion="$(echo $1 | sed 's/^v//')"
   178  release_version="v$release_ersion"
   179  release_branch="$(branch_or_main $release_version)"
   180  
   181  create_file ${release_version} "${dst_file}" "${release_branch}"
   182  
   183  # Offset of 2 lines above the release version will point to the previous schema
   184  # version, for example:
   185  # | v1.12.2         | 1.25.6         |
   186  # +-----------------+----------------+
   187  # | v1.12           | 1.25.6         |
   188  row_offset=2 # Gather 2 lines prior to the release branch
   189  if ! egrep "[ ]${release_version}[ ]" "${dst_file}"; then
   190    # Unreleased RC with no upstream branch needs to go back 4 lines from 'main'
   191    row_offset=4
   192  fi
   193  last_cilium_release=$(egrep "[ ]${release_branch}[ ]" -B${row_offset} "${dst_file}" | awk 'NR == 1 { print $2 }')
   194  last_release_version=$(egrep "[ ]${release_branch}[ ]" -B${row_offset} "${dst_file}" | awk 'NR == 1 { print $4 }')
   195  current_release_version=$(egrep "[ ]${release_branch}[ ]" -B$(( ${row_offset} - 2)) "${dst_file}" | awk 'NR == 1 { print $4 }')
   196  >&2 echo "Cilium ${last_cilium_release} schema: ${last_release_version}; Current: ${current_release_version}"
   197  
   198  # Cilium v1.9 or earlier used examples/crds, this dir was moved in v1.10.
   199  crd_path="$(realpath --relative-to . "examples/crds")"
   200  
   201  if ! git diff --quiet ${last_cilium_release}..${remote}/${release_branch} $crd_path \
   202      && semverEQ "${current_release_version}" "${last_release_version}"; then
   203    semverParseInto ${last_release_version} last_major last_minor last_patch ignore
   204    expected_version="${last_major}.${last_minor}.$(( ${last_patch} + 1 ))"
   205    if [[ "$#" -gt 1 ]] && [[ "$2" == "--update" ]]; then
   206      >&2 echo "Current version for branch ${release_branch} should be ${expected_version}, not ${current_release_version}, updating in-place."
   207      sed -i "s+${current_release_version}+${expected_version}+" $(get_line_of_schema_version ${release_branch} | tr '\n' ' ')
   208      create_file ${release_version} "${dst_file}" "${release_branch}"
   209    elif [[ "${current_release_version}" != "${expected_version}" ]]; then
   210      >&2 echo "Current version for branch ${release_branch} should be ${expected_version}, not ${current_release_version}, please run the following command to fix it:"
   211      >&2 echo "git checkout ${remote}/${release_branch} && \\"
   212      >&2 echo "sed -i 's+${current_release_version}+${expected_version}+' $(get_line_of_schema_version ${release_branch} | tr '\n' ' ')"
   213      exit 1
   214    fi
   215  fi
   216  
   217  exit 0