This repository has been archived by the owner on Oct 2, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 61
492 lines (460 loc) · 19.7 KB
/
main.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
name: test suite
on:
pull_request: # all pull requests
push:
branches: [ master ] # all commits on master
schedule:
- cron: '0 2 * * 0' # every Sunday at 2:00am UTC (Saturday 7:00pm MST)
jobs:
main:
runs-on: ubuntu-22.04
timeout-minutes: 90
strategy:
fail-fast: false # Actions seems kind of flaky lately
matrix:
builder:
- ch-image
pack_fmt: [squash-mount, tar-unpack, squash-unpack]
keep_sudo: # if false, remove self from sudoers post-install/setup
- false
cache:
- enabled
include:
- builder: none
pack_fmt: squash-mount
keep_sudo: false
cache: disabled
- builder: docker
pack_fmt: tar-unpack
keep_sudo: true
cache: enabled
- builder: ch-image
pack_fmt: squash-mount
keep_sudo: false
cache: disabled
env:
CH_IMAGE_CACHE: ${{ matrix.cache }}
CH_TEST_BUILDER: ${{ matrix.builder }}
CH_TEST_TARDIR: /mnt/tarballs
CH_TEST_IMGDIR: /mnt/images
CH_TEST_PACK_FMT: ${{ matrix.pack_fmt }}
CH_TEST_PERMDIRS: /mnt/perms_test /run/perms_test
ch_prefix: /var/tmp
steps:
- uses: actions/checkout@v3
- name: early setup & validation
run: |
[[ -n $CH_TEST_BUILDER ]]
sudo timedatectl set-timezone America/Denver
sudo chmod 1777 /mnt /usr/local/src
echo "ch_makej=-j$(getconf _NPROCESSORS_ONLN)" >> $GITHUB_ENV
# Remove sbin directories from $PATH (see issue #43). Assume none of
# these are the first entry in $PATH.
echo "PATH=$PATH"
path_new=$PATH
for i in /sbin /usr/sbin /usr/local/sbin; do
path_new=${path_new/:$i/}
done
echo "path_new=$path_new"
echo "PATH=$path_new" >> $GITHUB_ENV
# Set sudo umask to something quite restrictive. The default is
# 0022, but we had a "make install" bug (issue #947) that was
# tickled by 0027, which is a better setting. For reasons I don’t
# understand, this only affects sudo, but since that’s what we want,
# I left it. Note there are a few dependency installs below that
# have similar permissions bugs; these relax the umask on a
# case-by-case basis.
sudo sed -i -E 's/^UMASK\s+022/UMASK 0077/' /etc/login.defs
fgrep UMASK /etc/login.defs
- name: print starting environment
run: |
echo builder: ${{ matrix.builder }}
echo pack_fmt: ${{ matrix.pack_fmt }}
echo keep_sudo: ${{ matrix.keep_sudo }}
echo cache: ${{ matrix.cache }}
uname -a
lsb_release -a
id
pwd
getconf _NPROCESSORS_ONLN
free -m
df -h
locale -a
timedatectl
env | egrep '^(PATH|USER)='
env | egrep '^(ch|CH)_'
[[ $PATH != */usr/local/sbin* ]] # verify sbin removal; see above
printf 'umask for %s: ' $USER && umask
printf 'umask under sudo: ' && sudo sh -c umask
[[ $(umask) = 0022 ]]
[[ $(sudo sh -c umask) = 0077 ]]
- name: lines of code
if: ${{ matrix.builder == 'none' }}
run: |
sudo apt-get install cloc
misc/loc
- name: install/configure dependencies, all
run: |
# configure doesn’t tell us about these.
sudo apt-get install attr pigz pv
# configure does tell us about these.
sudo apt-get install bats squashfs-tools
# Track newest Sphinx in case it breaks things.
# FIXME: pip yells about docutils 0.19 so ask for latest 0.18
sudo su -c 'umask 0022 && pip3 install docutils==0.18.1 sphinx sphinx-rtd-theme sphinx-reredirects'
# Use newest shellcheck.
cd /usr/local/src
wget -nv https://github.com/koalaman/shellcheck/releases/download/stable/shellcheck-stable.linux.x86_64.tar.xz
tar xf shellcheck-stable.linux.x86_64.tar.xz
sudo mv shellcheck-stable/shellcheck /usr/local/bin
which shellcheck
shellcheck --version
- name: install/configure dependencies, ch-image
if: ${{ matrix.builder == 'ch-image' }}
run: |
# Use most current packages b/c new versions sometimes break things.
sudo sh -c 'umask 0022 && pip3 install lark requests wheel'
# Configure Git and friends for build cache.
if [[ $CH_IMAGE_CACHE = enabled ]]; then
# Git
command -v git
git --version
git config --global user.name 'Judit Polgár'
git config --global user.email judit@example.com
git config --global core.excludesfile ~/.gitignore
echo __ch-test_ignore__ >> ~/.gitignore
# Graphviz
sudo apt-get install -y graphviz
dot -V
# git2dot
sudo sh -c 'umask 0022 && pip install python-dateutil'
git clone https://github.com/jlinoff/git2dot.git ~/git2dot
cd ~/git2dot
git checkout $(git tag | sort -Vr | head -1)
sudo cp -a git2dot.py /usr/local/bin
command -v git2dot.py
git2dot.py --version
fi
- name: install libsquashfuse
if: ${{ matrix.pack_fmt == 'squash-mount' }}
run: |
set -x
sudo apt-get install -y libfuse3-dev
cd /usr/local/src
git clone https://github.com/vasi/squashfuse.git
cd squashfuse
# Check out the latest release.
git checkout $(git tag -l '[0-9].*' | sort -V | tail -1)
./autogen.sh
./configure --prefix=/usr/local
make
sudo sh -c 'umask 0022 && make install'
sudo ldconfig
# Unset setuid on all fusermount3(1) on the system.
sudo chmod -v u-s /usr/bin/fusermount*
ls -lh $(command -v fusermount3)
[[ ! -u $(command -v fusermount3) ]]
- name: install musl and friends
if: ${{ matrix.pack_fmt == 'tar-unpack' }}
run: |
sudo apt-get install -y musl-tools
# At present we use argp to parse command line arguments. This is
# not portable; it’s a glibc extension (see #1260). Thus, install a
# standalone argp.
cd /usr/local/src
git clone --depth=1 https://github.com/ericonr/argp-standalone.git
cd argp-standalone
autoreconf --force --install
CC=musl-gcc ./configure
make $ch_makej
sudo install -D -m644 argp.h /usr/include/x86_64-linux-musl/argp.h
sudo install -D -m755 libargp.a /usr/lib/x86_64-linux-musl/libargp.a
# musl-gcc does not install Linux headers. This is a bad kludge.
# See: https://www.openwall.com/lists/musl/2017/11/23/1
sudo ln -s ../linux ../asm-generic ../x86_64-linux-gnu \
/usr/include/x86_64-linux-musl/
sudo ln -s x86_64-linux-gnu/asm /usr/include/x86_64-linux-musl/
- name: disable bundled lark, ch-image
if: ${{ matrix.builder == 'ch-image'
&& matrix.pack_fmt == 'squash-mount'
&& matrix.cache == 'disabled' }}
run: |
set -x
# no install, disable
./autogen.sh --no-lark
./configure --disable-bundled-lark --prefix=$ch_prefix/from-git
fgrep '"lark" module ... external' config.log
! test -f ./lib/lark/lark.py
make $ch_makej
sudo make $ch_makej install
[[ $(bin/ch-image -v --dependencies) = 'lark path: /usr/local/lib/python3.10/dist-packages/lark/__init__.py' ]]
[[ $($ch_prefix/from-git/bin/ch-image -v --dependencies) = 'lark path: /usr/local/lib/python3.10/dist-packages/lark/__init__.py' ]]
make clean
# install, disable
./autogen.sh
./configure --disable-bundled-lark --prefix=$ch_prefix/from-git
fgrep '"lark" module ... bundled' config.log
test -f ./lib/lark/lark.py
make $ch_makej
sudo make $ch_makej install
[[ $(bin/ch-image -v --dependencies) = 'lark path: /home/runner/work/charliecloud/charliecloud/lib/lark/__init__.py' ]]
[[ $($ch_prefix/from-git/bin/ch-image -v --dependencies) = 'lark path: /usr/local/lib/python3.10/dist-packages/lark/__init__.py' ]]
make clean
# no install, enable: build fails, untested
# install, enable: normal configuration, remainder of CI
- name: build/install from Git
run: |
./autogen.sh
# Remove Autotools to make sure everything works without them.
sudo apt-get remove autoconf automake
# Configure and verify output.
#
# We want to support any standard libc, so build against musl for
# some cases:
#
# squash-mount: glibc; libsquashfuse and libfuse3 are built with it
# squash-unpack: glibc; to test ch-fromhost which assumes glibc
# tar-unpack: musl
#
# See PR #1258, which is a FTBFS for musl. Other build steps in this
# workflow also use glibc.
if [[ $CH_TEST_PACK_FMT == tar-unpack ]]; then
export CC=musl-gcc
# GNU ldd(1) doesn’t work on musl binaries.
LDD='/lib/ld-musl-x86_64.so.1 --list'
else
LDD=ldd
fi
# Go wild with install directories to make sure it works (see #683).
# We do have a normal install below.
./configure --prefix=$ch_prefix/from-git \
--datarootdir=$ch_prefix/from-git_dataroot \
--libexecdir=$ch_prefix/from-git_libexec \
--libdir=$ch_prefix/from-git_lib \
--mandir=$ch_prefix/from-git_man \
--docdir=$ch_prefix/from-git_doc \
--htmldir=$ch_prefix/from-git_html
set -x
fgrep 'documentation: yes' config.log
[[ $CH_TEST_BUILDER = docker ]] && command -v docker
if [[ $CH_TEST_BUILDER = ch-image ]]; then
fgrep 'with ch-image(1): yes' config.log
fgrep '"lark" module ... bundled' config.log
test -f ./lib/lark/lark.py
fi
fgrep 'recommended tests, tar-unpack mode: yes' config.log
fgrep 'recommended tests, squash-unpack mode: yes' config.log
if [[ $CH_TEST_PACK_FMT = squash-mount ]]; then
fgrep 'recommended tests, squash-mount mode: yes' config.log
fgrep 'internal SquashFS mounting ... yes' config.log
else
fgrep 'recommended tests, squash-mount mode: no' config.log
fgrep 'internal SquashFS mounting ... no' config.log
fi
set +x
# Build and install.
make $ch_makej
sudo make $ch_makej install
$LDD bin/ch-run
bin/ch-run --version
$LDD $ch_prefix/from-git/bin/ch-run
$ch_prefix/from-git/bin/ch-run --version
# Ensure bundled Lark in tarball.
make $ch_makej dist
tar tf charliecloud-*.tar.gz | fgrep /lib/lark/lark.py
- name: late setup & validation, ch-image
if: ${{ matrix.builder == 'ch-image' }}
run: |
set -x
[[ $(bin/ch-image gestalt python-path) = /usr/bin/python3 ]]
[[ $(bin/ch-image -v --dependencies) = "lark path: /home/runner/work/charliecloud/charliecloud/lib/lark/__init__.py" ]]
[[ $($ch_prefix/from-git/bin/ch-image gestalt python-path) = /usr/bin/python3 ]]
[[ $($ch_prefix/from-git/bin/ch-image -v --dependencies) = "lark path: /var/tmp/from-git_lib/charliecloud/lark/__init__.py" ]]
- name: late setup & validation, all
run: |
bin/ch-test --is-pedantic all
bin/ch-test --is-sudo all
- name: make filesystem permissions fixtures
run: |
bin/ch-test mk-perm-dirs
- name: start local registry, ch-image
if: ${{ matrix.builder == 'ch-image' }}
# See HOWTO in Google Docs for details.
run: |
set -x
mkdir ~/registry-etc
cp test/registry-config.yml ~/registry-etc/config.yml
cd ~/registry-etc
openssl req -batch -subj '/C=US/ST=NM/L=LA/O=LANL/CN=localhost' \
-newkey rsa:4096 -nodes -sha256 -x509 -days 36500 \
-keyout localhost.key -out localhost.crt
#openssl x509 -text -noout -in localhost.crt
sudo apt-get install apache2-utils
htpasswd -Bbn charlie test > ./htpasswd
diff -u <(docker run --rm registry:2 \
cat /etc/docker/registry/config.yml) \
config.yml || true
docker run -d --rm -p 127.0.0.1:5000:5000 \
-v ~/registry-etc:/etc/docker/registry registry:2
docker ps -a
- name: build/install from tarball
run: |
# Create and unpack tarball. The wildcard saves us having to put the
# version in a variable. This assumes there isn’t already a tarball
# or unpacked directory in $ch_prefix, which is true on the clean
# VMs GitHub gives us. Note that cd fails if it gets more than one
# argument, which helps, but this is probably kind of brittle.
make $ch_makej dist
mv charliecloud-*.tar.gz $ch_prefix
cd $ch_prefix
tar xf charliecloud-*.tar.gz
rm charliecloud-*.tar.gz # else cd fails with “too many arguments”
cd charliecloud-*
pwd
# Configure and verify output.
./configure --prefix=$ch_prefix/from-tarball
set -x
fgrep 'documentation: yes' config.log
[[ $CH_TEST_BUILDER = buildah* ]] && command -v buildah
[[ $CH_TEST_BUILDER = docker ]] && command -v docker
[[ $CH_TEST_BUILDER = ch-image ]] && fgrep 'with ch-image(1): yes' config.log
fgrep 'recommended tests, tar-unpack mode: yes' config.log
fgrep 'recommended tests, squash-unpack mode: yes' config.log
if [[ ${{ matrix.pack_fmt }} = squash-mount ]]; then
fgrep 'recommended tests, squash-mount mode: yes' config.log
fgrep 'internal SquashFS mounting ... yes' config.log
else
fgrep 'recommended tests, squash-mount mode: no' config.log
fgrep 'internal SquashFS mounting ... no' config.log
fi
set +x
# Build and install.
make $ch_makej
sudo make $ch_makej install
bin/ch-run --version
$ch_prefix/from-tarball/bin/ch-run --version
- name: configure sudo to user root, group non-root
if: ${{ matrix.keep_sudo }}
run: |
sudo sed -Ei 's/=\(ALL\)/=(ALL:ALL)/g' /etc/sudoers.d/runner
sudo cat /etc/sudoers.d/runner
- name: remove sudo
if: ${{ ! matrix.keep_sudo }}
run: |
sudo rm /etc/sudoers.d/runner
! sudo echo hello
- name: run test suite (Git WD, standard)
run: |
bin/ch-test all
# Validate that “rootemu” test phase didn’t run (skipped by default
# on standard scope).
[[ $(cat /tmp/ch-test.tmp.$USER/rootemu) = no ]]
- name: run root emulation phase
if: ${{ matrix.builder == 'ch-image'
&& matrix.pack_fmt == 'squash-mount'
&& matrix.cache == 'enabled' }}
run: |
# We only really need to run the root emulation tests once in CI.
# ch-image with an enabled cache is required for these unit tests.
# Since all CI tests that use ch-image with an enabled cache take
# roughly the same amount of time, we arbitrarily chose squash-mount
# as the pack format.
bin/ch-test rootemu
# Validate that “rootemu” test phase ran.
[[ $(cat /tmp/ch-test.tmp.$USER/rootemu) = yes ]]
- name: run test suite (installed from Git WD, standard)
if: ${{ matrix.builder == 'ch-image'
&& matrix.pack_fmt == 'squash-mount'
&& matrix.cache == 'enabled' }}
run: |
$ch_prefix/from-git/bin/ch-test all
[[ $(cat /tmp/ch-test.tmp.$USER/rootemu) = no ]]
- name: run test suite (installed from tarball, standard)
if: ${{ matrix.builder == 'ch-image'
&& matrix.pack_fmt == 'squash-mount'
&& matrix.cache == 'enabled' }}
run: |
$ch_prefix/from-tarball/bin/ch-test all
[[ $(cat /tmp/ch-test.tmp.$USER/rootemu) = no ]]
- name: uninstall from tarball
if: ${{ matrix.keep_sudo }}
run: |
cd $ch_prefix/charliecloud-*
sudo make uninstall
diff -u - <(find $ch_prefix/from-tarball | sort) <<'EOF'
/var/tmp/from-tarball
/var/tmp/from-tarball/bin
/var/tmp/from-tarball/lib
/var/tmp/from-tarball/libexec
/var/tmp/from-tarball/share
/var/tmp/from-tarball/share/doc
/var/tmp/from-tarball/share/man
/var/tmp/from-tarball/share/man/man1
/var/tmp/from-tarball/share/man/man7
EOF
- name: rebuild with most things --disable’d
if: ${{ matrix.builder == 'docker' }}
run: |
make distclean
./configure --prefix=/doesnotexist \
--disable-html --disable-man --disable-ch-image
set -x
fgrep 'HTML documentation ... no' config.log
fgrep 'man pages ... no' config.log
fgrep 'ch-image(1) ... no' config.log
fgrep 'with ch-image(1): no' config.log
# This CI test requires Docker, but the “configure” script doesn’t
# check for Docker, so we do it ourselves with “command -v”.
command -v docker
fgrep 'more complete tests: no' config.log
set +x
# Build.
make $ch_makej
bin/ch-run --version
- name: run test suite (Git WD, standard)
if: ${{ matrix.builder == 'docker' }}
run: |
bin/ch-test all
[[ $(cat /tmp/ch-test.tmp.$USER/rootemu) = no ]]
- name: remove non-essential dependencies
if: ${{ matrix.builder == 'docker' }}
run: |
set -x
# This breaks lots of dependencies unrelated to our build but YOLO.
sudo dpkg --remove --force-depends \
pigz \
pv \
python3-requests \
squashfs-tools
sudo pip3 uninstall -y sphinx sphinx-rtd-theme
if [[ ${{ matrix.pack_fmt }} = squash-mount ]]; then
( cd /usr/local/src/squashfuse && sudo make uninstall )
fi
! python3 -c 'import requests'
! python3 -c 'import lark'
- name: rebuild
if: ${{ matrix.builder == 'docker' }}
run: |
make distclean
./configure --prefix=/doesnotexist
set -x
fgrep 'documentation: no' config.log
command -v docker
fgrep 'more complete tests: no' config.log
fgrep 'recommended tests, squash-mount mode: no' config.log
set +x
# Build and install.
make $ch_makej
bin/ch-run --version
- name: run test suite (Git WD, standard)
if: ${{ matrix.builder == 'docker' }}
run: |
bin/ch-test all
[[ $(cat /tmp/ch-test.tmp.$USER/rootemu) = no ]]
- name: print ending environment
if: ${{ always() }}
run: |
free -m
df -h
du -sch $CH_TEST_TARDIR/* || true
du -sch $CH_TEST_IMGDIR/* || true