mrrl-containers

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

commit 5aef4f6017e9f93d6e745e7612fbbaeb125d1ad7
parent 19da41b2c98d68cdd6c3f8e9e5af814c00721ad3
Author: Jan Pobříslo <ccx@te2000.cz>
Date:   Mon, 22 Nov 2021 23:19:26 +0000

Untested sysroot container preset & confz target to generate them
Diffstat:
Mservice_scripts/alsa/run | 5+++++
Aservice_scripts/sysroot/finish | 19+++++++++++++++++++
Aservice_scripts/sysroot/run | 51+++++++++++++++++++++++++++++++++++++++++++++++++++
Mservice_scripts/xsession/run | 2+-
Mzsh-functions/confz_containers_init | 126+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mzsh-functions/confz_site_containers_init | 8++++++++
6 files changed, 210 insertions(+), 1 deletion(-)

diff --git a/service_scripts/alsa/run b/service_scripts/alsa/run @@ -38,6 +38,11 @@ env #RUN_CHOWN=${UID}:${GID} NS_EXTRA="if { mount -o bind,ro /dev/snd dev/snd } if { mount -o bind,ro /etc/passwd etc/passwd } if { mount -o bind,ro /etc/group etc/group }" +unshare -n # make new network namespace +if { ip addr add 127.0.0.1/8 dev lo } +if { ip addr add ::1/128 dev lo } +if { ip link set lo up } + # Put UID/GID/GIDLIST into environment for use by s6-applyuidgid below s6-envuidgid ${CONTAINER_USER} emptyenv -c diff --git a/service_scripts/sysroot/finish b/service_scripts/sysroot/finish @@ -0,0 +1,19 @@ +#!/command/execlineb +s6-envdir env +multisubstitute { + importas -i CONTAINER_NAME CONTAINER_NAME + importas -i CONTAINER_USER CONTAINER_USER +} +multisubstitute { + define CONTAINER_TMPFS /run/containers/${CONTAINER_NAME}.${CONTAINER_USER} +} +foreground { umount ${CONTAINER_TMPFS}/home } +foreground { umount ${CONTAINER_TMPFS}/run } +foreground { umount ${CONTAINER_TMPFS}/inbox } +foreground { umount ${CONTAINER_TMPFS}/tmp } +foreground { umount --recursive data/root/ } +foreground { + if { test -f ${CONTAINER_TMPFS}/run/uncaught-logs/current } + mv ${CONTAINER_TMPFS}/run/uncaught-logs/current data/lastlog +} +rm -rf ${CONTAINER_TMPFS} diff --git a/service_scripts/sysroot/run b/service_scripts/sysroot/run @@ -0,0 +1,51 @@ +#!/command/execlineb +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 + importas -i -u vtN vtN + define CONTAINER_TMPFS /run/containers/${CONTAINER_NAME}.${CONTAINER_USER} + 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 { 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} + +# Run user's script to populate /home /run and/or /tmp +if { + env HOME=${CONTAINER_USER_HOME} + s6-applyuidgid -U + backtick -E CONTAINER_ROOT { s6-linkname data/root } + confz container_sysroot_rundir + container_root=${CONTAINER_ROOT} + container_name=${CONTAINER_NAME} + tmp_dir=${CONTAINER_TMPFS} +} + +env + NS_EXTRA="if { mount -o bind,ro /etc/passwd etc/passwd } if { mount -o bind,ro /etc/group etc/group }" + +emptyenv -c +ns_run data/root +/mnt/ns/bin/s6-applyuidgid -U +env HOME=/root +/run/init diff --git a/service_scripts/xsession/run b/service_scripts/xsession/run @@ -47,7 +47,7 @@ if { ip addr add ::1/128 dev lo } if { ip link set lo up } emptyenv -c -/root/ns_run data/root +ns_run data/root /mnt/ns/bin/s6-applyuidgid -U env HOME=${CONTAINER_USER_HOME} /run/init diff --git a/zsh-functions/confz_containers_init b/zsh-functions/confz_containers_init @@ -106,6 +106,132 @@ confz_container_service_preset_check() { :svc_dir :root_link :fstab \?down \?control_user \?control_group \?fstab_post } +confz_container_group_check() { + checkvars group_name + local gid="${${(s.:.)"$(getent group $vars[group_name])"}[3]}" + if [[ -z $gid ]]; then + fail_reason="getent returns no GID for group ${(qqq)vars[group_name]}" + return 1 + fi + unify gid "$gid" +} +confz_container_group_do() { + addgroup "$vars[group_name]" || return $? + local gid="${${(s.:.)"$(getent group $vars[group_name])"}[3]}" + if [[ -z $gid ]]; then + fail_reason="getent returns no GID for group ${(qqq)vars[group_name]}" + return 1 + fi + unify gid "$gid" +} + +confz_container_user_check() { + checkvars user_name gid homedir + local -A uids + local -a entry + local line name + </etc/passwd while IFS= read line; do + entry=( "${${(s.:.)entry}[@]}" ) + # name:password:UID:GID:GECOS:directory:shell + # 1 :2 :3 :4 :5 :6 :7 + if [[ $entry[1] == $vars[user_name] ]]; then + unify uid "$entry[3]" + unify gid "$entry[4]" + unify homedir "$entry[6]" + return 0 + fi + uids[${entry[3]}]=$entry[1] + done + # name not found + if (($+vars[uid])); then + if (($+uids[${vars[uid]}])); then + die "UID ${vars[uid]} already assigned to user ${(qqq)vars[user_name]}" + else + return 1 + fi + fi + # UID not set, pick unused one + local n + for n in {1000..2000}; do + (($+uids[$n])) && continue + unify uid $n + return 1 + done + die "Could not find unassigned UID for user ${(qqq)vars[user_name]}" +} +confz_container_user_do() { + printf >>/etc/passwd "%s:x:%s:%s:container root:%s:/bin/sh\n" \ + "$vars[user_name]" "$vars[uid]" "$vars[gid]" "$vars[homedir]" +} + +confz_container_sysroot_user_check() { + checkvars containers_dir image_name + require container_group group_name=container-$vars[image_name] %gid + require container_user user_name=container-$vars[image_name] %uid :gid \ + homedir=$vars[containers_dir]/systems/root +} + +confz_container_image_owner_check() { + checkvars containers_dir image_name uid gid + do_command=( + chown -R $vars[uid]:$vars[gid] $vars[containers_dir]/systems/$vars[image_name] + ) + local -A stat_info + zstat -H stat_info $vars[containers_dir]/systems/$vars[image_name] \ + || die "Could not stat container directory." + [[ $stat_info[uid] == $vars[uid] && $stat_info[gid] == $vars[gid] ]] +} + +confz_container_service_sysroot_check() { + local uid gid svc_dir container + local -a fstab + checkvars containers_dir svscan_dir image_name + defvar fstab_extra '' + defvar container_name "$vars[image_name]" + container=$vars[container_name] + + require container_sysroot_user %uid %gid :container_dir :image_name + require container_image_owner :uid :gid :container_dir :image_name + + require fs_d filename=$vars[containers_dir]/user/sysroot + require fs_m filename=$vars[containers_dir]/user/sysroot mode=751 + require fs_o filename=$vars[containers_dir]/user/sysroot owner=0:$gid + + container_user_dir=$vars[containers_dir]/user/sysroot/$container + require fs_d filename=$container_user_dir + require fs_m filename=$container_user_dir mode=751 + require fs_o filename=$container_user_dir owner=0:$gid + + require fs_d filename=$container_user_dir/root + + # require fs_d filename=$vars[containers_dir]/home/sysroot + # require fs_m filename=$vars[containers_dir]/home/sysroot mode=751 + # require fs_o filename=$vars[containers_dir]/home/sysroot owner=0:$gid + + # require fs_l filename=$vars[containers_dir]/home/sysroot/$container \ + # destination=../../user/sysroot/$container/root/home/sysroot + + fstab=( + $vars[containers_dir]/systems/$vars[image_name]$'\t'$container_user_dir/root$'\tnone\tbind,ro,nosuid,nodev\t0 0' + # /run/containers/$container.sysroot/home$'\t'$container_user_dir/root/home$'\tnone\tbind,nosuid,nodev\t0 0' + /run/containers/$container.sysroot/run$'\t'$container_user_dir/root/run$'\tnone\tbind,nosuid,nodev\t0 0' + # /run/containers/$container.sysroot/tmp$'\t'$container_user_dir/root/tmp$'\tnone\tbind,nosuid,nodev\t0 0' + /run/containers/$container.sysroot/inbox$'\t'$container_user_dir/root/.inbox$'\tnone\tbind,ro,nosuid,nodev\t0 0' + "${(f@)vars[fstab_extra]}" + ) + + svc_dir=$vars[svscan_dir]/container.$container.sysroot + require container_service_preset preset=sysroot \ + svc_dir=$svc_dir control_user=$vars[uid] control_group=$vars[gid] \ + root_link=$container_user_dir/root \ + fstab=${(F)fstab} \?down \?fstab_post + require fs_d filename=$svc_dir/env + require fs_contentnl filename=$svc_dir/env/CONTAINER_USER \ + content=container-$vars[image_name] + require fs_contentnl filename=$svc_dir/env/CONTAINER_NAME \ + content=$container +} + confz_container_service_generic_check() { local uid gid container_user_dir svc_dir container local -a fstab diff --git a/zsh-functions/confz_site_containers_init b/zsh-functions/confz_site_containers_init @@ -37,4 +37,12 @@ confz_site_containers_check() { defvar containers_dir /mnt/volumes/containers defvar svscan_dir /run/service require site_containers_user user=ccx :containers_dir :svscan_dir + require container_service_sysroot :containers_dir :svscan_dir \ + image_name=alpine-dev +} + +confz_sysroot_rundir_check() { + checkvars container_root container_name tmp_dir + require fs_contentnl filename=$vars[tmp_dir]/run/init \ + content=$'$!/bin/sh\nexec sleep 3600' }