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:
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'
}