blob: 230ae1fbae6e39560bcdb79512d997e039f568b7 [file] [log] [blame]
Luca Prete1b823d62018-12-13 17:33:47 -08001#!/usr/bin/env bash
2
Joey Armstrongaebf1852022-12-09 08:34:13 -05003# Copyright 2018-2023 Open Networking Foundation (ONF) and the ONF Contributors
Luca Prete1b823d62018-12-13 17:33:47 -08004#
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 Williams48542de2018-12-19 17:26:41 -070018# 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 Prete1b823d62018-12-13 17:33:47 -080020
21set -eu -o pipefail
22
Joey Armstronge9b327e2023-06-22 17:09:52 -040023##-------------------##
24##---] GLOBALS [---##
25##-------------------##
Zack Williams48542de2018-12-19 17:26:41 -070026
Luca Prete1b823d62018-12-13 17:33:47 -080027# when not running under Jenkins, use current dir as workspace
28WORKSPACE=${WORKSPACE:-.}
29
Zack Williams48542de2018-12-19 17:26:41 -070030# directory to compare against, doesn't need to be present
31OLD_REPO_DIR="${OLD_REPO_DIR:-cord-charts-repo}"
32NEW_REPO_DIR="${NEW_REPO_DIR:-chart_repo}"
Luca Prete1b823d62018-12-13 17:33:47 -080033
Luca Prete138c7762018-12-14 14:16:14 -080034PUBLISH_URL="${PUBLISH_URL:-charts.opencord.org}"
Luca Prete1b823d62018-12-13 17:33:47 -080035
Joey Armstronge9b327e2023-06-22 17:09:52 -040036## -----------------------------------------------------------------------
37## Intent: Dispay called function with given output
38## -----------------------------------------------------------------------
39function func_echo()
40{
41 echo "** ${FUNCNAME[1]}: $*"
42 return
43}
44
45## -----------------------------------------------------------------------
46## Intent: Display given text and exit with shell error status.
47## -----------------------------------------------------------------------
48function 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## -----------------------------------------------------------------------
57function 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## -----------------------------------------------------------------------
70function 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## -----------------------------------------------------------------------
85function 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## -----------------------------------------------------------------------
100function 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## -----------------------------------------------------------------------
121function 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## -----------------------------------------------------------------------
139function 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
170while [ $# -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
178Usage: $0
179 --debug Enable debug mode
180 --dry-run Simulate helm calls
181EOH
182 ;;
183
184 -*) echo "[SKIP] unknown switch [$arg]" ;;
185 *) echo "[SKIP] unknown argument [$arg]" ;;
186 esac
187done
188
189
190echo "# helmrepo.sh, using helm: $(helm version -c) #"
191
Zack Williams48542de2018-12-19 17:26:41 -0700192# create and clean NEW_REPO_DIR
193mkdir -p "${NEW_REPO_DIR}"
194rm -f "${NEW_REPO_DIR}"/*
Luca Prete94d95192018-12-14 09:56:00 -0800195
Zack Williams48542de2018-12-19 17:26:41 -0700196# if OLD_REPO_DIR doesn't exist, generate packages and index in NEW_REPO_DIR
197if [ ! -d "${OLD_REPO_DIR}" ]
198then
Joey Armstronge9b327e2023-06-22 17:09:52 -0400199 create_helm_repo_new "$NEW_REPO_DIR" "$WORKSPACE"
200 echo
201 echo "# helmrepo.sh Success! Generated new repo index in ${NEW_REPO_DIR}"
Luca Prete1b823d62018-12-13 17:33:47 -0800202
Zack Williams48542de2018-12-19 17:26:41 -0700203else
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 Prete1b823d62018-12-13 17:33:47 -0800206
Zack Williams48542de2018-12-19 17:26:41 -0700207 # Loop and create chart packages, only if changed
Joey Armstronge9b327e2023-06-22 17:09:52 -0400208 declare -a charts=()
209 get_chart_yaml "$WORKSPACE" charts
210
211 for chart in "${charts[@]}";
Zack Williams48542de2018-12-19 17:26:41 -0700212 do
Joey Armstronge9b327e2023-06-22 17:09:52 -0400213 echo
214 func_echo "Chart.yaml: $chart"
Luca Prete1b823d62018-12-13 17:33:47 -0800215
Joey Armstronge9b327e2023-06-22 17:09:52 -0400216 chartdir=''
217 chart_path_to_test_dir "$chart" chartdir
218 func_echo " Chart.dir: $chartdir"
Luca Prete05ba35b2018-12-14 11:08:12 -0800219
Joey Armstronge9b327e2023-06-22 17:09:52 -0400220 # 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 Prete1b823d62018-12-13 17:33:47 -0800225
Joey Armstronge9b327e2023-06-22 17:09:52 -0400226 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 Prete1b823d62018-12-13 17:33:47 -0800230
Joey Armstronge9b327e2023-06-22 17:09:52 -0400231 [[ -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 Williams48542de2018-12-19 17:26:41 -0700274 # Check for collisions between old/new packages
Joey Armstronge9b327e2023-06-22 17:09:52 -0400275 # while IFS= read -r -d '' package_path
276 for package_path in "${package_paths[@]}";
Zack Williams48542de2018-12-19 17:26:41 -0700277 do
Joey Armstronge9b327e2023-06-22 17:09:52 -0400278 package="${package_path##*/}" # basename
Zack Williams48542de2018-12-19 17:26:41 -0700279
Joey Armstronge9b327e2023-06-22 17:09:52 -0400280 [ -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 Williams48542de2018-12-19 17:26:41 -0700288
Joey Armstronge9b327e2023-06-22 17:09:52 -0400289 # Create updated index.yaml (new version created in NEW_REPO_DIR)
290 helm_index_merge "${OLD_REPO_DIR}" "${NEW_REPO_DIR}"
Zack Williams48542de2018-12-19 17:26:41 -0700291
Joey Armstronge9b327e2023-06-22 17:09:52 -0400292 # 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 Williams48542de2018-12-19 17:26:41 -0700295
Joey Armstronge9b327e2023-06-22 17:09:52 -0400296 echo "# helmrepo.sh Success! Updated existing repo index in ${OLD_REPO_DIR}"
Zack Williams2f075ea2019-01-03 14:20:29 -0700297
298 else
299 echo "# helmrepo.sh Success! No new charts added."
300 fi
Zack Williams48542de2018-12-19 17:26:41 -0700301fi
302
303exit 0