Skip to content

Commit d1fe5bc

Browse files
Merge pull request opendatahub-io#912 from jstourac/testImgSizeBash
RHOAIENG-20088: chore(GHA CI): check images size change
2 parents 8f3681e + 4793870 commit d1fe5bc

File tree

2 files changed

+187
-19
lines changed

2 files changed

+187
-19
lines changed

Diff for: ci/check-params-env.sh

+81-12
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@ PARAMS_ENV_PATH="manifests/base/params.env"
2727
# images we want to have in the `params.env` file.
2828
EXPECTED_NUM_RECORDS=21
2929

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+
3036
# ---------------------------- DEFINED FUNCTIONS ----------------------------- #
3137

3238
function check_variables_uniq() {
@@ -80,95 +86,114 @@ function check_variables_uniq() {
8086
return "${ret_code}"
8187
}
8288

83-
function check_image_variable_matches_name_and_commitref() {
89+
function check_image_variable_matches_name_and_commitref_and_size() {
8490
local image_variable="${1}"
8591
local image_name="${2}"
8692
local image_commitref="${3}"
8793
local openshift_build_name="${4}"
94+
local actual_img_size="${5}"
8895

8996
local expected_name
9097
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+
92101
case "${image_variable}" in
93102
odh-minimal-notebook-image-n)
94103
expected_name="odh-notebook-jupyter-minimal-ubi9-python-3.11"
95104
expected_commitref="2024b"
96105
expected_build_name="jupyter-minimal-ubi9-python-3.11-amd64"
106+
expected_img_size=520
97107
;;
98108
odh-minimal-notebook-image-n-1)
99109
expected_name="odh-notebook-jupyter-minimal-ubi9-python-3.9"
100110
expected_commitref="2024a"
101111
expected_build_name="jupyter-minimal-ubi9-python-3.9-amd64"
112+
expected_img_size=503
102113
;;
103114
odh-minimal-gpu-notebook-image-n)
104115
expected_name="odh-notebook-jupyter-minimal-ubi9-python-3.11"
105116
expected_commitref="2024b"
106117
expected_build_name="cuda-jupyter-minimal-ubi9-python-3.11-amd64"
118+
expected_img_size=5157
107119
;;
108120
odh-minimal-gpu-notebook-image-n-1)
109121
expected_name="odh-notebook-jupyter-minimal-ubi9-python-3.9"
110122
expected_commitref="2024a"
111123
expected_build_name="cuda-jupyter-minimal-ubi9-python-3.9-amd64"
124+
expected_img_size=5718
112125
;;
113126
odh-pytorch-gpu-notebook-image-n)
114127
expected_name="odh-notebook-jupyter-pytorch-ubi9-python-3.11"
115128
expected_commitref="2024b"
116129
expected_build_name="jupyter-pytorch-ubi9-python-3.11-amd64"
130+
expected_img_size=8571
117131
;;
118132
odh-pytorch-gpu-notebook-image-n-1)
119133
expected_name="odh-notebook-jupyter-pytorch-ubi9-python-3.9"
120134
expected_commitref="2024a"
121135
expected_build_name="jupyter-pytorch-ubi9-python-3.9-amd64"
136+
expected_img_size=9037
122137
;;
123138
odh-generic-data-science-notebook-image-n)
124139
expected_name="odh-notebook-jupyter-datascience-ubi9-python-3.11"
125140
expected_commitref="2024b"
126141
expected_build_name="jupyter-datascience-ubi9-python-3.11-amd64"
142+
expected_img_size=961
127143
;;
128144
odh-generic-data-science-notebook-image-n-1)
129145
expected_name="odh-notebook-jupyter-datascience-ubi9-python-3.9"
130146
expected_commitref="2024a"
131147
expected_build_name="jupyter-datascience-ubi9-python-3.9-amd64"
148+
expected_img_size=904
132149
;;
133150
odh-tensorflow-gpu-notebook-image-n)
134151
expected_name="odh-notebook-cuda-jupyter-tensorflow-ubi9-python-3.11"
135152
expected_commitref="2024b"
136153
expected_build_name="cuda-jupyter-tensorflow-ubi9-python-3.11-amd64"
154+
expected_img_size=8211
137155
;;
138156
odh-tensorflow-gpu-notebook-image-n-1)
139157
expected_name="odh-notebook-cuda-jupyter-tensorflow-ubi9-python-3.9"
140158
expected_commitref="2024a"
141159
expected_build_name="cuda-jupyter-tensorflow-ubi9-python-3.9-amd64"
160+
expected_img_size=6667
142161
;;
143162
odh-trustyai-notebook-image-n)
144163
expected_name="odh-notebook-jupyter-trustyai-ubi9-python-3.11"
145164
expected_commitref="2024b"
146165
expected_build_name="jupyter-trustyai-ubi9-python-3.11-amd64"
166+
expected_img_size=4197
147167
;;
148168
odh-trustyai-notebook-image-n-1)
149169
expected_name="odh-notebook-jupyter-trustyai-ubi9-python-3.9"
150170
expected_commitref="2024a"
151171
expected_build_name="jupyter-trustyai-ubi9-python-3.9-amd64"
172+
expected_img_size=1158
152173
;;
153174
odh-codeserver-notebook-image-n)
154175
expected_name="odh-notebook-code-server-ubi9-python-3.11"
155176
expected_commitref="2024b"
156177
expected_build_name="codeserver-ubi9-python-3.11-amd64"
178+
expected_img_size=893
157179
;;
158180
odh-codeserver-notebook-image-n-1)
159181
expected_name="odh-notebook-code-server-ubi9-python-3.9"
160182
expected_commitref="2024a"
161183
expected_build_name="codeserver-ubi9-python-3.9-amd64"
184+
expected_img_size=850
162185
;;
163186
odh-rstudio-notebook-image-n)
164187
expected_name="odh-notebook-rstudio-server-c9s-python-3.11"
165188
expected_commitref="2024b"
166189
expected_build_name="rstudio-c9s-python-3.11-amd64"
190+
expected_img_size=1242
167191
;;
168192
odh-rstudio-notebook-image-n-1)
169193
expected_name="odh-notebook-rstudio-server-c9s-python-3.9"
170194
expected_commitref="2024a"
171195
expected_build_name="rstudio-c9s-python-3.9-amd64"
196+
expected_img_size=1208
172197
;;
173198
# For both RStudio GPU workbenches - the final name labels are identical to plain RStudio ones
174199
# 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() {
177202
expected_name="odh-notebook-rstudio-server-c9s-python-3.11"
178203
expected_commitref="2024b"
179204
expected_build_name="cuda-rstudio-c9s-python-3.11-amd64"
205+
expected_img_size=7184
180206
;;
181207
odh-rstudio-gpu-notebook-image-n-1)
182208
expected_name="odh-notebook-rstudio-server-c9s-python-3.9"
183209
expected_commitref="2024a"
184210
expected_build_name="cuda-rstudio-c9s-python-3.9-amd64"
211+
expected_img_size=7129
185212
;;
186213
odh-rocm-minimal-notebook-image-n)
187214
expected_name="odh-notebook-jupyter-minimal-ubi9-python-3.11"
188215
expected_commitref="2024b"
189216
expected_build_name="rocm-jupyter-minimal-ubi9-python-3.11-amd64"
217+
expected_img_size=4830
190218
;;
191219
odh-rocm-pytorch-notebook-image-n)
192220
expected_name="odh-notebook-jupyter-rocm-pytorch-ubi9-python-3.11"
193221
expected_commitref="2024b"
194222
expected_build_name="rocm-jupyter-pytorch-ubi9-python-3.11-amd64"
223+
expected_img_size=6571
195224
;;
196225
odh-rocm-tensorflow-notebook-image-n)
197226
expected_name="odh-notebook-jupyter-rocm-tensorflow-ubi9-python-3.11"
198227
expected_commitref="2024b"
199228
expected_build_name="rocm-jupyter-tensorflow-ubi9-python-3.11-amd64"
229+
expected_img_size=5782
200230
;;
201231
*)
202232
echo "Unimplemented variable name: '${image_variable}'"
@@ -217,6 +247,22 @@ function check_image_variable_matches_name_and_commitref() {
217247
echo "Image URL points to an incorrect image: expected OPENSHIFT_BUILD_NAME '${expected_build_name}'; actual '${openshift_build_name}'"
218248
return 1
219249
}
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+
}
220266
}
221267

222268
function check_image_commit_id_matches_metadata() {
@@ -249,29 +295,29 @@ function check_image() {
249295

250296
echo "Checking metadata for image '${image_variable}' with URL '${image_url}'"
251297

252-
local image_metadata
298+
local image_metadata_config
253299
local image_name
254300
local image_commit_id
255301
local image_commitref
256302
local image_created
257303

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!"
260306
return 1
261307
}
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') || {
263309
echo "Couldn't parse '.config.Labels.name' from image metadata!"
264310
return 1
265311
}
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"') || {
267313
echo "Couldn't parse '.config.Labels."io.openshift.build.commit.id"' from image metadata!"
268314
return 1
269315
}
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"') || {
271317
echo "Couldn't parse '.config.Labels."io.openshift.build.commit.ref"' from image metadata!"
272318
return 1
273319
}
274-
image_created=$(echo "${image_metadata}" | jq --raw-output '.created') || {
320+
image_created=$(echo "${image_metadata_config}" | jq --raw-output '.created') || {
275321
echo "Couldn't parse '.created' from image metadata!"
276322
return 1
277323
}
@@ -280,7 +326,7 @@ function check_image() {
280326
local build_name_raw
281327
local openshift_build_name
282328

283-
config_env=$(echo "${image_metadata}" | jq --raw-output '.config.Env') || {
329+
config_env=$(echo "${image_metadata_config}" | jq --raw-output '.config.Env') || {
284330
echo "Couldn't parse '.config.Env' from image metadata!"
285331
return 1
286332
}
@@ -293,15 +339,38 @@ function check_image() {
293339
return 1
294340
}
295341

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+
296363
test -n "${image_name}" || {
297364
echo "Couldn't retrieve the name of the image - got empty value!"
298365
return 1
299366
}
300367

301368
echo "Image name retrieved: '${image_name}'"
302369
echo "Image created: '${image_created}'"
370+
echo "Image size: ${image_size_mb} MB"
303371

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
305374

306375
check_image_commit_id_matches_metadata "${image_variable}" "${image_commit_id}" || return 1
307376

@@ -374,4 +443,4 @@ else
374443
echo "The '${PARAMS_ENV_PATH}' file isn't valid, please check above!"
375444
fi
376445

377-
exit "${ret_code}"
446+
exit "${ret_code}"

0 commit comments

Comments
 (0)