Luca Prete | 1b823d6 | 2018-12-13 17:33:47 -0800 | [diff] [blame] | 1 | #!/usr/bin/env bash |
| 2 | |
Joey Armstrong | aebf185 | 2022-12-09 08:34:13 -0500 | [diff] [blame] | 3 | # Copyright 2018-2023 Open Networking Foundation (ONF) and the ONF Contributors |
Luca Prete | 1b823d6 | 2018-12-13 17:33:47 -0800 | [diff] [blame] | 4 | # |
| 5 | # Licensed under the Apache License, Version 2.0 (the "License"); |
| 6 | # you may not use this file except in compliance with the License. |
| 7 | # You may obtain a copy of the License at |
| 8 | # |
| 9 | # http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | # |
| 11 | # Unless required by applicable law or agreed to in writing, software |
| 12 | # distributed under the License is distributed on an "AS IS" BASIS, |
| 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 14 | # See the License for the specific language governing permissions and |
| 15 | # limitations under the License. |
| 16 | |
| 17 | # helmrepo.sh |
Zack Williams | 48542de | 2018-12-19 17:26:41 -0700 | [diff] [blame] | 18 | # creates or updates a helm repo for publishing on the guide website |
| 19 | # Reference: https://github.com/helm/charts/blob/master/test/repo-sync.sh |
Luca Prete | 1b823d6 | 2018-12-13 17:33:47 -0800 | [diff] [blame] | 20 | |
| 21 | set -eu -o pipefail |
| 22 | |
Joey Armstrong | e9b327e | 2023-06-22 17:09:52 -0400 | [diff] [blame^] | 23 | ##-------------------## |
| 24 | ##---] GLOBALS [---## |
| 25 | ##-------------------## |
Zack Williams | 48542de | 2018-12-19 17:26:41 -0700 | [diff] [blame] | 26 | |
Luca Prete | 1b823d6 | 2018-12-13 17:33:47 -0800 | [diff] [blame] | 27 | # when not running under Jenkins, use current dir as workspace |
| 28 | WORKSPACE=${WORKSPACE:-.} |
| 29 | |
Zack Williams | 48542de | 2018-12-19 17:26:41 -0700 | [diff] [blame] | 30 | # directory to compare against, doesn't need to be present |
| 31 | OLD_REPO_DIR="${OLD_REPO_DIR:-cord-charts-repo}" |
| 32 | NEW_REPO_DIR="${NEW_REPO_DIR:-chart_repo}" |
Luca Prete | 1b823d6 | 2018-12-13 17:33:47 -0800 | [diff] [blame] | 33 | |
Luca Prete | 138c776 | 2018-12-14 14:16:14 -0800 | [diff] [blame] | 34 | PUBLISH_URL="${PUBLISH_URL:-charts.opencord.org}" |
Luca Prete | 1b823d6 | 2018-12-13 17:33:47 -0800 | [diff] [blame] | 35 | |
Joey Armstrong | e9b327e | 2023-06-22 17:09:52 -0400 | [diff] [blame^] | 36 | ## ----------------------------------------------------------------------- |
| 37 | ## Intent: Dispay called function with given output |
| 38 | ## ----------------------------------------------------------------------- |
| 39 | function func_echo() |
| 40 | { |
| 41 | echo "** ${FUNCNAME[1]}: $*" |
| 42 | return |
| 43 | } |
| 44 | |
| 45 | ## ----------------------------------------------------------------------- |
| 46 | ## Intent: Display given text and exit with shell error status. |
| 47 | ## ----------------------------------------------------------------------- |
| 48 | function error() |
| 49 | { |
| 50 | echo "** ${BASH_SOURCE[0]}::${FUNCNAME[1]} ERROR: $*" |
| 51 | exit 1 |
| 52 | } |
| 53 | |
| 54 | ## ----------------------------------------------------------------------- |
| 55 | ## Intent: Gather a list of Chart.yaml files from the filesystem. |
| 56 | ## ----------------------------------------------------------------------- |
| 57 | function get_chart_yaml() |
| 58 | { |
| 59 | local dir="$1" ; shift |
| 60 | declare -n ref=$1 ; shift |
| 61 | |
| 62 | readarray -t _charts < <(find "$dir" -name Chart.yaml -print | sort) |
| 63 | ref=("${_charts[@]}") |
| 64 | return |
| 65 | } |
| 66 | |
| 67 | ## ----------------------------------------------------------------------- |
| 68 | ## Intent: Update helm package dependencies |
| 69 | ## ----------------------------------------------------------------------- |
| 70 | function helm_deps_update() |
| 71 | { |
| 72 | local dest="$1"; shift # helm --destination |
| 73 | |
| 74 | if [[ -v dry_run ]]; then |
| 75 | func_echo "helm package --dependency-update --destination $dest $chartdir" |
| 76 | else |
| 77 | helm package --dependency-update --destination "$dest" "$chartdir" |
| 78 | fi |
| 79 | return |
| 80 | } |
| 81 | |
| 82 | ## ----------------------------------------------------------------------- |
| 83 | ## Intent: Update helm package index |
| 84 | ## ----------------------------------------------------------------------- |
| 85 | function helm_index_publish() |
| 86 | { |
| 87 | local repo_dir="$1"; shift # helm --destination |
| 88 | |
| 89 | if [[ -v dry_run ]]; then |
| 90 | func_echo "helm repo index $repo_dir --url https://${PUBLISH_URL}" |
| 91 | else |
| 92 | helm repo index "$repo_dir" --url https://"${PUBLISH_URL}" |
| 93 | fi |
| 94 | return |
| 95 | } |
| 96 | |
| 97 | ## ----------------------------------------------------------------------- |
| 98 | ## Intent: Update helm package index |
| 99 | ## ----------------------------------------------------------------------- |
| 100 | function helm_index_merge() |
| 101 | { |
| 102 | local old_repo="$1" ; shift |
| 103 | local new_repo="$1" ; shift |
| 104 | |
| 105 | declare -a cmd=() |
| 106 | cmd+=('helm' 'repo' 'index') |
| 107 | cmd+=('--url' "https://${PUBLISH_URL}") |
| 108 | cmd+=('--merge' "${old_repo}/index.yaml" "$new_repo") |
| 109 | |
| 110 | if [[ -v dry_run ]]; then |
| 111 | func_echo "${cmd[@]}" |
| 112 | else |
| 113 | "${cmd[@]}" |
| 114 | fi |
| 115 | return |
| 116 | } |
| 117 | |
| 118 | ## ----------------------------------------------------------------------- |
| 119 | ## Intent: Given a Chart.yaml file path return test directory where stored |
| 120 | ## ----------------------------------------------------------------------- |
| 121 | function chart_path_to_test_dir() |
| 122 | { |
| 123 | local val="$1" ; shift |
| 124 | |
| 125 | # shellcheck disable=SC2178 |
| 126 | declare -n ref=$1 ; shift # indirect var |
| 127 | |
| 128 | val="${val%/Chart.yaml}" # dirname: prune /Chart.yaml |
| 129 | val="${val##*/}" # basename: test directory |
| 130 | |
| 131 | # shellcheck disable=SC2034,SC2178 |
| 132 | ref="$val" # Return value to caller |
| 133 | return |
| 134 | } |
| 135 | |
| 136 | ## ----------------------------------------------------------------------- |
| 137 | ## Intent: Given a Chart.yaml file path return test directory where stored |
| 138 | ## ----------------------------------------------------------------------- |
| 139 | function create_helm_repo_new() |
| 140 | { |
| 141 | local repo_dir="$1"; shift # NEW_REPO_DIR |
| 142 | local work_dir="$1"; shift # WORKSPACE |
| 143 | |
| 144 | echo "Creating new helm repo: ${repo_dir}" |
| 145 | |
| 146 | declare -a charts=() |
| 147 | get_chart_yaml "$work_dir" charts |
| 148 | |
| 149 | local chart |
| 150 | for chart in "${charts[@]}"; |
| 151 | do |
| 152 | echo |
| 153 | func_echo "Chart.yaml: $chart" |
| 154 | |
| 155 | chartdir='' |
| 156 | chart_path_to_test_dir "$chart" chartdir |
| 157 | func_echo " Chart.dir: $chartdir" |
| 158 | |
| 159 | helm_deps_update "${repo_dir}" |
| 160 | done |
| 161 | |
| 162 | helm_index_publish "${repo_dir}" |
| 163 | return |
| 164 | } |
| 165 | |
| 166 | ##----------------## |
| 167 | ##---] MAIN [---## |
| 168 | ##----------------## |
| 169 | |
| 170 | while [ $# -gt 0 ]; do |
| 171 | arg="$1"; shift |
| 172 | |
| 173 | case "$arg" in |
| 174 | -*debug) declare -g -i debug=1 ;; |
| 175 | -*dry*) declare -g -i dry_run=1 ;; |
| 176 | -*help) |
| 177 | cat <<EOH |
| 178 | Usage: $0 |
| 179 | --debug Enable debug mode |
| 180 | --dry-run Simulate helm calls |
| 181 | EOH |
| 182 | ;; |
| 183 | |
| 184 | -*) echo "[SKIP] unknown switch [$arg]" ;; |
| 185 | *) echo "[SKIP] unknown argument [$arg]" ;; |
| 186 | esac |
| 187 | done |
| 188 | |
| 189 | |
| 190 | echo "# helmrepo.sh, using helm: $(helm version -c) #" |
| 191 | |
Zack Williams | 48542de | 2018-12-19 17:26:41 -0700 | [diff] [blame] | 192 | # create and clean NEW_REPO_DIR |
| 193 | mkdir -p "${NEW_REPO_DIR}" |
| 194 | rm -f "${NEW_REPO_DIR}"/* |
Luca Prete | 94d9519 | 2018-12-14 09:56:00 -0800 | [diff] [blame] | 195 | |
Zack Williams | 48542de | 2018-12-19 17:26:41 -0700 | [diff] [blame] | 196 | # if OLD_REPO_DIR doesn't exist, generate packages and index in NEW_REPO_DIR |
| 197 | if [ ! -d "${OLD_REPO_DIR}" ] |
| 198 | then |
Joey Armstrong | e9b327e | 2023-06-22 17:09:52 -0400 | [diff] [blame^] | 199 | create_helm_repo_new "$NEW_REPO_DIR" "$WORKSPACE" |
| 200 | echo |
| 201 | echo "# helmrepo.sh Success! Generated new repo index in ${NEW_REPO_DIR}" |
Luca Prete | 1b823d6 | 2018-12-13 17:33:47 -0800 | [diff] [blame] | 202 | |
Zack Williams | 48542de | 2018-12-19 17:26:41 -0700 | [diff] [blame] | 203 | else |
| 204 | # OLD_REPO_DIR exists, check for new charts and update only with changes |
| 205 | echo "Found existing helm repo: ${OLD_REPO_DIR}, attempting update" |
Luca Prete | 1b823d6 | 2018-12-13 17:33:47 -0800 | [diff] [blame] | 206 | |
Zack Williams | 48542de | 2018-12-19 17:26:41 -0700 | [diff] [blame] | 207 | # Loop and create chart packages, only if changed |
Joey Armstrong | e9b327e | 2023-06-22 17:09:52 -0400 | [diff] [blame^] | 208 | declare -a charts=() |
| 209 | get_chart_yaml "$WORKSPACE" charts |
| 210 | |
| 211 | for chart in "${charts[@]}"; |
Zack Williams | 48542de | 2018-12-19 17:26:41 -0700 | [diff] [blame] | 212 | do |
Joey Armstrong | e9b327e | 2023-06-22 17:09:52 -0400 | [diff] [blame^] | 213 | echo |
| 214 | func_echo "Chart.yaml: $chart" |
Luca Prete | 1b823d6 | 2018-12-13 17:33:47 -0800 | [diff] [blame] | 215 | |
Joey Armstrong | e9b327e | 2023-06-22 17:09:52 -0400 | [diff] [blame^] | 216 | chartdir='' |
| 217 | chart_path_to_test_dir "$chart" chartdir |
| 218 | func_echo " Chart.dir: $chartdir" |
Luca Prete | 05ba35b | 2018-12-14 11:08:12 -0800 | [diff] [blame] | 219 | |
Joey Armstrong | e9b327e | 2023-06-22 17:09:52 -0400 | [diff] [blame^] | 220 | # See if chart version changed from previous HEAD commit |
| 221 | readarray -t chart_yaml_diff < <(git diff -p HEAD^ -- "$chart") |
| 222 | |
| 223 | if [[ ! -v chart_yaml_diff ]]; then |
| 224 | echo "Chart unchanged, not packaging: '${chartdir}'" |
Luca Prete | 1b823d6 | 2018-12-13 17:33:47 -0800 | [diff] [blame] | 225 | |
Joey Armstrong | e9b327e | 2023-06-22 17:09:52 -0400 | [diff] [blame^] | 226 | elif [ ${#chart_yaml_diff} -gt 0 ]; then |
| 227 | # assumes that helmlint.sh and chart_version_check.sh have been run |
| 228 | # pre-merge, which ensures that all charts are valid and have their |
| 229 | # version updated in Chart.yaml |
Luca Prete | 1b823d6 | 2018-12-13 17:33:47 -0800 | [diff] [blame] | 230 | |
Joey Armstrong | e9b327e | 2023-06-22 17:09:52 -0400 | [diff] [blame^] | 231 | [[ -v new_version_string ]] && unset new_version_string |
| 232 | |
| 233 | for line in "${chart_yaml_diff[@]}"; |
| 234 | do |
| 235 | [[ -v debug ]] && func_echo "$line" |
| 236 | |
| 237 | case "$line" in |
| 238 | # "-version: \"1.0.3\"" |
| 239 | -version:*) |
| 240 | [[ ! -v debug ]] && func_echo "$line" |
| 241 | ;; |
| 242 | |
| 243 | # "+version: \"1.0.4\"" |
| 244 | +version:*) |
| 245 | [[ ! -v debug ]] && func_echo "$line" |
| 246 | |
| 247 | readarray -d':' -t _fields <<<"$line" # split on delimiter |
| 248 | val="${_fields[1]}" |
| 249 | val="${val//[[:blank:]]}" |
| 250 | |
| 251 | # error detection: only assign when we have a value. |
| 252 | [ ${#val} -gt 0 ] && new_version_string="$val" |
| 253 | break |
| 254 | ;; |
| 255 | esac |
| 256 | done |
| 257 | |
| 258 | [[ ! -v new_version_string ]] && error "Failed to detect version: in $chart" |
| 259 | |
| 260 | echo "New version of chart ${chartdir}, creating package: ${new_version_string}" |
| 261 | |
| 262 | helm_deps_update "1${NEW_REPO_DIR}" |
| 263 | |
| 264 | else |
| 265 | echo "Chart unchanged, not packaging: '${chartdir}'" |
| 266 | fi |
| 267 | done |
| 268 | |
| 269 | ## ----------------------------------------------------------------------- |
| 270 | ## ----------------------------------------------------------------------- |
| 271 | readarray -t package_paths < <(find "${NEW_REPO_DIR}" -name '*.tgz' -print) |
| 272 | declare -p package_paths |
| 273 | |
Zack Williams | 48542de | 2018-12-19 17:26:41 -0700 | [diff] [blame] | 274 | # Check for collisions between old/new packages |
Joey Armstrong | e9b327e | 2023-06-22 17:09:52 -0400 | [diff] [blame^] | 275 | # while IFS= read -r -d '' package_path |
| 276 | for package_path in "${package_paths[@]}"; |
Zack Williams | 48542de | 2018-12-19 17:26:41 -0700 | [diff] [blame] | 277 | do |
Joey Armstrong | e9b327e | 2023-06-22 17:09:52 -0400 | [diff] [blame^] | 278 | package="${package_path##*/}" # basename |
Zack Williams | 48542de | 2018-12-19 17:26:41 -0700 | [diff] [blame] | 279 | |
Joey Armstrong | e9b327e | 2023-06-22 17:09:52 -0400 | [diff] [blame^] | 280 | [ -f "${OLD_REPO_DIR}/${package}" ] \ |
| 281 | && error "Package: ${package} with same version already exists in ${OLD_REPO_DIR}" |
| 282 | done |
| 283 | |
| 284 | ## ----------------------------------------------------------------------- |
| 285 | ## ----------------------------------------------------------------------- |
| 286 | # only update index when new charts are added |
| 287 | if [ ${#package_paths[@]} -gt 0 ]; then |
Zack Williams | 48542de | 2018-12-19 17:26:41 -0700 | [diff] [blame] | 288 | |
Joey Armstrong | e9b327e | 2023-06-22 17:09:52 -0400 | [diff] [blame^] | 289 | # Create updated index.yaml (new version created in NEW_REPO_DIR) |
| 290 | helm_index_merge "${OLD_REPO_DIR}" "${NEW_REPO_DIR}" |
Zack Williams | 48542de | 2018-12-19 17:26:41 -0700 | [diff] [blame] | 291 | |
Joey Armstrong | e9b327e | 2023-06-22 17:09:52 -0400 | [diff] [blame^] | 292 | # move over packages and index.yaml |
| 293 | mv "${NEW_REPO_DIR}"/*.tgz "${OLD_REPO_DIR}/" |
| 294 | mv "${NEW_REPO_DIR}/index.yaml" "${OLD_REPO_DIR}/index.yaml" |
Zack Williams | 48542de | 2018-12-19 17:26:41 -0700 | [diff] [blame] | 295 | |
Joey Armstrong | e9b327e | 2023-06-22 17:09:52 -0400 | [diff] [blame^] | 296 | echo "# helmrepo.sh Success! Updated existing repo index in ${OLD_REPO_DIR}" |
Zack Williams | 2f075ea | 2019-01-03 14:20:29 -0700 | [diff] [blame] | 297 | |
| 298 | else |
| 299 | echo "# helmrepo.sh Success! No new charts added." |
| 300 | fi |
Zack Williams | 48542de | 2018-12-19 17:26:41 -0700 | [diff] [blame] | 301 | fi |
| 302 | |
| 303 | exit 0 |