mrrl-containers

MRRL version of container scripts
git clone https://ccx.te2000.cz/git/mrrl-containers
Log | Files | Refs

commit 00055f0322d33a0c18902daf71202ded2cf82c1f
parent 2250aae515a3b4b1f777e637853435b5e9f09ab7
Author: Jan Pobříslo <ccx@te2000.cz>
Date:   Thu, 16 Dec 2021 13:27:55 +0000

scripts to run in the sysroot container directly without going through s6 services
Diffstat:
Asbin/container_sysroot_run | 43+++++++++++++++++++++++++++++++++++++++++++
Asbin/pidns_run | 73+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mservice_scripts/sysroot/run | 4+++-
Mzsh-functions/confz_containers_init | 23+++++++++++++++++++++++
Mzsh-functions/confz_site_containers_init | 12++++++++++++
5 files changed, 154 insertions(+), 1 deletion(-)

diff --git a/sbin/container_sysroot_run b/sbin/container_sysroot_run @@ -0,0 +1,43 @@ +#!/command/execlineb -s0 +s6-envdir env +multisubstitute { + importas -i -u CONTAINER_NAME CONTAINER_NAME + importas -i -u CONTAINER_USER CONTAINER_USER +} +backtick -in CONTAINER_USER_HOME { homeof $CONTAINER_USER } +multisubstitute { + importas -i -u CONTAINER_USER_HOME CONTAINER_USER_HOME + define CONTAINER_TMPFS /run/containers/${CONTAINER_NAME}.sysroot + define -s tmpfs_dirs "home run tmp inbox run/inbox tmp/.X11-unix" +} + +getpid NS_PID +foreground { + importas -i NS_PID NS_PID + if { test -d /run/cgroup2 } + if { mkdir -p /run/cgroup2/containers/${CONTAINER_USER}/${CONTAINER_NAME} } + redirfd -w 1 /run/cgroup2/containers/${CONTAINER_USER}/${CONTAINER_NAME}/cgroup.procs + printf "%s" ${NS_PID} +} + +if { touch ${CONTAINER_TMPFS}.lockfile } +s6-setlock -n ${CONTAINER_TMPFS}.lockfile +if { rm -rf ${CONTAINER_TMPFS} } +if { mkdir -p ${CONTAINER_TMPFS}/${tmpfs_dirs} } +if { chmod 1770 ${CONTAINER_TMPFS}/${tmpfs_dirs} } +if { chown root:${CONTAINER_USER} ${CONTAINER_TMPFS}/${tmpfs_dirs} } +if { mount -a --fstab data/fstab } + +# Put UID/GID/GIDLIST into environment for use by s6-applyuidgid below +s6-envuidgid ${CONTAINER_USER} + +#env +# NS_EXTRA="if { mount -o bind,ro /etc/passwd etc/passwd } if { mount -o bind,ro /etc/group etc/group }" + +emptyenv -c +pidns_run +ns_run data/root +/mnt/ns/bin/s6-applyuidgid -U +env HOME=/root +$@ + diff --git a/sbin/pidns_run b/sbin/pidns_run @@ -0,0 +1,73 @@ +#!/usr/bin/env python3 +import sys +import os +import os.path +import ctypes +import fcntl + +libc = ctypes.CDLL(None, use_errno=True) +CLONE_NEWPID = 0x20000000 + + +def nonblock_cloexec(fd): + fcntl.fcntl( + fd, + fcntl.F_SETFD, + fcntl.fcntl(fd, fcntl.F_GETFD) | os.O_NONBLOCK | fcntl.FD_CLOEXEC, + ) + + +def exit_status(status): + sig = status & 0xff + ret = status >> 8 + if sig: + raise SystemExit(128 + sig) + if ret >= 128 + raise SystemExit(128) + raise SystemExit(ret) + + +def main(argv): + (parent_rfd, parent_wfd) = os.pipe() + nonblock_cloexec(read_fd) + nonblock_cloexec(write_fd) + if libc.unshare(CLONE_NEWPID) != 0: + raise OSError(ctypes.get_errno()) + fork_pid = os.fork() + if fork_pid: + # child + os.close(parent_wfd) + fork2_pid = os.fork() + if fork2_pid: + # child + if argv[1][0] == '/': + os.execve(argv[1], argv[1:]) + for d in os.environ['PATH'].split(':'): + try: + os.execv(os.path.join(d, argv[1]), argv[1:]) + except FileNotFoundError: + continue + raise SystemExit(127) + else: + # parent + rlist, wlist, elist = (parent_rfd), (), () + while True: + (pid, status) = os.waitpid(0, os.WNOHANG) + if pid: + exit_status(status) + try: + r, w, x = select.select(rlist, wlist, elist, timeout=1.0) + except select.error as e: + code, msg = e.args + # We might get interrupted by SIGCHLD here + if code != errno.EINTR: + raise + else: + # parent + os.close(parent_rfd) + (pid, status) = os.waitpid(fork_pid) + exit_status(status) + + +if __name__ == '__main__': + main(sys.argv) diff --git a/service_scripts/sysroot/run b/service_scripts/sysroot/run @@ -1,4 +1,4 @@ -#!/command/execlineb +#!/command/execlineb -P s6-envdir env multisubstitute { importas -i -u CONTAINER_NAME CONTAINER_NAME @@ -20,6 +20,8 @@ foreground { printf "%s" ${NS_PID} } +if { touch ${CONTAINER_TMPFS}.lockfile } +s6-setlock -n ${CONTAINER_TMPFS}.lockfile if { rm -rf ${CONTAINER_TMPFS} } if { mkdir -p ${CONTAINER_TMPFS}/${tmpfs_dirs} } if { chmod 1770 ${CONTAINER_TMPFS}/${tmpfs_dirs} } diff --git a/zsh-functions/confz_containers_init b/zsh-functions/confz_containers_init @@ -756,6 +756,29 @@ confz_container_alpine_image_check() { root=$root user=container-$vars[image_name] } +confz_container_alpine_packages_installed_check() { + checkvars containers_dir image_name packages svscan_dir + + local root=$vars[containers_dir]/systems/$vars[image_name] + local -a world=( "${(@f)$(<$root/etc/apk/world)}" ) + local -a missing + local pkg + + for pkg in $=vars[packages]; do + (( $world[(I)${pkg}] )) || missing+=( $pkg ) + done + + unify to_install "${(F)missing}" + + do_command=( + cd $vars[svscan_dir]/container.$vars[image_name].sysroot + container_sysroot_run + apk add $missing + ) + + (( $#missing )) +} + # --- Void --- confz_container_void_base_files_check() { diff --git a/zsh-functions/confz_site_containers_init b/zsh-functions/confz_site_containers_init @@ -43,8 +43,20 @@ confz_site_container_services_check() { confz_site_container_images_check() { defvar containers_dir /mnt/volumes/containers + defvar svscan_dir /run/service + local -a alpine_core=( + abduco + s6 + s6-{rc,linux-utils,portable-utils} + execline + ncurses-terminfo + rxvt-unicode-terminfo + zsh + ) require container_alpine_image :containers_dir arch=x86_64 \ image_name=alpine-sndio + require container_alpine_packages_installed :containers_dir :svscan_dir \ + image_name=alpine-sndio packages="$alpine_core" require container_void_image :containers_dir arch=x86_64-musl \ repository=current/musl image_name=void-browsers }