OILS / deps / images.sh View on Github | oils.pub

348 lines, 132 significant
1#!/usr/bin/env bash
2#
3# Manage container images for Soil
4#
5# Usage:
6# deps/images.sh <function name>
7#
8# Dirs maybe to clear:
9#
10# $0 clean-all # Start from scratch
11#
12# Example:
13#
14# (1) Update LATEST_TAG
15#
16# (2) Bootstrapping Wedges
17#
18# $0 build wedge-bootstrap-debian-12 # runs init-deb-cache
19#
20# (3) Building wedges:
21#
22# build/deps.sh fetch
23# build/deps.sh boxed-wedges
24# build/deps.sh boxed-spec-bin
25#
26# (4) Rebuild an image
27#
28# $0 build soil-debian-12 # runs init-deb-cache and populate the cache
29# $0 build soil-test-image T # reuse package cache from apt-get
30# $0 smoke soil-test-image # smoke test
31#
32# (5) Update live version in 'soil/host-shim.sh live-image-tag'
33#
34# (6) Push Everything you Built
35#
36# $0 push wedge-bootstrap-debian-12 # pushes both $LATEST_TAG and latest
37# $0 push soil-debian-12 # ditto
38# $0 push soil-test-image # ditto
39#
40# More
41# ----
42#
43# Images: https://hub.docker.com/u/oilshell
44#
45# $0 list-tagged # Show versions of images
46#
47# $0 show-cachemount # show files in apt cache
48#
49# $0 prune # seems to clear the cache
50
51set -o nounset
52set -o pipefail
53set -o errexit
54
55source deps/podman.sh
56
57DOCKER=${DOCKER:-docker}
58
59# Build with this tag
60readonly LATEST_TAG='v-2025-04-30b'
61
62clean-all() {
63 dirs='_build/wedge/tmp _build/wedge/binary _build/deps-source'
64 #rm -r -f $dirs
65 sudo rm -r -f $dirs
66}
67
68# BUGS in Docker.
69#
70# https://stackoverflow.com/questions/69173822/docker-build-uses-wrong-dockerfile-content-bug
71
72# NOTE: This also clears the exec.cachemount
73prune() {
74 sudo $DOCKER builder prune -f
75}
76
77# https://stackoverflow.com/questions/62834806/docker-buildkit-cache-location-size-and-id
78#
79# It lives somewhere in /var/lib/docker/overlay2
80
81show-cachemount() {
82 sudo $DOCKER system df -v --format '{{ .BuildCache | json }}' \
83 | jq '.[] | select(.CacheType == "exec.cachemount")' | tee _tmp/cachemount.txt
84
85 cat _tmp/cachemount.txt | jq -r '.ID' | while read id; do
86 sudo tree /var/lib/docker/overlay2/$id
87 sudo du --si -s /var/lib/docker/overlay2/$id
88 echo
89 done
90}
91
92tag-latest() {
93 local name=${1:-wedge-bootstrap-debian-12}
94 local tag_built_with=${2:-$LATEST_TAG}
95
96 set -x # 'docker tag' is annoyingly silent
97 sudo $DOCKER tag oilshell/$name:{$tag_built_with,latest}
98}
99
100build() {
101 local name=${1:-soil-dummy}
102 local use_cache=${2:-} # OFF by default
103
104 # set -x
105 local -a flags
106 if test -n "$use_cache"; then
107 flags=()
108 else
109 flags=('--no-cache=true')
110 fi
111 #flags+=('--progress=plain')
112
113 # Uh BuildKit is not the default on Linux!
114 # http://jpetazzo.github.io/2021/11/30/docker-build-container-images-antipatterns/
115 #
116 # It is more parallel and has colored output.
117
118 # TODO: use --authfile and more
119 #export-podman
120
121 # can't preserve the entire env: https://github.com/containers/buildah/issues/3887
122 #sudo --preserve-env=CONTAINERS_REGISTRIES_CONF --preserve-env=REGISTRY_AUTH_FILE \
123 sudo -E DOCKER_BUILDKIT=1 \
124 $DOCKER build "${flags[@]}" \
125 --tag "oilshell/$name:$LATEST_TAG" \
126 --file deps/Dockerfile.$name .
127
128 # Avoid hassle by also tagging it
129 tag-latest $name
130}
131
132list-images() {
133 for name in deps/Dockerfile.*; do
134 local image_id=${name//'deps/Dockerfile.'/}
135 if test "$image_id" = 'test-image'; then
136 continue
137 fi
138 echo $image_id
139 done
140}
141
142build-all() {
143 # Should rebuild all these
144 # Except I also want to change the Dockerfile to use Debian 12
145 list-images | egrep -v 'test-image|ovm-tarball|benchmarks|wedge-bootstrap|debian-12'
146}
147
148list-tagged() {
149 sudo $DOCKER images 'oilshell/*' #:v-*'
150}
151
152push() {
153 local name=${1:-soil-dummy}
154 local tag=${2:-$LATEST_TAG}
155
156 # TODO: replace with flags
157 #export-podman
158
159 local image="oilshell/$name:$tag"
160
161 set -x
162
163 # -E for export-podman vars
164 sudo -E $DOCKER push $image
165 #sudo -E $DOCKER --log-level=debug push $image
166
167 # Also push the 'latest' tag, to avoid getting out of sync
168 sudo -E $DOCKER push oilshell/$name:latest
169}
170
171smoke-test-script() {
172 echo '
173for file in /etc/debian_version /etc/lsb-release; do
174 if test -f $file; then
175 # spec/ble-idioms tests this
176 #grep -E "foo|^10" $file; echo grep=$?
177
178 echo $file
179 echo
180 cat $file
181 echo
182 else
183 echo "($file does not exist)"
184 fi
185done
186
187echo "bash $BASH_VERSION"
188
189git --version
190
191for name in python python2 python3; do
192 if which $name; then
193 $name -V
194 else
195 echo "$name not found"
196 fi
197done
198
199echo PATH=$PATH
200
201#curl https://op.oilshell.org/
202
203if true; then
204 python3 -c "import ssl; print(ssl)"
205 find /usr/lib | grep -i libssl
206 echo
207
208 dpkg -S /usr/lib/x86_64-linux-gnu/libssl.so.3
209 echo
210
211 #ls -l /usr/lib/x86_64-linux-gnu/libssl.so.1.1
212
213 apt-cache show libssl-dev
214
215 # find /lib | grep -i libssl
216 # echo
217 # find /usr/local | grep -i libssl
218 # echo
219 # python3-config --libs
220
221 # Useful command
222 # ldconfig -v #| grep ssl
223 # echo
224
225 #find / -name 'libssl.so*'
226fi
227'
228}
229
230smoke() {
231 sudo $0 _smoke "$@"
232}
233
234_smoke() {
235 ### Smoke test of container
236 local name=${1:-soil-dummy}
237 local tag=${2:-$LATEST_TAG}
238 local docker=${3:-$DOCKER}
239 local prefix=${4:-}
240
241 #sudo docker run oilshell/$name
242 #sudo docker run oilshell/$name python2 -c 'print("python2")'
243
244 # Need to point at registries.conf ?
245 #export-podman
246
247 $docker run ${prefix}oilshell/$name:$tag bash -c "$(smoke-test-script)"
248
249 # Python 2.7 build/prepare.sh requires this
250 #sudo docker run oilshell/$name python -V
251
252 #sudo docker run oilshell/$name python3 -c 'import pexpect; print(pexpect)'
253}
254
255smoke-podman() {
256 local name=${1:-dummy}
257
258 # 2025-04: I need to do 'podman login docker.io'
259 #
260 # Running without root
261
262 # need explicit docker.io prefix with podman
263 # smoke $name latest podman docker.io/
264
265 local tag='latest'
266 local prefix='docker.io/'
267 smoke-test-script | podman run -i ${prefix}oilshell/soil-$name:$tag bash
268}
269
270cmd() {
271 ### Run an arbitrary command
272 local name=${1:-soil-dummy}
273 local tag=${2:-$LATEST_TAG}
274
275 shift 2
276
277 sudo $DOCKER run oilshell/$name:$tag "$@"
278}
279
280utf8() {
281 # needed for a spec test, not the default on Debian
282 cmd ovm-tarball bash -c 'LC_ALL=en_US.UTF-8; echo $LC_ALL'
283}
284
285mount-test() {
286 local name=${1:-soil-dummy}
287
288 local -a argv
289 if test $# -le 1; then
290 argv=(sh -c 'ls -l /home/uke/oil')
291 else
292 argv=( "${@:2}" ) # index 2 not 1, weird shell behavior
293 fi
294
295 # mount Oil directory as /app
296 sudo $DOCKER run \
297 --mount "type=bind,source=$PWD,target=/home/uke/oil" \
298 oilshell/$name "${argv[@]}"
299}
300
301image-history() {
302 local image_id=${1:-soil-dummy}
303 local tag=${2:-latest}
304
305 local image="oilshell/$image_id"
306
307 sudo $DOCKER history $image:$tag
308}
309
310save() {
311 local image_id=${1:-soil-dummy}
312 local tag=${2:-latest}
313
314 local image="oilshell/$image_id"
315
316 mkdir -p _tmp/images
317 local out=_tmp/images/$image_id.tar
318
319 # Use > instead of -o so it doesn'th have root permissions
320 time sudo $DOCKER save $image:$tag > $out
321 ls -l -h $out
322}
323
324# This shows CREATED, command CREATED BY, size
325# It's a human readable size though
326#
327# This doesn't really have anything better
328# https://gist.github.com/MichaelSimons/fb588539dcefd9b5fdf45ba04c302db6
329#
330# It's annoying that the remote registry API is different than the local API.
331
332layers() {
333 local name=${1:-soil-dummy}
334 local tag=${2:-$LATEST_TAG}
335
336 local image="oilshell/$name:$tag"
337
338 # Gah this still prints 237M, not the exact number of bytes!
339 # --format ' {{ .Size }} '
340 sudo $DOCKER history --no-trunc $image
341
342 echo $'Size\tVirtual Size'
343 sudo $DOCKER inspect $image \
344 | jq --raw-output '.[0] | [.Size, .VirtualSize] | @tsv' \
345 | commas
346}
347
348"$@"