This commit is contained in:
Kevin Nause 2026-02-14 10:45:27 +11:00 committed by GitHub
commit 821e9b4761
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 102 additions and 5 deletions

6
.dockerignore Normal file
View file

@ -0,0 +1,6 @@
# SPDX-FileCopyrightText: 2024 Lance Vick <lance@vick.house>
#
# SPDX-License-Identifier: GPL-3.0-or-later
!target

57
Dockerfile Normal file
View file

@ -0,0 +1,57 @@
# SPDX-FileCopyrightText: 2024 Lance Vick <lance@vick.house>
# SPDX-FileCopyrightText: 2025 Kevin Nause <kevin@nause.engineering>
#
# SPDX-License-Identifier: GPL-3.0-or-later
ARG ARCH=x86
ARG USER=user
ARG UID=1000
ARG GID=1000
ARG HOME=/home/${USER}
FROM scratch AS build
ARG TARGET
ARG INIT
COPY ${TARGET} /
FROM build AS build-aarch64
RUN ["/bootstrap-seeds/POSIX/AArch64/kaem-optional-seed"]
FROM build AS build-amd64
RUN ["/bootstrap-seeds/POSIX/AMD64/kaem-optional-seed"]
FROM build AS build-riscv32
RUN ["/bootstrap-seeds/POSIX/riscv32/kaem-optional-seed"]
FROM build AS build-riscv64
RUN ["/bootstrap-seeds/POSIX/riscv64/kaem-optional-seed"]
FROM build AS build-x86
RUN ["/bootstrap-seeds/POSIX/x86/kaem-optional-seed"]
FROM build-${ARCH} AS install
ARG USER
ARG UID
ARG GID
ARG HOME
ENV PATH=/bin:/usr/sbin:/usr/bin
RUN set -eu; \
rm -rf /usr/lib/python*/__pycache__; \
mkdir -p /rootfs/etc /rootfs/${HOME}; \
cp -R $(ls -d /etc/* | grep -v '\(resolv.conf\|hosts\)') /rootfs/etc/; \
cp -R lib usr bin var /rootfs/; \
echo "${USER}:x:${GID}:" > /rootfs/etc/group; \
echo "${USER}:x:${UID}:${GID}::${HOME}:/bin/bash" > /rootfs/etc/passwd; \
find /rootfs -exec touch -hcd "@0" "{}" +
FROM scratch AS package
ARG UID
ARG GID
COPY --from=install /rootfs /
USER ${UID}:${GID}
ENTRYPOINT ["/bin/bash"]
ENV TZ=UTC
ENV LANG=C.UTF-8
ENV SOURCE_DATE_EPOCH=1
ENV KCONFIG_NOTIMESTAMP=1
ENV PS1="bootstrap$ "

View file

@ -33,8 +33,8 @@ Without using Python:
passing it to ``rootfs.py```). passing it to ``rootfs.py```).
1. ``git clone https://github.com/fosslinux/live-bootstrap`` 1. ``git clone https://github.com/fosslinux/live-bootstrap``
2. ``git submodule update --init --recursive`` 2. ``git submodule update --init --recursive``
3. Consider whether you are going to run this in a chroot, in QEMU, or on bare 3. Consider whether you are going to run this in a chroot, in QEMU, on bare
metal. (All of this *can* be automated, but not in a trustable way. See metal, or docker. (All of this *can* be automated, but not in a trustable way. See
further below.) further below.)
a. **chroot:** Create a directory where the chroot will reside, run a. **chroot:** Create a directory where the chroot will reside, run
@ -73,6 +73,15 @@ Without using Python:
(``-nic user,model=e1000``), and ``-machine kernel-irqchip=split``. (``-nic user,model=e1000``), and ``-machine kernel-irqchip=split``.
c. **Bare metal:** Follow the same steps as QEMU, but the disks need to be c. **Bare metal:** Follow the same steps as QEMU, but the disks need to be
two different *physical* disks, and boot from the first disk. two different *physical* disks, and boot from the first disk.
d. **Docker:** Follow the same steps as chroot. To debug build errors, see
[docker buildx debug](https://docs.docker.com/reference/cli/docker/buildx/debug/).
```bash
DOCKER_BUILDKIT=1 BUILDX_EXPERIMENTAL=1 \
docker buildx debug --invoke /bin/sh build \
--build-arg=ARCH=x86 --build-arg=TARGET=target/ --build-arg=SOURCE_DATE_EPOCH=1 \
--progress=auto --platform=linux/amd64 --target=install --tag=live-bootstrap-debug .
```
Mirrors Mirrors
------- -------

View file

@ -13,6 +13,8 @@ you can run bootstap inside chroot.
# SPDX-FileCopyrightText: 2021 Melg Eight <public.melg8@gmail.com> # SPDX-FileCopyrightText: 2021 Melg Eight <public.melg8@gmail.com>
# SPDX-FileCopyrightText: 2021-23 Samuel Tyler <samuel@samuelt.me> # SPDX-FileCopyrightText: 2021-23 Samuel Tyler <samuel@samuelt.me>
# SPDX-FileCopyrightText: 2023-24 Gábor Stefanik <netrolller.3d@gmail.com> # SPDX-FileCopyrightText: 2023-24 Gábor Stefanik <netrolller.3d@gmail.com>
# SPDX-FileCopyrightText: 2024 Lance Vick <lance@vick.house>
# SPDX-FileCopyrightText: 2025 Kevin Nause <kevin@nause.engineering>
import argparse import argparse
import os import os
@ -34,7 +36,7 @@ def create_configuration_file(args):
config.write(f"ARCH={args.arch}\n") config.write(f"ARCH={args.arch}\n")
config.write(f"ARCH_DIR={stage0_arch_map.get(args.arch, args.arch)}\n") config.write(f"ARCH_DIR={stage0_arch_map.get(args.arch, args.arch)}\n")
config.write(f"FORCE_TIMESTAMPS={args.force_timestamps}\n") config.write(f"FORCE_TIMESTAMPS={args.force_timestamps}\n")
config.write(f"CHROOT={args.chroot or args.bwrap}\n") config.write(f"CHROOT={args.chroot or args.bwrap or args.docker}\n")
config.write(f"UPDATE_CHECKSUMS={args.update_checksums}\n") config.write(f"UPDATE_CHECKSUMS={args.update_checksums}\n")
config.write(f"JOBS={args.cores}\n") config.write(f"JOBS={args.cores}\n")
config.write(f"SWAP_SIZE={args.swap}\n") config.write(f"SWAP_SIZE={args.swap}\n")
@ -75,6 +77,8 @@ def main():
action="store_true") action="store_true")
parser.add_argument("-bw", "--bwrap", help="Run inside a bwrap sandbox", parser.add_argument("-bw", "--bwrap", help="Run inside a bwrap sandbox",
action="store_true") action="store_true")
parser.add_argument("-do", "--docker", help="Run inside a docker build",
action="store_true")
parser.add_argument("-t", "--target", help="Target directory", parser.add_argument("-t", "--target", help="Target directory",
default="target") default="target")
parser.add_argument("--tmpfs", help="Use a tmpfs on target", parser.add_argument("--tmpfs", help="Use a tmpfs on target",
@ -140,15 +144,17 @@ def main():
count += 1 count += 1
if args.bwrap: if args.bwrap:
count += 1 count += 1
if args.docker:
count += 1
if args.bare_metal: if args.bare_metal:
count += 1 count += 1
return count return count
if check_types() > 1: if check_types() > 1:
raise ValueError("No more than one of qemu, chroot, bwrap, bare metal" raise ValueError("No more than one of qemu, chroot, bwrap, docker, bare metal"
"may be used.") "may be used.")
if check_types() == 0: if check_types() == 0:
raise ValueError("One of qemu, chroot, bwrap, or bare metal must be selected.") raise ValueError("One of qemu, chroot, bwrap, docker, or bare metal must be selected.")
# Arch validation # Arch validation
if args.arch != "x86": if args.arch != "x86":
@ -171,6 +177,9 @@ def main():
else: else:
args.target_size = 0 args.target_size = 0
if args.docker:
args.external_sources = True
# Swap file size validation # Swap file size validation
if args.qemu or args.bare_metal: if args.qemu or args.bare_metal:
args.swap = (int(str(args.swap).rstrip('gGmM')) * args.swap = (int(str(args.swap).rstrip('gGmM')) *
@ -250,6 +259,22 @@ print(shutil.which('chroot'))
run_as_root('env', '-i', 'PATH=/bin', chroot_binary, generator.target_dir, init, run_as_root('env', '-i', 'PATH=/bin', chroot_binary, generator.target_dir, init,
cleanup=cleanup) cleanup=cleanup)
elif args.docker:
generator.prepare(target, 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')
target_rel = os.path.relpath(generator.target_dir, os.getcwd())
run('env', '-i', 'DOCKER_BUILDKIT=1',
'docker', 'build',
'--build-arg=ARCH='+ arch,
'--build-arg=TARGET=' + target_rel,
'--build-arg=SOURCE_DATE_EPOCH=1',
'--progress=auto',
'--platform=linux/amd64,linux/arm64,linux/i386,linux/riscv64',
'--target=package',
'--tag=live-bootstrap-' + arch,
'.')
elif args.bwrap: elif args.bwrap:
init = '/init' init = '/init'
if not args.internal_ci or args.internal_ci == "pass1": if not args.internal_ci or args.internal_ci == "pass1":