From 9ed4ae9a598fbd818929b395f0f4b4215dd848d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Stefanik?= Date: Sat, 23 Dec 2023 07:11:31 +0100 Subject: [PATCH 01/13] Support reusing existing directory for multipass bootstrapping --- lib/generator.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/generator.py b/lib/generator.py index 82ecd1e..fff9191 100755 --- a/lib/generator.py +++ b/lib/generator.py @@ -32,6 +32,13 @@ class Generator(): self.tmp_dir = None self.external_dir = None + def reuse(self, tmpdir): + """ + Reuse a previously prepared bwrap environment for further stages. + """ + self.tmp_dir = tmpdir.path + self.external_dir = os.path.join(self.tmp_dir, 'external') + def prepare(self, tmpdir, using_kernel=False, kernel_bootstrap=False, target_size=0): """ Prepare basic media of live-bootstrap. @@ -39,8 +46,7 @@ class Generator(): / -- contains seed to allow steps to be built, containing custom scripts and stage0-posix """ - self.tmp_dir = tmpdir.path - self.external_dir = os.path.join(self.tmp_dir, 'external') + self.reuse(tmpdir) # We use ext3 here; ext4 actually has a variety of extensions that # have been added with varying levels of recency From 1481ad0d20a8e5952a76ce14e8771be8a2dcb7aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Stefanik?= Date: Sat, 23 Dec 2023 07:12:23 +0100 Subject: [PATCH 02/13] Do not try to create /dev nodes under chroot/bwrap --- steps/improve/populate_device_nodes.sh | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/steps/improve/populate_device_nodes.sh b/steps/improve/populate_device_nodes.sh index 35856e9..98ffc8d 100755 --- a/steps/improve/populate_device_nodes.sh +++ b/steps/improve/populate_device_nodes.sh @@ -15,19 +15,6 @@ test -c "/dev/urandom" || mknod -m 444 "/dev/urandom" c 1 9 test -c "/dev/ptmx" || mknod -m 666 "/dev/ptmx" c 5 2 test -c "/dev/tty" || mknod -m 666 "/dev/tty" c 5 0 -test -b "/dev/sda" || mknod -m 600 "/dev/sda" b 8 0 -test -b "/dev/sda1" || mknod -m 600 "/dev/sda1" b 8 1 -test -b "/dev/sda2" || mknod -m 600 "/dev/sda2" b 8 2 -test -b "/dev/sda3" || mknod -m 600 "/dev/sda3" b 8 3 -test -b "/dev/sdb" || mknod -m 600 "/dev/sdb" b 8 16 -test -b "/dev/sdb1" || mknod -m 600 "/dev/sdb1" b 8 17 -test -b "/dev/sdb2" || mknod -m 600 "/dev/sdb2" b 8 18 -test -b "/dev/sdb2" || mknod -m 600 "/dev/sdb3" b 8 19 -test -b "/dev/sdc" || mknod -m 600 "/dev/sdc" b 8 32 -test -b "/dev/sdc1" || mknod -m 600 "/dev/sdc1" b 8 33 -test -b "/dev/sdc2" || mknod -m 600 "/dev/sdc2" b 8 34 -test -b "/dev/sdc3" || mknod -m 600 "/dev/sdc3" b 8 35 - test -e "/dev/stdout" || ln -s "/proc/self/fd/1" "/dev/stdout" if mount --version >/dev/null 2>&1; then @@ -37,4 +24,16 @@ fi if [ "${CHROOT}" = False ]; then test -c "/dev/console" || mknod -m 666 "/dev/console" c 5 1 + test -b "/dev/sda" || mknod -m 600 "/dev/sda" b 8 0 + test -b "/dev/sda1" || mknod -m 600 "/dev/sda1" b 8 1 + test -b "/dev/sda2" || mknod -m 600 "/dev/sda2" b 8 2 + test -b "/dev/sda3" || mknod -m 600 "/dev/sda3" b 8 3 + test -b "/dev/sdb" || mknod -m 600 "/dev/sdb" b 8 16 + test -b "/dev/sdb1" || mknod -m 600 "/dev/sdb1" b 8 17 + test -b "/dev/sdb2" || mknod -m 600 "/dev/sdb2" b 8 18 + test -b "/dev/sdb2" || mknod -m 600 "/dev/sdb3" b 8 19 + test -b "/dev/sdc" || mknod -m 600 "/dev/sdc" b 8 32 + test -b "/dev/sdc1" || mknod -m 600 "/dev/sdc1" b 8 33 + test -b "/dev/sdc2" || mknod -m 600 "/dev/sdc2" b 8 34 + test -b "/dev/sdc3" || mknod -m 600 "/dev/sdc3" b 8 35 fi From f66f9efa2cf9ebfc4a6d89ea95fb6a2619ba23d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Stefanik?= Date: Sat, 23 Dec 2023 07:16:59 +0100 Subject: [PATCH 03/13] Update bwrap bootstrap code to match the simplify refactor --- rootfs.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/rootfs.py b/rootfs.py index 8641d02..e7fdb13 100755 --- a/rootfs.py +++ b/rootfs.py @@ -15,7 +15,6 @@ you can run bootstap inside chroot. import argparse import os -import shutil from lib.utils import run, run_as_root from lib.tmpdir import Tmpdir @@ -32,7 +31,7 @@ def create_configuration_file(args): config.write(f"CHROOT={args.chroot or args.bwrap}\n") config.write(f"UPDATE_CHECKSUMS={args.update_checksums}\n") config.write(f"JOBS={args.cores}\n") - config.write(f"INTERNAL_CI={args.internal_ci}\n") + config.write(f"INTERNAL_CI={args.internal_ci or False}\n") config.write(f"BARE_METAL={args.bare_metal}\n") if (args.bare_metal or args.qemu) and not args.kernel: if args.repo or args.external_sources: @@ -195,7 +194,7 @@ print(shutil.which('chroot')) run('bwrap', '--unshare-user', '--uid', '0', '--gid', '0', - '--unshare-net', + '--unshare-net' if args.external_sources else None, '--clearenv', '--setenv', 'PATH', '/usr/bin', '--bind', generator.tmp_dir, '/', @@ -206,19 +205,21 @@ print(shutil.which('chroot')) '--dev-bind', '/dev/urandom', '/dev/urandom', '--dev-bind', '/dev/ptmx', '/dev/ptmx', '--dev-bind', '/dev/tty', '/dev/tty', + '--tmpfs', '/dev/shm', + '--proc', '/proc', + '--bind', '/sys', '/sys', + '--tmpfs', '/tmp', init) - if not args.internal_ci or args.internal_ci == "pass2" or args.internal_ci == "pass3": - os.makedirs(os.path.join(generator.tmp_dir, 'stage2', 'steps'), exist_ok=True) - shutil.copy2(os.path.join('steps', 'bootstrap.cfg'), - os.path.join(generator.tmp_dir, 'stage2', 'steps', 'bootstrap.cfg')) + if args.internal_ci in ("pass2", "pass3"): + generator.reuse(tmpdir) run('bwrap', '--unshare-user', '--uid', '0', '--gid', '0', '--unshare-net' if args.external_sources else None, '--clearenv', '--setenv', 'PATH', '/usr/bin', - '--bind', os.path.join(generator.tmp_dir, "stage2"), '/', + '--bind', generator.tmp_dir, '/', '--dir', '/dev', '--dev-bind', '/dev/null', '/dev/null', '--dev-bind', '/dev/zero', '/dev/zero', From e9787b55c8f597ac08233705c84b5b51b964e511 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Stefanik?= Date: Sat, 23 Dec 2023 07:18:24 +0100 Subject: [PATCH 04/13] Add breakpoints between passes for INTERNAL_CI These are implemented as dummy jumps with a script that just exits with success. Since this script will be sourced, rather than called, this causes the bootstrap process to exit at that point. The breakpoints are conditional on INTERNAL_CI (we check for "pass1" because that's the only pass when script-generator runs, but the resulting effect is that each pass only bootstraps its own part of the manifest). --- steps/jump/break.sh | 1 + steps/manifest | 2 ++ 2 files changed, 3 insertions(+) create mode 100644 steps/jump/break.sh diff --git a/steps/jump/break.sh b/steps/jump/break.sh new file mode 100644 index 0000000..ca916d0 --- /dev/null +++ b/steps/jump/break.sh @@ -0,0 +1 @@ +exit 0 diff --git a/steps/manifest b/steps/manifest index 164ce2c..b5aed41 100644 --- a/steps/manifest +++ b/steps/manifest @@ -115,6 +115,7 @@ define: BUILD_LINUX = ( CHROOT == False || BUILD_KERNELS == True ) build: kexec-linux-1.0.0 ( BUILD_LINUX == True ) build: kexec-tools-2.0.22 ( BUILD_LINUX == True ) build: linux-4.9.10 ( BUILD_LINUX == True ) +jump: break ( INTERNAL_CI == pass1 ) jump: linux ( CHROOT == False ) improve: finalize_fhs build: musl-1.2.4 @@ -174,6 +175,7 @@ build: python-3.3.7 build: python-3.4.10 build: python-3.8.16 build: python-3.11.1 +jump: break ( INTERNAL_CI == pass1 ) # scripts are generated in pass1 build: gcc-10.4.0 build: binutils-2.41 build: gcc-13.1.0 From 2823e1632512b51bad7a92c3081bdb16b8856aad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Stefanik?= Date: Sat, 23 Dec 2023 07:20:33 +0100 Subject: [PATCH 05/13] Update CI workflows to match changes from simplify --- .github/workflows/bwrap.yml | 64 ++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 33 deletions(-) diff --git a/.github/workflows/bwrap.yml b/.github/workflows/bwrap.yml index dcbe1bd..a4d1c11 100644 --- a/.github/workflows/bwrap.yml +++ b/.github/workflows/bwrap.yml @@ -12,8 +12,8 @@ on: - master jobs: - sysa: - name: Run sysa under bubblewrap + pass1: + name: Run up to Linux build under bubblewrap runs-on: ubuntu-latest steps: - name: Install bubblewrap @@ -30,9 +30,8 @@ jobs: uses: actions/cache/restore@v3 with: path: | - sysa/distfiles - sysc/distfiles - key: cache-${{ hashFiles('sys*/*/sources') }} + externals/distfiles + key: cache-${{ hashFiles('steps/*/sources') }} - name: Get sources if: steps.cache.outputs.cache-hit != 'true' run: ./download-distfiles.sh @@ -41,9 +40,8 @@ jobs: uses: actions/cache/save@v3 with: path: | - sysa/distfiles - sysc/distfiles - key: cache-${{ hashFiles('sys*/*/sources') }} + externals/distfiles + key: cache-${{ hashFiles('steps/*/sources') }} - name: Run bootstrap run: ./rootfs.py --bwrap --external-sources --build-kernels --preserve --cores 2 --internal-ci pass1 - name: Archive created packages @@ -51,18 +49,18 @@ jobs: uses: actions/upload-artifact@v3 with: name: packages - path: tmp/sysa/usr/src/repo/** - - name: Tar sysc_image - run: tar -cf sysc_image.tar tmp/sysa/sysc_image/ - - name: Archive sysc_image + path: tmp/external/repo/** + - name: Tar pass1 image + run: tar -cf pass1_image.tar tmp + - name: Archive pass1_image uses: actions/upload-artifact@v3 with: - name: internal_sysc_image - path: sysc_image.tar + name: internal_pass1_image + path: pass1_image.tar - sysc1: - name: Run sysc (part 1) under bubblewrap - needs: sysa + pass2: + name: Run up to Python bootstrap under bubblewrap + needs: pass1 runs-on: ubuntu-latest steps: - name: Install bubblewrap @@ -74,24 +72,24 @@ jobs: # There is a strange bug(?) in nongnu, when you clone a git repository # against a commit != HEAD with depth=1, it errors out. fetch-depth: 0 - - name: Get sysc_image + - name: Get pass1_image uses: actions/download-artifact@v3 with: - name: internal_sysc_image - - name: Extract sysc_image - run: tar -xf sysc_image.tar + name: internal_pass1_image + - name: Extract pass1_image + run: tar -xf pass1_image.tar - name: Run bootstrap run: ./rootfs.py --bwrap --external-sources --build-kernels --preserve --cores 2 --internal-ci pass2 - name: Archive created packages if: always() # archive failed builds progress uses: actions/upload-artifact@v3 with: - name: internal_packages_sysc1 - path: tmp/sysa/sysc_image/usr/src/repo/** + name: internal_packages_pass2 + path: tmp/externals/repo/** - sysc2: - name: Run sysc (part 2) under bubblewrap - needs: sysc1 + pass3: + name: Run remaining builds under bubblewrap + needs: pass2 runs-on: ubuntu-latest steps: - name: Install bubblewrap @@ -103,18 +101,18 @@ jobs: # There is a strange bug(?) in nongnu, when you clone a git repository # against a commit != HEAD with depth=1, it errors out. fetch-depth: 0 - - name: Get sysc_image + - name: Get pass1_image uses: actions/download-artifact@v3 with: - name: internal_sysc_image - - name: Extract sysc_image - run: tar -xf sysc_image.tar + name: internal_pass1_image + - name: Extract pass1_image + run: tar -xf pass1_image.tar # By doing this, all packages that have already been compiled will come from the preseed. - name: Get packages repo progress uses: actions/download-artifact@v3 with: - name: internal_packages_sysc1 - path: tmp/sysa/sysc_image/usr/src/repo-preseeded/ + name: internal_packages_pass2 + path: tmp/externals/repo-preseeded/ - name: Run bootstrap run: ./rootfs.py --bwrap --external-sources --build-kernels --preserve --cores 2 --internal-ci pass3 - name: Archive created packages @@ -122,4 +120,4 @@ jobs: uses: actions/upload-artifact@v3 with: name: packages - path: tmp/sysa/sysc_image/usr/src/repo/** + path: tmp/externals/repo/** From 97f31072ce22e381b4fff3f8da74de1a2f5aebbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Stefanik?= Date: Sat, 23 Dec 2023 07:30:11 +0100 Subject: [PATCH 06/13] Add license information to break.sh Not that it's exactly copyrightable, being just "exit 0", but linter complains about it. --- steps/jump/break.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/steps/jump/break.sh b/steps/jump/break.sh index ca916d0..e6788ce 100644 --- a/steps/jump/break.sh +++ b/steps/jump/break.sh @@ -1 +1,7 @@ +#!/bin/bash +# +# SPDX-FileCopyrightText: 2023 Gábor Stefanik +# +# SPDX-License-Identifier: GPL-3.0-or-later + exit 0 From 2c6ac949746072f0ee4e396a40a58ab09fc39df6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Stefanik?= Date: Mon, 25 Dec 2023 10:21:49 +0100 Subject: [PATCH 07/13] Replace --clearenv with env - to support older bwrap This makes bwrap work on Debian 10. --- rootfs.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/rootfs.py b/rootfs.py index e7fdb13..c8bf7d0 100755 --- a/rootfs.py +++ b/rootfs.py @@ -191,11 +191,10 @@ print(shutil.which('chroot')) arch = stage0_arch_map.get(args.arch, args.arch) init = os.path.join(os.sep, 'bootstrap-seeds', 'POSIX', arch, 'kaem-optional-seed') - run('bwrap', '--unshare-user', + run('env', '-', 'bwrap', '--unshare-user', '--uid', '0', '--gid', '0', '--unshare-net' if args.external_sources else None, - '--clearenv', '--setenv', 'PATH', '/usr/bin', '--bind', generator.tmp_dir, '/', '--dir', '/dev', @@ -213,11 +212,10 @@ print(shutil.which('chroot')) if args.internal_ci in ("pass2", "pass3"): generator.reuse(tmpdir) - run('bwrap', '--unshare-user', + run('env', '-', 'bwrap', '--unshare-user', '--uid', '0', '--gid', '0', '--unshare-net' if args.external_sources else None, - '--clearenv', '--setenv', 'PATH', '/usr/bin', '--bind', generator.tmp_dir, '/', '--dir', '/dev', From 591959924fa8de282f3d11983de6cf19c50f5af0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Stefanik?= Date: Mon, 25 Dec 2023 11:04:18 +0100 Subject: [PATCH 08/13] Re-acquire missing sources before each CI pass --- .github/workflows/bwrap.yml | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/.github/workflows/bwrap.yml b/.github/workflows/bwrap.yml index a4d1c11..37de45d 100644 --- a/.github/workflows/bwrap.yml +++ b/.github/workflows/bwrap.yml @@ -78,6 +78,23 @@ jobs: name: internal_pass1_image - name: Extract pass1_image run: tar -xf pass1_image.tar + - name: Query cache for sources + id: cache + uses: actions/cache/restore@v3 + with: + path: | + externals/distfiles + key: cache-${{ hashFiles('steps/*/sources') }} + - name: Get sources + if: steps.cache.outputs.cache-hit != 'true' + run: ./download-distfiles.sh + - name: Cache sources + if: steps.cache.outputs.cache-hit != 'true' + uses: actions/cache/save@v3 + with: + path: | + externals/distfiles + key: cache-${{ hashFiles('steps/*/sources') }} - name: Run bootstrap run: ./rootfs.py --bwrap --external-sources --build-kernels --preserve --cores 2 --internal-ci pass2 - name: Archive created packages @@ -113,6 +130,23 @@ jobs: with: name: internal_packages_pass2 path: tmp/externals/repo-preseeded/ + - name: Query cache for sources + id: cache + uses: actions/cache/restore@v3 + with: + path: | + externals/distfiles + key: cache-${{ hashFiles('steps/*/sources') }} + - name: Get sources + if: steps.cache.outputs.cache-hit != 'true' + run: ./download-distfiles.sh + - name: Cache sources + if: steps.cache.outputs.cache-hit != 'true' + uses: actions/cache/save@v3 + with: + path: | + externals/distfiles + key: cache-${{ hashFiles('steps/*/sources') }} - name: Run bootstrap run: ./rootfs.py --bwrap --external-sources --build-kernels --preserve --cores 2 --internal-ci pass3 - name: Archive created packages From 63c0a5206749e34f6b37065dc2870eac51a0acde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Stefanik?= Date: Mon, 25 Dec 2023 11:09:51 +0100 Subject: [PATCH 09/13] Fix external & distfiles directory paths for CI --- .github/workflows/bwrap.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/bwrap.yml b/.github/workflows/bwrap.yml index 37de45d..8d40f8b 100644 --- a/.github/workflows/bwrap.yml +++ b/.github/workflows/bwrap.yml @@ -30,7 +30,7 @@ jobs: uses: actions/cache/restore@v3 with: path: | - externals/distfiles + distfiles key: cache-${{ hashFiles('steps/*/sources') }} - name: Get sources if: steps.cache.outputs.cache-hit != 'true' @@ -40,7 +40,7 @@ jobs: uses: actions/cache/save@v3 with: path: | - externals/distfiles + distfiles key: cache-${{ hashFiles('steps/*/sources') }} - name: Run bootstrap run: ./rootfs.py --bwrap --external-sources --build-kernels --preserve --cores 2 --internal-ci pass1 @@ -83,7 +83,7 @@ jobs: uses: actions/cache/restore@v3 with: path: | - externals/distfiles + distfiles key: cache-${{ hashFiles('steps/*/sources') }} - name: Get sources if: steps.cache.outputs.cache-hit != 'true' @@ -93,7 +93,7 @@ jobs: uses: actions/cache/save@v3 with: path: | - externals/distfiles + distfiles key: cache-${{ hashFiles('steps/*/sources') }} - name: Run bootstrap run: ./rootfs.py --bwrap --external-sources --build-kernels --preserve --cores 2 --internal-ci pass2 @@ -102,7 +102,7 @@ jobs: uses: actions/upload-artifact@v3 with: name: internal_packages_pass2 - path: tmp/externals/repo/** + path: tmp/external/repo/** pass3: name: Run remaining builds under bubblewrap @@ -129,13 +129,13 @@ jobs: uses: actions/download-artifact@v3 with: name: internal_packages_pass2 - path: tmp/externals/repo-preseeded/ + path: tmp/external/repo-preseeded/ - name: Query cache for sources id: cache uses: actions/cache/restore@v3 with: path: | - externals/distfiles + distfiles key: cache-${{ hashFiles('steps/*/sources') }} - name: Get sources if: steps.cache.outputs.cache-hit != 'true' @@ -145,7 +145,7 @@ jobs: uses: actions/cache/save@v3 with: path: | - externals/distfiles + distfiles key: cache-${{ hashFiles('steps/*/sources') }} - name: Run bootstrap run: ./rootfs.py --bwrap --external-sources --build-kernels --preserve --cores 2 --internal-ci pass3 @@ -154,4 +154,4 @@ jobs: uses: actions/upload-artifact@v3 with: name: packages - path: tmp/externals/repo/** + path: tmp/external/repo/** From 30fb367e7aaf8275c2064166efdb0f9737bc53ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Stefanik?= Date: Mon, 25 Dec 2023 17:43:31 +0100 Subject: [PATCH 10/13] Simplify bwrap setup code and support more than 3 passes --- rootfs.py | 59 ++++++++++++++++++++----------------------------------- 1 file changed, 21 insertions(+), 38 deletions(-) diff --git a/rootfs.py b/rootfs.py index c8bf7d0..18834ab 100755 --- a/rootfs.py +++ b/rootfs.py @@ -186,50 +186,33 @@ print(shutil.which('chroot')) run_as_root('env', '-i', 'PATH=/bin', chroot_binary, generator.tmp_dir, init) elif args.bwrap: + init = '/init' if not args.internal_ci or args.internal_ci == "pass1": generator.prepare(tmpdir, using_kernel=False) arch = stage0_arch_map.get(args.arch, args.arch) init = os.path.join(os.sep, 'bootstrap-seeds', 'POSIX', arch, 'kaem-optional-seed') - run('env', '-', 'bwrap', '--unshare-user', - '--uid', '0', - '--gid', '0', - '--unshare-net' if args.external_sources else None, - '--setenv', 'PATH', '/usr/bin', - '--bind', generator.tmp_dir, '/', - '--dir', '/dev', - '--dev-bind', '/dev/null', '/dev/null', - '--dev-bind', '/dev/zero', '/dev/zero', - '--dev-bind', '/dev/random', '/dev/random', - '--dev-bind', '/dev/urandom', '/dev/urandom', - '--dev-bind', '/dev/ptmx', '/dev/ptmx', - '--dev-bind', '/dev/tty', '/dev/tty', - '--tmpfs', '/dev/shm', - '--proc', '/proc', - '--bind', '/sys', '/sys', - '--tmpfs', '/tmp', - init) - - if args.internal_ci in ("pass2", "pass3"): + else: generator.reuse(tmpdir) - run('env', '-', 'bwrap', '--unshare-user', - '--uid', '0', - '--gid', '0', - '--unshare-net' if args.external_sources else None, - '--setenv', 'PATH', '/usr/bin', - '--bind', generator.tmp_dir, '/', - '--dir', '/dev', - '--dev-bind', '/dev/null', '/dev/null', - '--dev-bind', '/dev/zero', '/dev/zero', - '--dev-bind', '/dev/random', '/dev/random', - '--dev-bind', '/dev/urandom', '/dev/urandom', - '--dev-bind', '/dev/ptmx', '/dev/ptmx', - '--dev-bind', '/dev/tty', '/dev/tty', - '--tmpfs', '/dev/shm', - '--proc', '/proc', - '--bind', '/sys', '/sys', - '--tmpfs', '/tmp', - '/init') + + run('env', '-i', 'bwrap', '--unshare-user', + '--uid', '0', + '--gid', '0', + '--unshare-net' if args.external_sources else None, + '--setenv', 'PATH', '/usr/bin', + '--bind', generator.tmp_dir, '/', + '--dir', '/dev', + '--dev-bind', '/dev/null', '/dev/null', + '--dev-bind', '/dev/zero', '/dev/zero', + '--dev-bind', '/dev/random', '/dev/random', + '--dev-bind', '/dev/urandom', '/dev/urandom', + '--dev-bind', '/dev/ptmx', '/dev/ptmx', + '--dev-bind', '/dev/tty', '/dev/tty', + '--tmpfs', '/dev/shm', + '--proc', '/proc', + '--bind', '/sys', '/sys', + '--tmpfs', '/tmp', + init) elif args.bare_metal: if args.kernel: From 896c618bd1ebd67b708cb274eaca829b98f8ab2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Stefanik?= Date: Mon, 25 Dec 2023 18:34:04 +0100 Subject: [PATCH 11/13] Re-copy distfiles on generator.reuse() --- lib/generator.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/generator.py b/lib/generator.py index fff9191..1af4f98 100755 --- a/lib/generator.py +++ b/lib/generator.py @@ -38,6 +38,7 @@ class Generator(): """ self.tmp_dir = tmpdir.path self.external_dir = os.path.join(self.tmp_dir, 'external') + self.distfiles() def prepare(self, tmpdir, using_kernel=False, kernel_bootstrap=False, target_size=0): """ @@ -46,7 +47,8 @@ class Generator(): / -- contains seed to allow steps to be built, containing custom scripts and stage0-posix """ - self.reuse(tmpdir) + self.tmp_dir = tmpdir.path + self.external_dir = os.path.join(self.tmp_dir, 'external') # We use ext3 here; ext4 actually has a variety of extensions that # have been added with varying levels of recency From f67c7d114411dcde4e8f5c965381dbb3b4a0fa13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Stefanik?= Date: Mon, 25 Dec 2023 19:27:11 +0100 Subject: [PATCH 12/13] Tolerate externals/distfiles already existing (needed for CI) --- lib/generator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/generator.py b/lib/generator.py index 1af4f98..326101a 100755 --- a/lib/generator.py +++ b/lib/generator.py @@ -174,11 +174,11 @@ class Generator(): main_distfile_dir = os.path.join(self.external_dir, 'distfiles') if early_distfile_dir != main_distfile_dir: - os.makedirs(early_distfile_dir) + os.makedirs(early_distfile_dir, exist_ok=True) copy_no_network_distfiles(early_distfile_dir) if self.external_sources: - shutil.copytree(self.distfiles_dir, main_distfile_dir) + shutil.copytree(self.distfiles_dir, main_distfile_dir, dirs_exist_ok=True) else: os.mkdir(main_distfile_dir) copy_no_network_distfiles(main_distfile_dir) From fe9cb1222fd129e90b42ce9cce3d96cd766170b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Stefanik?= Date: Mon, 25 Dec 2023 22:41:44 +0100 Subject: [PATCH 13/13] Change pass2 -> pass3 transition to the same mechanism as pass1 -> pass2 Fixes pass3 prematurely reporting success and quitting, having built nothing. --- .github/workflows/bwrap.yml | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/.github/workflows/bwrap.yml b/.github/workflows/bwrap.yml index 8d40f8b..776ea20 100644 --- a/.github/workflows/bwrap.yml +++ b/.github/workflows/bwrap.yml @@ -98,11 +98,18 @@ jobs: - name: Run bootstrap run: ./rootfs.py --bwrap --external-sources --build-kernels --preserve --cores 2 --internal-ci pass2 - name: Archive created packages - if: always() # archive failed builds progress + if: failure() # archive failed builds progress uses: actions/upload-artifact@v3 with: name: internal_packages_pass2 path: tmp/external/repo/** + - name: Tar pass2 image + run: tar -cf pass2_image.tar tmp + - name: Archive pass2_image + uses: actions/upload-artifact@v3 + with: + name: internal_pass2_image + path: pass2_image.tar pass3: name: Run remaining builds under bubblewrap @@ -118,18 +125,12 @@ jobs: # There is a strange bug(?) in nongnu, when you clone a git repository # against a commit != HEAD with depth=1, it errors out. fetch-depth: 0 - - name: Get pass1_image + - name: Get pass2_image uses: actions/download-artifact@v3 with: - name: internal_pass1_image - - name: Extract pass1_image - run: tar -xf pass1_image.tar - # By doing this, all packages that have already been compiled will come from the preseed. - - name: Get packages repo progress - uses: actions/download-artifact@v3 - with: - name: internal_packages_pass2 - path: tmp/external/repo-preseeded/ + name: internal_pass2_image + - name: Extract pass2_image + run: tar -xf pass2_image.tar - name: Query cache for sources id: cache uses: actions/cache/restore@v3 @@ -150,7 +151,7 @@ jobs: - name: Run bootstrap run: ./rootfs.py --bwrap --external-sources --build-kernels --preserve --cores 2 --internal-ci pass3 - name: Archive created packages - if: always() # archive failed builds + if: always() # archive both failed and successful builds uses: actions/upload-artifact@v3 with: name: packages