1
+ #! /bin/bash
2
+ #
3
+ # This script serves to check and validate the `params.env` file that contains
4
+ # definitions of the notebook images that are supposed to be used in the resulting
5
+ # release.
6
+ #
7
+ # It is verified that particular image link exists and is a proper type for the
8
+ # assigned variable name. Structure of the `params.env` file is also checked.
9
+ #
10
+ # THIS FILE DOESN'T CHECK THAT THE USED LINK TO IMAGE IS THE LATEST ONE AVAILABLE!
11
+ #
12
+ # This script uses `skopeo` and `jq` tools installed locally for retrieving
13
+ # information about the particular remote images.
14
+ #
15
+ # Local execution: ./ci/check-params-env.sh
16
+ # Note: please execute from the root directory so that relative path matches
17
+ #
18
+ # In case of the PR on GitHub, this check is tied to GitHub actions automatically,
19
+ # see `.github/workflows` directory.
20
+
21
+ # ----------------------------- GLOBAL VARIABLES ----------------------------- #
22
+
23
+ PARAMS_ENV_PATH=" manifests/base/params.env"
24
+
25
+ # This value needs to be updated everytime we deliberately change number of the
26
+ # images we want to have in the `params.env` file.
27
+ EXPECTED_NUM_RECORDS=24
28
+
29
+ # ---------------------------- DEFINED FUNCTIONS ----------------------------- #
30
+
31
+ function check_variables_uniq() {
32
+ local params_env_path=" ${1} "
33
+ local ret_code=0
34
+
35
+ echo " Checking that all variables in the file '${params_env_path} ' are unique and expected"
36
+
37
+ local content
38
+ content=$( sed ' s#\(.*\)=.*#\1#' " ${params_env_path} " | sort)
39
+
40
+ local num_records
41
+ num_records=$( echo " ${content} " | wc -l)
42
+
43
+ local num_uniq_records
44
+ num_uniq_records=$( echo " ${content} " | uniq | wc -l)
45
+
46
+ test " ${num_records} " -eq " ${num_uniq_records} " || {
47
+ echo " Some of the records in the file aren't unique!"
48
+ ret_code=1
49
+ }
50
+
51
+ test " ${num_records} " -eq " ${EXPECTED_NUM_RECORDS} " || {
52
+ echo " Number of records in the file is incorrect - expected '${EXPECTED_NUM_RECORDS} ' but got '${num_records} '!"
53
+ ret_code=1
54
+ }
55
+
56
+ echo " ---------------------------------------------"
57
+ return " ${ret_code} "
58
+ }
59
+
60
+ function check_image_variable_matches_name_and_commitref() {
61
+ local image_variable=" ${1} "
62
+ local image_name=" ${2} "
63
+ local image_commitref=" ${3} "
64
+ local openshift_build_name=" ${4} "
65
+
66
+ local expected_name
67
+ local expected_commitref
68
+ local expected_build_name # Why some of the images has `-amd64` suffix and others not?
69
+ case " ${image_variable} " in
70
+ odh-minimal-notebook-image-n)
71
+ expected_name=" odh-notebook-jupyter-minimal-ubi9-python-3.9"
72
+ expected_commitref=" 2023b"
73
+ expected_build_name=" jupyter-minimal-ubi9-python-3.9-amd64"
74
+ ;;
75
+ odh-minimal-notebook-image-n-1)
76
+ expected_name=" odh-notebook-jupyter-minimal-ubi9-python-3.9"
77
+ expected_commitref=" 2023a"
78
+ expected_build_name=" jupyter-minimal-ubi9-python-3.9-amd64"
79
+ ;;
80
+ odh-minimal-notebook-image-n-2)
81
+ expected_name=" odh-notebook-jupyter-minimal-ubi8-python-3.8"
82
+ expected_commitref=" main"
83
+ expected_build_name=" jupyter-minimal-ubi8-python-3.8"
84
+ ;;
85
+ odh-minimal-gpu-notebook-image-n)
86
+ expected_name=" odh-notebook-jupyter-minimal-ubi9-python-3.9"
87
+ expected_commitref=" 2023b"
88
+ expected_build_name=" cuda-jupyter-minimal-ubi9-python-3.9-amd64"
89
+ ;;
90
+ odh-minimal-gpu-notebook-image-n-1)
91
+ expected_name=" odh-notebook-jupyter-minimal-ubi9-python-3.9"
92
+ expected_commitref=" 2023a"
93
+ expected_build_name=" cuda-jupyter-minimal-ubi9-python-3.9-amd64"
94
+ ;;
95
+ odh-minimal-gpu-notebook-image-n-2)
96
+ expected_name=" odh-notebook-jupyter-minimal-ubi8-python-3.8"
97
+ expected_commitref=" main"
98
+ expected_build_name=" cuda-jupyter-minimal-ubi8-python-3.8"
99
+ ;;
100
+ odh-pytorch-gpu-notebook-image-n)
101
+ expected_name=" odh-notebook-jupyter-pytorch-ubi9-python-3.9"
102
+ expected_commitref=" 2023b"
103
+ expected_build_name=" jupyter-pytorch-ubi9-python-3.9-amd64"
104
+ ;;
105
+ odh-pytorch-gpu-notebook-image-n-1)
106
+ expected_name=" odh-notebook-jupyter-pytorch-ubi9-python-3.9"
107
+ expected_commitref=" 2023a"
108
+ expected_build_name=" jupyter-pytorch-ubi9-python-3.9-amd64"
109
+ ;;
110
+ odh-pytorch-gpu-notebook-image-n-2)
111
+ expected_name=" odh-notebook-cuda-jupyter-pytorch-ubi8-python-3.8"
112
+ expected_commitref=" main"
113
+ expected_build_name=" cuda-jupyter-pytorch-ubi8-python-3.8"
114
+ ;;
115
+ odh-generic-data-science-notebook-image-n)
116
+ expected_name=" odh-notebook-jupyter-datascience-ubi9-python-3.9"
117
+ expected_commitref=" 2023b"
118
+ expected_build_name=" jupyter-datascience-ubi9-python-3.9-amd64"
119
+ ;;
120
+ odh-generic-data-science-notebook-image-n-1)
121
+ expected_name=" odh-notebook-jupyter-datascience-ubi9-python-3.9"
122
+ expected_commitref=" 2023a"
123
+ expected_build_name=" jupyter-datascience-ubi9-python-3.9-amd64"
124
+ ;;
125
+ odh-generic-data-science-notebook-image-n-2)
126
+ expected_name=" odh-notebook-jupyter-datascience-ubi8-python-3.8"
127
+ expected_commitref=" main"
128
+ expected_build_name=" jupyter-datascience-ubi8-python-3.8"
129
+ ;;
130
+ odh-tensorflow-gpu-notebook-image-n)
131
+ expected_name=" odh-notebook-cuda-jupyter-tensorflow-ubi9-python-3.9"
132
+ expected_commitref=" 2023b"
133
+ expected_build_name=" cuda-jupyter-tensorflow-ubi9-python-3.9-amd64"
134
+ ;;
135
+ odh-tensorflow-gpu-notebook-image-n-1)
136
+ expected_name=" odh-notebook-cuda-jupyter-tensorflow-ubi9-python-3.9"
137
+ expected_commitref=" 2023a"
138
+ expected_build_name=" cuda-jupyter-tensorflow-ubi9-python-3.9-amd64"
139
+ ;;
140
+ odh-tensorflow-gpu-notebook-image-n-2)
141
+ expected_name=" odh-notebook-cuda-jupyter-tensorflow-ubi8-python-3.8"
142
+ expected_commitref=" main"
143
+ expected_build_name=" cuda-jupyter-tensorflow-ubi8-python-3.8"
144
+ ;;
145
+ odh-trustyai-notebook-image-n)
146
+ expected_name=" odh-notebook-jupyter-trustyai-ubi9-python-3.9"
147
+ expected_commitref=" 2023b"
148
+ expected_build_name=" jupyter-trustyai-ubi9-python-3.9-amd64"
149
+ ;;
150
+ odh-trustyai-notebook-image-n-1)
151
+ expected_name=" odh-notebook-jupyter-trustyai-ubi9-python-3.9"
152
+ expected_commitref=" 2023a"
153
+ expected_build_name=" jupyter-trustyai-ubi9-python-3.9-amd64"
154
+ ;;
155
+ odh-habana-notebook-image-n)
156
+ expected_name=" odh-notebook-habana-jupyter-1.10.0-ubi8-python-3.8"
157
+ # expected_commitref="2023b"
158
+ expected_commitref=" main"
159
+ expected_build_name=" habana-jupyter-1.10.0-ubi8-python-3.8"
160
+ ;;
161
+ odh-codeserver-notebook-n)
162
+ expected_name=" odh-notebook-code-server-ubi9-python-3.9"
163
+ expected_commitref=" 2023b"
164
+ expected_build_name=" codeserver-ubi9-python-3.9-amd64"
165
+ ;;
166
+ odh-codeserver-notebook-n-1)
167
+ expected_name=" odh-notebook-code-server-c9s-python-3.9"
168
+ # expected_commitref="2023a"
169
+ expected_commitref=" main"
170
+ expected_build_name=" codeserver-c9s-python-3.9"
171
+ ;;
172
+ odh-rstudio-notebook-n)
173
+ expected_name=" odh-notebook-rstudio-c9s-python-3.9"
174
+ expected_commitref=" 2023b"
175
+ expected_build_name=" rstudio-c9s-python-3.9-amd64"
176
+ ;;
177
+ odh-rstudio-notebook-n-1)
178
+ expected_name=" odh-notebook-rstudio-c9s-python-3.9"
179
+ # expected_commitref="2023a"
180
+ expected_commitref=" main"
181
+ expected_build_name=" rstudio-c9s-python-3.9"
182
+ ;;
183
+ # For both RStudio GPU workbenches - the final name labels are identical to plain RStudio ones
184
+ # This is because the very same RStudio Dockerfile is used but different base images in both cases
185
+ # We should consider what to do with this - in ideal case, we should have different labels for these cases.
186
+ odh-rstudio-gpu-notebook-n)
187
+ expected_name=" odh-notebook-rstudio-c9s-python-3.9"
188
+ expected_commitref=" 2023b"
189
+ expected_build_name=" cuda-rstudio-c9s-python-3.9-amd64"
190
+ ;;
191
+ odh-rstudio-gpu-notebook-n-1)
192
+ expected_name=" odh-notebook-rstudio-c9s-python-3.9"
193
+ # expected_commitref="2023a"
194
+ expected_commitref=" main"
195
+ expected_build_name=" cuda-rstudio-c9s-python-3.9"
196
+ ;;
197
+ * )
198
+ echo " Unimplemented variable name: '${image_variable} '"
199
+ return 1
200
+ esac
201
+
202
+ test " ${image_name} " = " ${expected_name} " || {
203
+ echo " Image URL points to an incorrect image: expected name '${expected_name} '; actual '${image_name} '"
204
+ return 1
205
+ }
206
+
207
+ test " ${image_commitref} " = " ${expected_commitref} " || {
208
+ echo " Image URL points to an incorrect image: expected commitref '${expected_commitref} '; actual '${image_commitref} '"
209
+ return 1
210
+ }
211
+
212
+ test " ${openshift_build_name} " = " ${expected_build_name} " || {
213
+ echo " Image URL points to an incorrect image: expected OPENSHIFT_BUILD_NAME '${expected_build_name} '; actual '${openshift_build_name} '"
214
+ return 1
215
+ }
216
+ }
217
+
218
+ function check_image() {
219
+ local image_variable=" ${1} "
220
+ local image_url=" ${2} "
221
+
222
+ echo " Checking metadata for image '${image_variable} ' with URL '${image_url} '"
223
+
224
+ local image_metadata
225
+ local image_name
226
+ local image_commitref
227
+
228
+ image_metadata=" $( skopeo inspect --config " docker://${image_url} " ) " || {
229
+ echo " Couldn't download image metadata with skopeo tool!"
230
+ return 1
231
+ }
232
+ image_name=$( echo " ${image_metadata} " | jq --raw-output ' .config.Labels.name' ) || {
233
+ echo " Couldn't parse '.config.Labels.name' from image metadata!"
234
+ return 1
235
+ }
236
+ image_commitref=$( echo " ${image_metadata} " | jq --raw-output ' .config.Labels."io.openshift.build.commit.ref"' ) || {
237
+ echo " Couldn't parse '.config.Labels." io.openshift.build.commit.ref" ' from image metadata!"
238
+ return 1
239
+ }
240
+
241
+ local config_env
242
+ local build_name_raw
243
+ local openshift_build_name
244
+
245
+ config_env=$( echo " ${image_metadata} " | jq --raw-output ' .config.Env' ) || {
246
+ echo " Couldn't parse '.config.Env' from image metadata!"
247
+ return 1
248
+ }
249
+ build_name_raw=$( echo " ${config_env} " | grep ' "OPENSHIFT_BUILD_NAME=' ) || {
250
+ echo " Couldn't get 'OPENSHIFT_BUILD_NAME' from set of the image environment variables!"
251
+ return 1
252
+ }
253
+ openshift_build_name=$( echo " ${build_name_raw} " | sed ' s/.*"OPENSHIFT_BUILD_NAME=\(.*\)".*/\1/' ) || {
254
+ echo " Couldn't parse value of the 'OPENSHIFT_BUILD_NAME' variable from '${build_name_raw} '!"
255
+ return 1
256
+ }
257
+
258
+ test -n " ${image_name} " || {
259
+ echo " Couldn't retrieve the name of the image - got empty value!"
260
+ return 1
261
+ }
262
+
263
+ echo " Image name retrieved: '${image_name} '"
264
+
265
+ check_image_variable_matches_name_and_commitref " ${image_variable} " " ${image_name} " " ${image_commitref} " " ${openshift_build_name} " || return 1
266
+
267
+ echo " ---------------------------------------------"
268
+ }
269
+
270
+ # ------------------------------ MAIN SCRIPT --------------------------------- #
271
+
272
+ ret_code=0
273
+
274
+ echo " Starting check for file: '${PARAMS_ENV_PATH} '"
275
+ echo " ---------------------------------------------"
276
+
277
+ check_variables_uniq " ${PARAMS_ENV_PATH} " || {
278
+ echo " ERROR: Variable names in the file failed validation!"
279
+ echo " ----------------------------------------------------"
280
+ ret_code=1
281
+ }
282
+
283
+ while IFS= read -r LINE; do
284
+ echo " Checking format of: '${LINE} '"
285
+ [[ " ${LINE} " = * [[:space:]]* ]] && {
286
+ echo " ERROR: Line contains white-space and it shouldn't!"
287
+ echo " --------------------------------------------------"
288
+ ret_code=1
289
+ continue
290
+ }
291
+ [[ " ${LINE} " != * = * ]] && {
292
+ echo " ERROR: Line doesn't contain '=' and it should!"
293
+ echo " ----------------------------------------------"
294
+ ret_code=1
295
+ continue
296
+ }
297
+
298
+ IMAGE_VARIABLE=$( echo " ${LINE} " | cut --delimiter ' =' --field 1)
299
+ IMAGE_URL=$( echo " ${LINE} " | cut --delimiter ' =' --field 2)
300
+
301
+ test -n " ${IMAGE_VARIABLE} " || {
302
+ echo " ERROR: Couldn't parse image variable - got empty value!"
303
+ echo " -------------------------------------------------------"
304
+ ret_code=1
305
+ continue
306
+ }
307
+
308
+ test -n " ${IMAGE_URL} " || {
309
+ echo " ERROR: Couldn't parse image URL - got empty value!"
310
+ echo " --------------------------------------------------"
311
+ ret_code=1
312
+ continue
313
+ }
314
+
315
+ check_image " ${IMAGE_VARIABLE} " " ${IMAGE_URL} " || {
316
+ echo " ERROR: Image definition for '${IMAGE_VARIABLE} ' isn't okay!"
317
+ echo " ------------------------"
318
+ ret_code=1
319
+ continue
320
+ }
321
+ done < " ${PARAMS_ENV_PATH} "
322
+
323
+ echo " "
324
+ if test " ${ret_code} " -eq 0; then
325
+ echo " Validation of '${PARAMS_ENV_PATH} ' was successful! Congrats :)"
326
+ else
327
+ echo " The '${PARAMS_ENV_PATH} ' file isn't valid, please check above!"
328
+ fi
329
+
330
+ exit " ${ret_code} "
0 commit comments