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

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