@@ -27,6 +27,12 @@ PARAMS_ENV_PATH="manifests/base/params.env"
27
27
# images we want to have in the `params.env` file.
28
28
EXPECTED_NUM_RECORDS=21
29
29
30
+ # Size change tresholds:
31
+ # Max percentual change
32
+ SIZE_PERCENTUAL_TRESHOLD=10
33
+ # Max absolute change in MB
34
+ SIZE_ABSOLUTE_TRESHOLD=100
35
+
30
36
# ---------------------------- DEFINED FUNCTIONS ----------------------------- #
31
37
32
38
function check_variables_uniq() {
@@ -80,95 +86,114 @@ function check_variables_uniq() {
80
86
return " ${ret_code} "
81
87
}
82
88
83
- function check_image_variable_matches_name_and_commitref () {
89
+ function check_image_variable_matches_name_and_commitref_and_size () {
84
90
local image_variable=" ${1} "
85
91
local image_name=" ${2} "
86
92
local image_commitref=" ${3} "
87
93
local openshift_build_name=" ${4} "
94
+ local actual_img_size=" ${5} "
88
95
89
96
local expected_name
90
97
local expected_commitref
91
- local expected_build_name # Why some of the images has `-amd64` suffix and others not?
98
+ local expected_build_name
99
+ local expected_img_size
100
+
92
101
case " ${image_variable} " in
93
102
odh-minimal-notebook-image-n)
94
103
expected_name=" odh-notebook-jupyter-minimal-ubi9-python-3.11"
95
104
expected_commitref=" 2024b"
96
105
expected_build_name=" jupyter-minimal-ubi9-python-3.11-amd64"
106
+ expected_img_size=520
97
107
;;
98
108
odh-minimal-notebook-image-n-1)
99
109
expected_name=" odh-notebook-jupyter-minimal-ubi9-python-3.9"
100
110
expected_commitref=" 2024a"
101
111
expected_build_name=" jupyter-minimal-ubi9-python-3.9-amd64"
112
+ expected_img_size=503
102
113
;;
103
114
odh-minimal-gpu-notebook-image-n)
104
115
expected_name=" odh-notebook-jupyter-minimal-ubi9-python-3.11"
105
116
expected_commitref=" 2024b"
106
117
expected_build_name=" cuda-jupyter-minimal-ubi9-python-3.11-amd64"
118
+ expected_img_size=5157
107
119
;;
108
120
odh-minimal-gpu-notebook-image-n-1)
109
121
expected_name=" odh-notebook-jupyter-minimal-ubi9-python-3.9"
110
122
expected_commitref=" 2024a"
111
123
expected_build_name=" cuda-jupyter-minimal-ubi9-python-3.9-amd64"
124
+ expected_img_size=5718
112
125
;;
113
126
odh-pytorch-gpu-notebook-image-n)
114
127
expected_name=" odh-notebook-jupyter-pytorch-ubi9-python-3.11"
115
128
expected_commitref=" 2024b"
116
129
expected_build_name=" jupyter-pytorch-ubi9-python-3.11-amd64"
130
+ expected_img_size=8571
117
131
;;
118
132
odh-pytorch-gpu-notebook-image-n-1)
119
133
expected_name=" odh-notebook-jupyter-pytorch-ubi9-python-3.9"
120
134
expected_commitref=" 2024a"
121
135
expected_build_name=" jupyter-pytorch-ubi9-python-3.9-amd64"
136
+ expected_img_size=9037
122
137
;;
123
138
odh-generic-data-science-notebook-image-n)
124
139
expected_name=" odh-notebook-jupyter-datascience-ubi9-python-3.11"
125
140
expected_commitref=" 2024b"
126
141
expected_build_name=" jupyter-datascience-ubi9-python-3.11-amd64"
142
+ expected_img_size=961
127
143
;;
128
144
odh-generic-data-science-notebook-image-n-1)
129
145
expected_name=" odh-notebook-jupyter-datascience-ubi9-python-3.9"
130
146
expected_commitref=" 2024a"
131
147
expected_build_name=" jupyter-datascience-ubi9-python-3.9-amd64"
148
+ expected_img_size=904
132
149
;;
133
150
odh-tensorflow-gpu-notebook-image-n)
134
151
expected_name=" odh-notebook-cuda-jupyter-tensorflow-ubi9-python-3.11"
135
152
expected_commitref=" 2024b"
136
153
expected_build_name=" cuda-jupyter-tensorflow-ubi9-python-3.11-amd64"
154
+ expected_img_size=8211
137
155
;;
138
156
odh-tensorflow-gpu-notebook-image-n-1)
139
157
expected_name=" odh-notebook-cuda-jupyter-tensorflow-ubi9-python-3.9"
140
158
expected_commitref=" 2024a"
141
159
expected_build_name=" cuda-jupyter-tensorflow-ubi9-python-3.9-amd64"
160
+ expected_img_size=6667
142
161
;;
143
162
odh-trustyai-notebook-image-n)
144
163
expected_name=" odh-notebook-jupyter-trustyai-ubi9-python-3.11"
145
164
expected_commitref=" 2024b"
146
165
expected_build_name=" jupyter-trustyai-ubi9-python-3.11-amd64"
166
+ expected_img_size=4197
147
167
;;
148
168
odh-trustyai-notebook-image-n-1)
149
169
expected_name=" odh-notebook-jupyter-trustyai-ubi9-python-3.9"
150
170
expected_commitref=" 2024a"
151
171
expected_build_name=" jupyter-trustyai-ubi9-python-3.9-amd64"
172
+ expected_img_size=1158
152
173
;;
153
174
odh-codeserver-notebook-image-n)
154
175
expected_name=" odh-notebook-code-server-ubi9-python-3.11"
155
176
expected_commitref=" 2024b"
156
177
expected_build_name=" codeserver-ubi9-python-3.11-amd64"
178
+ expected_img_size=893
157
179
;;
158
180
odh-codeserver-notebook-image-n-1)
159
181
expected_name=" odh-notebook-code-server-ubi9-python-3.9"
160
182
expected_commitref=" 2024a"
161
183
expected_build_name=" codeserver-ubi9-python-3.9-amd64"
184
+ expected_img_size=850
162
185
;;
163
186
odh-rstudio-notebook-image-n)
164
187
expected_name=" odh-notebook-rstudio-server-c9s-python-3.11"
165
188
expected_commitref=" 2024b"
166
189
expected_build_name=" rstudio-c9s-python-3.11-amd64"
190
+ expected_img_size=1242
167
191
;;
168
192
odh-rstudio-notebook-image-n-1)
169
193
expected_name=" odh-notebook-rstudio-server-c9s-python-3.9"
170
194
expected_commitref=" 2024a"
171
195
expected_build_name=" rstudio-c9s-python-3.9-amd64"
196
+ expected_img_size=1208
172
197
;;
173
198
# For both RStudio GPU workbenches - the final name labels are identical to plain RStudio ones
174
199
# This is because the very same RStudio Dockerfile is used but different base images in both cases
@@ -177,26 +202,31 @@ function check_image_variable_matches_name_and_commitref() {
177
202
expected_name=" odh-notebook-rstudio-server-c9s-python-3.11"
178
203
expected_commitref=" 2024b"
179
204
expected_build_name=" cuda-rstudio-c9s-python-3.11-amd64"
205
+ expected_img_size=7184
180
206
;;
181
207
odh-rstudio-gpu-notebook-image-n-1)
182
208
expected_name=" odh-notebook-rstudio-server-c9s-python-3.9"
183
209
expected_commitref=" 2024a"
184
210
expected_build_name=" cuda-rstudio-c9s-python-3.9-amd64"
211
+ expected_img_size=7129
185
212
;;
186
213
odh-rocm-minimal-notebook-image-n)
187
214
expected_name=" odh-notebook-jupyter-minimal-ubi9-python-3.11"
188
215
expected_commitref=" 2024b"
189
216
expected_build_name=" rocm-jupyter-minimal-ubi9-python-3.11-amd64"
217
+ expected_img_size=4830
190
218
;;
191
219
odh-rocm-pytorch-notebook-image-n)
192
220
expected_name=" odh-notebook-jupyter-rocm-pytorch-ubi9-python-3.11"
193
221
expected_commitref=" 2024b"
194
222
expected_build_name=" rocm-jupyter-pytorch-ubi9-python-3.11-amd64"
223
+ expected_img_size=6571
195
224
;;
196
225
odh-rocm-tensorflow-notebook-image-n)
197
226
expected_name=" odh-notebook-jupyter-rocm-tensorflow-ubi9-python-3.11"
198
227
expected_commitref=" 2024b"
199
228
expected_build_name=" rocm-jupyter-tensorflow-ubi9-python-3.11-amd64"
229
+ expected_img_size=5782
200
230
;;
201
231
* )
202
232
echo " Unimplemented variable name: '${image_variable} '"
@@ -217,6 +247,22 @@ function check_image_variable_matches_name_and_commitref() {
217
247
echo " Image URL points to an incorrect image: expected OPENSHIFT_BUILD_NAME '${expected_build_name} '; actual '${openshift_build_name} '"
218
248
return 1
219
249
}
250
+
251
+ # Check the size change constraints now
252
+ # 1. Percentual size change
253
+ percent_change=$(( 100 * actual_img_size / expected_img_size - 100 ))
254
+ abs_percent_change=${percent_change# -* }
255
+ test ${abs_percent_change} -le ${SIZE_PERCENTUAL_TRESHOLD} || {
256
+ echo " Image size changed by ${abs_percent_change} % (expected: ${expected_img_size} MB; actual: ${actual_img_size} MB; treshold: ${SIZE_PERCENTUAL_TRESHOLD} %)."
257
+ return 1
258
+ }
259
+ # 2. Absolute size change
260
+ size_difference=$(( actual_img_size - expected_img_size))
261
+ abs_size_difference=${size_difference# -* }
262
+ test ${abs_size_difference} -le ${SIZE_ABSOLUTE_TRESHOLD} || {
263
+ echo " Image size changed by ${abs_size_difference} MB (expected: ${expected_img_size} MB; actual: ${actual_img_size} MB; treshold: ${SIZE_ABSOLUTE_TRESHOLD} MB)."
264
+ return 1
265
+ }
220
266
}
221
267
222
268
function check_image_commit_id_matches_metadata() {
@@ -249,29 +295,29 @@ function check_image() {
249
295
250
296
echo " Checking metadata for image '${image_variable} ' with URL '${image_url} '"
251
297
252
- local image_metadata
298
+ local image_metadata_config
253
299
local image_name
254
300
local image_commit_id
255
301
local image_commitref
256
302
local image_created
257
303
258
- image_metadata =" $( skopeo inspect --config " docker://${image_url} " ) " || {
259
- echo " Couldn't download image metadata with skopeo tool!"
304
+ image_metadata_config =" $( skopeo inspect --config " docker://${image_url} " ) " || {
305
+ echo " Couldn't download image config metadata with skopeo tool!"
260
306
return 1
261
307
}
262
- image_name=$( echo " ${image_metadata } " | jq --raw-output ' .config.Labels.name' ) || {
308
+ image_name=$( echo " ${image_metadata_config } " | jq --raw-output ' .config.Labels.name' ) || {
263
309
echo " Couldn't parse '.config.Labels.name' from image metadata!"
264
310
return 1
265
311
}
266
- image_commit_id=$( echo " ${image_metadata } " | jq --raw-output ' .config.Labels."io.openshift.build.commit.id"' ) || {
312
+ image_commit_id=$( echo " ${image_metadata_config } " | jq --raw-output ' .config.Labels."io.openshift.build.commit.id"' ) || {
267
313
echo " Couldn't parse '.config.Labels." io.openshift.build.commit.id" ' from image metadata!"
268
314
return 1
269
315
}
270
- image_commitref=$( echo " ${image_metadata } " | jq --raw-output ' .config.Labels."io.openshift.build.commit.ref"' ) || {
316
+ image_commitref=$( echo " ${image_metadata_config } " | jq --raw-output ' .config.Labels."io.openshift.build.commit.ref"' ) || {
271
317
echo " Couldn't parse '.config.Labels." io.openshift.build.commit.ref" ' from image metadata!"
272
318
return 1
273
319
}
274
- image_created=$( echo " ${image_metadata } " | jq --raw-output ' .created' ) || {
320
+ image_created=$( echo " ${image_metadata_config } " | jq --raw-output ' .created' ) || {
275
321
echo " Couldn't parse '.created' from image metadata!"
276
322
return 1
277
323
}
@@ -280,7 +326,7 @@ function check_image() {
280
326
local build_name_raw
281
327
local openshift_build_name
282
328
283
- config_env=$( echo " ${image_metadata } " | jq --raw-output ' .config.Env' ) || {
329
+ config_env=$( echo " ${image_metadata_config } " | jq --raw-output ' .config.Env' ) || {
284
330
echo " Couldn't parse '.config.Env' from image metadata!"
285
331
return 1
286
332
}
@@ -293,15 +339,38 @@ function check_image() {
293
339
return 1
294
340
}
295
341
342
+ local image_metadata
343
+ local image_size
344
+ local image_size_mb
345
+
346
+ image_metadata=" $( skopeo inspect --raw " docker://${image_url} " ) " || {
347
+ echo " Couldn't download image metadata with skopeo tool!"
348
+ return 1
349
+ }
350
+ # Here we get the image size as a compressed image. This differs to what we gather in
351
+ # 'tests/containers/base_image_test.py#test_image_size_change' where we check against the extracted image size.
352
+ # There is no actual reason to compare these different sizes except that in this case we want to do check the
353
+ # image remotely, whereas in the othe test, we have the image present locally on the machine.
354
+ image_size=$( echo " ${image_metadata} " | jq ' [ .layers[].size ] | add' ) || {
355
+ echo " Couldn't count image size from image metadata!"
356
+ return 1
357
+ }
358
+ image_size_mb=$(( image_size / 1024 / 1024 )) || {
359
+ echo " Couldn't count image size from image metadata!"
360
+ return 1
361
+ }
362
+
296
363
test -n " ${image_name} " || {
297
364
echo " Couldn't retrieve the name of the image - got empty value!"
298
365
return 1
299
366
}
300
367
301
368
echo " Image name retrieved: '${image_name} '"
302
369
echo " Image created: '${image_created} '"
370
+ echo " Image size: ${image_size_mb} MB"
303
371
304
- check_image_variable_matches_name_and_commitref " ${image_variable} " " ${image_name} " " ${image_commitref} " " ${openshift_build_name} " || return 1
372
+ check_image_variable_matches_name_and_commitref_and_size " ${image_variable} " " ${image_name} " " ${image_commitref} " \
373
+ " ${openshift_build_name} " " ${image_size_mb} " || return 1
305
374
306
375
check_image_commit_id_matches_metadata " ${image_variable} " " ${image_commit_id} " || return 1
307
376
374
443
echo " The '${PARAMS_ENV_PATH} ' file isn't valid, please check above!"
375
444
fi
376
445
377
- exit " ${ret_code} "
446
+ exit " ${ret_code} "
0 commit comments