OILS / regtest / aports-container.sh View on Github | oils.pub

304 lines, 111 significant
1#!/usr/bin/env bash
2#
3# Usage:
4# regtest/aports-container.sh <function name>
5
6: ${LIB_OSH=stdlib/osh}
7source $LIB_OSH/bash-strict.sh
8source $LIB_OSH/task-five.sh
9
10source regtest/aports-common.sh
11
12# Flow
13#
14# - make-chroot
15# - add-build-deps - extra packages
16# - config-chroot - users/groups, keygen
17# - oils-in-chroot - can this be bind mount?
18# - save-default-config
19# - hm maybe we can use LAYERS here - baseline and osh
20#
21# - fetch-packages
22# - this can be another layer
23# - build-packages, which yields TSV and logs
24# - do we use podman cp?
25# - or do we set up a bind mount, and aports-guest.sh knows how to write
26# there?
27# - /home/udu/oils/_tmp/aports-guest could be the bind mount
28# - back to _tmp/aports-guest
29#
30# - and then we can push to a central registry?
31# - packages are 6 GB, so I guess we can take advantage of that
32#
33# TODO:
34# - test abuild rootbld
35
36
37deps() {
38 # https://blog.abysm.org/2023/06/switching-system-wide-default-storage-driver-from-vfs-to-overlayfs-for-podman-on-debian-bookworm/
39
40 # containers-storage needed on Debian bookworm for overlayfs
41
42 sudo apt-get install podman containers-storage
43}
44
45system-reset() {
46 # this removes everything
47 podman system reset
48}
49
50system-prune() {
51 # this is GC - it sorta works
52 podman system prune -a
53}
54
55show-work-area() {
56 # 16K files, each layer is already materialized
57
58 # Hm the container is 277 M
59 # But this work dir is 580 M , after podman system reset?
60 # It's doubling the storage?
61 # Because it's the VFS driver? Geez
62 # for rootless operation
63
64 local work_dir=~/.local/share/containers/storage/
65
66 set +o errexit
67 find $work_dir | wc -l
68
69 du --si -s $work_dir
70}
71
72remove-all() {
73 # It's silly that podman/docker have a separate set of commands
74 # this should just be removing files!
75
76 podman rmi -a -f
77}
78
79check-kernel-module() {
80 lsmod | grep overlay
81}
82
83migrate() {
84 # not sure if we need this
85 podman system migrate
86}
87
88readonly branch='v3.22'
89readonly ROOTFS_TAR=_chroot/alpine-$branch.tar.gz
90
91make-rootfs() {
92 rm -f -v $ROOTFS_TAR
93
94 # apk-tools needed to bootstrap? otherwise we can't apk add later
95 sudo ../../alpinelinux/alpine-make-rootfs/alpine-make-rootfs \
96 --branch $branch \
97 --packages 'apk-tools' \
98 $ROOTFS_TAR
99}
100
101list-tar() {
102 tar --list -z < $ROOTFS_TAR
103 echo
104
105 ls -l --si $ROOTFS_TAR
106}
107
108# copied from /etc/profile in the chroot
109readonly GUEST_PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
110
111make-oci() {
112 ### make OCI image with buildah
113 # there is also the pure hsell 'sloci-image' from Alpine
114
115 set -x
116
117 # Create a new container from scratch
118 echo "Creating container from rootfs..."
119 c1=$(buildah from scratch)
120 echo "Container ID: $c1"
121
122 # Add the rootfs directory contents to the container
123 echo "Adding rootfs contents..."
124 buildah add $c1 _chroot/alpine-v3.22.tar.gz /
125
126 # Optional: Set environment variables
127 # TODO: check this path, where does it come from?
128 buildah config --env PATH=$GUEST_PATH $c1
129
130 # Set some basic container metadata (optional but recommended)
131 buildah config --workingdir /home/oils $c1
132 buildah config --cmd /bin/sh $c1
133
134 # copied from regtest/aports-setup.sh
135 buildah run $c1 -- adduser -D udu
136 buildah run $c1 -- addgroup udu abuild
137 buildah run $c1 -- addgroup udu wheel
138 buildah run $c1 -- sh -c \
139 'echo "permit nopass :wheel" >> /etc/doas.conf'
140
141 buildah config --user udu $c1
142
143 # Create the /app/data directory in the container
144 #buildah run $c1 -- mkdir -p /home/oils
145
146 # Commit the container to create an image
147 IMAGE_NAME='aports-build:latest'
148 echo "Committing container to image: $IMAGE_NAME"
149 buildah commit $c1 $IMAGE_NAME
150
151 # necessary for 2 layers
152 local c2
153 c2=$(buildah from $IMAGE_NAME)
154
155 # Defaults from alpine-chroot-install
156 buildah run --user root $c2 -- \
157 apk add build-base ca-certificates ssl_client alpine-sdk abuild-rootbld pigz doas
158
159 # Run as udu
160 buildah run $c2 -- \
161 abuild-keygen --append --install -n
162
163 buildah commit $c2 $IMAGE_NAME
164
165 # Hm this seems necessary to clean up the work area? Why?
166 # system-prune also works, but it's a bad interface!
167 #
168 # I don't see why buildah does this extra copying ...
169
170 #buildah rm $c2
171
172 echo "Image built successfully: $IMAGE_NAME c1=$c1 c2=$c2"
173}
174
175
176run() {
177 # Run the container with podman (rootless) and bind mount a dir
178
179 # Make sure the host directory exists
180 local host_dir=_tmp/mnt/data
181 mkdir -p $host_dir
182 touch $host_dir/foo.txt
183
184 # Run the container with bind mount
185 # --rm: remove container when it exits
186 # -it: interactive with tty
187 # -v: bind mount (volume)
188 #
189 # takes ~213 to ~275 ms to run
190
191 # -v accepts :ro or :rw for mount options
192 # also :z :Z selinux stuff
193
194 local script='
195 echo hi
196 whoami
197 pwd
198 ls -l /
199 echo
200 ls -l /app/data
201 echo
202 apk list
203
204 #ping www.google.com
205 nslookup google.com
206 echo
207
208 ip addr show
209 echo
210
211 #ping host.containers.internal
212 #echo
213
214 #ping www.google.com
215
216 nc google.com 80 <<"EOF"
217GET /
218EOF
219 '
220
221 local script='
222 #ls -l /home/udu/aports/main
223
224 whoami
225 pwd
226
227 abuild -f -r -C ~/aports/main/lua5.4 rootbld
228 '
229 # --userns=keep-id for mounts
230 time podman run --rm -it \
231 --privileged \
232 --userns=keep-id \
233 -v "$PWD/_tmp/mnt/data:/app/data:ro" \
234 -v "$PWD/../../alpinelinux/aports/main:/home/udu/aports/main:rw" \
235 aports-build:latest \
236 sh -c "$script"
237
238}
239
240save() {
241 local tar=_tmp/aports-oci.tar
242 rm -f -v $tar
243 podman save -o $tar aports-build:latest
244}
245
246extract-saved() {
247 local tar=_tmp/aports-oci.tar
248
249 tar --list < _tmp/aports-oci.tar
250 echo
251
252 ls -l --si $tar
253
254 local tmp=_tmp/aports-oci
255 rm -r -f $tmp
256 mkdir -p $tmp
257 pushd $tmp
258 tar -x < ../aports-oci.tar
259 popd
260}
261
262show-saved() {
263 tree -h _tmp/aports-oci
264}
265
266list() {
267 podman images | grep aports-build
268}
269
270test-rootless-overlay() {
271 # AH, this works with --mount! Cool!
272
273 unshare --user --map-root-user --mount -- bash -c '
274 dir=_tmp/overlay-test
275 mkdir -p $dir/{lower,upper,work,merged}
276 echo "lower" > $dir/lower/foo
277
278 # Try to mount as regular user
279 #
280 # permission denied
281 # how does podman do it? Test it out
282
283 mount -t overlay overlay \
284 -o lowerdir=$dir/lower,upperdir=$dir/upper,workdir=$dir/work \
285 $dir/merged
286
287 echo MERGED
288 ls -l $dir/merged
289 echo "modify" > $dir/merged/foo
290 cat $dir/merged/foo
291
292 tree $dir
293
294 echo LOWER
295 cat $dir/lower/foo
296 echo
297
298 echo UPPER
299 cat $dir/upper/foo
300 echo
301 '
302}
303
304task-five "$@"