# vim: ft=zsh noet ts=4 sts=4 sw=4
# find: ‘./event’: Permission denied
# / d o0:0 m755
# /clone-newpid cN o0:0 m644
# /data d o0:0 m755
# /data/fstab
# CN /mnt/volumes/containers/alpine-xsession /mnt/volumes/containers/user/ccx/xsession.6/root none bind,ro 0 0
# /run/containers/xsession.6.ccx/run /mnt/volumes/containers/user/ccx/xsession.6/root/run none bind 0 0
# /run/containers/xsession.6.ccx/tmp /mnt/volumes/containers/user/ccx/xsession.6/root/tmp none bind 0 0
# /run/containers/xsession.6.ccx/home /mnt/volumes/containers/user/ccx/xsession.6/root/home none bind 0 0
# /run/containers/xsession.6.ccx/inbox /mnt/volumes/containers/user/ccx/xsession.6/root/run/inbox none bind,ro 0 0
# o0:0 m644
# /data/root l /mnt/volumes/containers/user/ccx/xsession.6/root o0:0 m777
# /down cN o0:0 m644
# /env d o0:0 m755
# /env/CONTAINER_NAME cN xsession.6 o0:0 m644
# /env/CONTAINER_USER cN ccx o0:0 m644
# /event d o0:100 m3730
# /finish l /usr/local/bzr/containers/service_scripts/xsession/finish o0:0 m777
# /run l /usr/local/bzr/containers/service_scripts/xsession/run o0:0 m777
# /supervise d o0:0 m755
# /supervise/control p o1000:0 m600
# /supervise/death_tally cN o0:0 m644
# /supervise/lock cN o1000:0 m644
# /supervise/status B QAAAAF/8iBYvOSJcQAAAAF/8iBYvOSJcAAAAAAAAAAAAABQ=
# o0:0 m644
confz_container_service_check() {
checkvars svc_dir root_link run_link finish_link fstab
defvar down true
defvar control_user root
defvar control_group root
defvar fstab_post ''
require fs_d flags=p filename=$vars[svc_dir]
require fs_m filename=$vars[svc_dir] mode=755
if $vars[down]; then
require fs_f filename=$vars[svc_dir]/down
else
require fs_r filename=$vars[svc_dir]/down
fi
require fs_f filename=$vars[svc_dir]/clone-newpid
require fs_d filename=$vars[svc_dir]/data
require fs_m filename=$vars[svc_dir]/data mode=755
require fs_l filename=$vars[svc_dir]/data/root \
destination=$vars[root_link]
require fs_contentnl filename=$vars[svc_dir]/data/fstab \
content=$vars[fstab]
require fs_m filename=$vars[svc_dir]/data/fstab mode=644
require fs_d filename=$vars[svc_dir]/env
if [[ -n $vars[fstab_post] ]]; then
require fs_contentnl filename=$vars[svc_dir]/env/NS_FSTAB \
content=$vars[svc_dir]/data/fstab_post
require fs_contentnl filename=$vars[svc_dir]/data/fstab_post \
content=$vars[fstab_post]
else
require fs_r filename=$vars[svc_dir]/env/NS_FSTAB
require fs_r filename=$vars[svc_dir]/data/fstab_post
fi
require fs_l filename=$vars[svc_dir]/run \
destination=$vars[run_link]
require fs_l filename=$vars[svc_dir]/finish \
destination=$vars[finish_link]
require fs_contentnl filename=$vars[svc_dir]/notification-fd \
content=3
require fs_d filename=$vars[svc_dir]/event
require fs_o filename=$vars[svc_dir]/event \
owner=0:$vars[control_group]
require fs_m filename=$vars[svc_dir]/event mode=3730
require fs_d filename=$vars[svc_dir]/supervise
require fs_o filename=$vars[svc_dir]/supervise \
owner=0:0
require fs_m filename=$vars[svc_dir]/supervise mode=755
require fs_pipe filename=$vars[svc_dir]/supervise/control
require fs_o filename=$vars[svc_dir]/supervise/control \
owner=$vars[control_user]:0
require fs_m filename=$vars[svc_dir]/supervise/control mode=600
require fs_f filename=$vars[svc_dir]/supervise/lock
require fs_o filename=$vars[svc_dir]/supervise/lock \
owner=$vars[control_user]:0
require fs_m filename=$vars[svc_dir]/supervise/lock mode=644
if (($+vars[log_dir])); then
require container_service_log :svc_dir :log_dir :log_uid :log_gid \
\?log_umask
else
[[ -e $vars[svc_dir]/log/supervise ]] && \
die "Should not have a logger but one might be running: ${(qqq)vars[svc_dir]}"
require fs_r flags=r filename=$vars[svc_dir]/log
fi
}
confz_container_service_log_check() {
checkvars svc_dir log_dir log_uid log_gid
defvar log_umask 027
local -a runscript=(
'#!/command/execlineb -P'
"if { mkdir -p ${(qqq)vars[log_dir]} }"
"if { chmod $(( [##8] 8#777 ^ 8#$vars[log_umask] )) ${(qqq)vars[log_dir]} }"
"umask $vars[log_umask]"
"if { chown -R $vars[log_uid]:$vars[log_gid] ${(qqq)vars[log_dir]} }"
"s6-setuidgid $vars[log_uid]:$vars[log_gid]"
"s6-log -b -- t ${(qqq)vars[log_dir]}"
)
require fs_d filename=$vars[svc_dir]/log
require fs_m filename=$vars[svc_dir]/log mode=755
require fs_contentnl filename=$vars[svc_dir]/log/run \
content="${(F)runscript}"
require fs_m filename=$vars[svc_dir]/log/run mode=755
require fs_o filename=$vars[svc_dir]/log/run owner=0:0
}
confz_container_service_preset_check() {
# local preset_dir=/usr/local/bzr/containers/service_scripts
local preset_dir=$functions_source[confz_container_service_preset_check]:A:h:h/service_scripts
checkvars svc_dir preset root_link fstab
[[ -x $preset_dir/$vars[preset]/run ]] || die "not an executable file: $preset_dir/$vars[preset]/run"
[[ -x $preset_dir/$vars[preset]/finish ]] || die "not an executable file: $preset_dir/$vars[preset]/finish"
require container_service \
run_link=$preset_dir/$vars[preset]/run \
finish_link=$preset_dir/$vars[preset]/finish \
:svc_dir :root_link :fstab \?down \?control_user \?control_group \?fstab_post \
\?log_dir \?log_uid \?log_gid
}
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.:.)line}[@]}" )
# 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
unify sysroot_user container-$vars[image_name]
unify sysroot_group container-$vars[image_name]
require container_group group_name=$vars[sysroot_group] %gid
require container_user user_name=$vars[sysroot_user] %uid :gid \
homedir=$vars[containers_dir]/systems/root
}
confz_container_image_layout_check() {
checkvars containers_dir image_name
unify root $vars[containers_dir]/systems/$vars[image_name]
require container_sysroot_user :containers_dir :image_name \
%uid %gid %sysroot_user %sysroot_group
}
confz_container_image_layout_svc_check() {
checkvars containers_dir svscan_dir image_name
unify sysroot_svc $vars[svscan_dir]/container.$vars[image_name].sysroot
require container_image_layout :containers_dir :image_name \
%root %uid %gid %sysroot_user %sysroot_group
}
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 container_user_dir
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_image_layout_svc \
:containers_dir :svscan_dir :image_name \
%uid %gid %sysroot_svc %root %sysroot_user %sysroot_group
require container_image_owner :uid :gid :containers_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:0
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:0
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,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]}"
)
require container_service_preset preset=sysroot \
svc_dir=$vars[sysroot_svc] control_user=$vars[uid] control_group=$vars[gid] \
root_link=$container_user_dir/root \
fstab=${(F)fstab} \?down \?fstab_post
require fs_d filename=$vars[sysroot_svc]/env
require fs_contentnl filename=$vars[sysroot_svc]/env/CONTAINER_USER \
content=container-$vars[image_name]
require fs_contentnl filename=$vars[sysroot_svc]/env/CONTAINER_NAME \
content=$container
}
confz_container_service_generic_check() {
local uid gid container_user_dir svc_dir log_dir container
local -a fstab mnt_dirs
checkvars containers_dir svscan_dir image_name user
defvar fstab_extra ''
defvar mnt_dirs_extra ''
defvar container_name "$vars[image_name]"
container=$vars[container_name]
uid="${${(s.:.)"$(getent passwd $vars[user])"}[3]}" \
gid="${${(s.:.)"$(getent group $vars[user])"}[3]}" \
require fs_d filename=$vars[containers_dir]/user/$vars[user]
require fs_m filename=$vars[containers_dir]/user/$vars[user] mode=751
require fs_o filename=$vars[containers_dir]/user/$vars[user] owner=0:$gid
container_user_dir=$vars[containers_dir]/user/$vars[user]/$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=$container_user_dir/home
require fs_m filename=$container_user_dir/home mode=751
require fs_o filename=$container_user_dir/home owner=0:$gid
require fs_d filename=$container_user_dir/home/$vars[user]
require fs_o filename=$container_user_dir/home/$vars[user] owner=$uid:$gid
require fs_d filename=$vars[containers_dir]/home/$vars[user]
require fs_m filename=$vars[containers_dir]/home/$vars[user] mode=751
require fs_o filename=$vars[containers_dir]/home/$vars[user] owner=0:$gid
require fs_l filename=$vars[containers_dir]/home/$vars[user]/$container \
destination=../../user/$vars[user]/$container/home/$vars[user]
mnt_dirs=( ns $=vars[mnt_dirs_extra] )
fstab=(
$vars[containers_dir]/systems/$vars[image_name]$'\t'$container_user_dir/root$'\tnone\tbind,ro,nosuid,nodev\t0 0'
$container_user_dir/home$'\t'$container_user_dir/root/home$'\tnone\tbind,nosuid,nodev\t0 0'
/run/containers/$container.$vars[user]/run$'\t'$container_user_dir/root/run$'\tnone\tbind,nosuid,nodev\t0 0'
/run/containers/$container.$vars[user]/tmp$'\t'$container_user_dir/root/tmp$'\tnone\tbind,nosuid,nodev\t0 0'
/run/containers/$container.$vars[user]/inbox$'\t'$container_user_dir/root/.inbox$'\tnone\tbind,ro,nosuid,nodev\t0 0'
/run/containers/$container.$vars[user]/mnt$'\t'$container_user_dir/root/mnt$'\tnone\tbind,ro,nosuid,nodev\t0 0'
"${(f@)vars[fstab_extra]}"
)
svc_dir=$vars[svscan_dir]/container.$container.$vars[user]
require container_service_preset preset=generic \
svc_dir=$svc_dir control_user=$uid control_group=$gid \
log_dir=/run/container-logs/$container.$vars[user] \
log_uid=0 log_gid=$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=$vars[user]
require fs_contentnl filename=$svc_dir/env/CONTAINER_NAME \
content=$container
require fs_contentnl filename=$svc_dir/env/CONTAINER_MNT_DIRS \
content="$mnt_dirs"
}
confz_container_service_alsa_check() {
local uid gid container_user_dir svc_dir container
local -a fstab
checkvars containers_dir svscan_dir image_name user
defvar fstab_extra ''
defvar container_name "$vars[image_name]"
container=$vars[container_name]
uid="${${(s.:.)"$(getent passwd $vars[user])"}[3]}" \
gid="${${(s.:.)"$(getent group $vars[user])"}[3]}" \
require fs_d filename=$vars[containers_dir]/user/$vars[user]
require fs_m filename=$vars[containers_dir]/user/$vars[user] mode=751
require fs_o filename=$vars[containers_dir]/user/$vars[user] owner=0:$gid
container_user_dir=$vars[containers_dir]/user/$vars[user]/$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=$container_user_dir/home
require fs_m filename=$container_user_dir/home mode=751
require fs_o filename=$container_user_dir/home owner=0:$gid
require fs_d filename=$container_user_dir/home/$vars[user]
require fs_o filename=$container_user_dir/home/$vars[user] owner=$uid:$gid
require fs_d filename=$vars[containers_dir]/home/$vars[user]
require fs_m filename=$vars[containers_dir]/home/$vars[user] mode=751
require fs_o filename=$vars[containers_dir]/home/$vars[user] owner=0:$gid
require fs_l filename=$vars[containers_dir]/home/$vars[user]/$container \
destination=../../user/$vars[user]/$container/home/$vars[user]
fstab=(
$vars[containers_dir]/systems/$vars[image_name]$'\t'$container_user_dir/root$'\tnone\tbind,ro,nosuid,nodev\t0 0'
$container_user_dir/home$'\t'$container_user_dir/root/home$'\tnone\tbind,nosuid,nodev\t0 0'
/run/containers/$container.$vars[user]/run$'\t'$container_user_dir/root/run$'\tnone\tbind,nosuid,nodev\t0 0'
/run/containers/$container.$vars[user]/tmp$'\t'$container_user_dir/root/tmp$'\tnone\tbind,nosuid,nodev\t0 0'
/run/containers/$container.$vars[user]/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.$vars[user]
require container_service_preset preset=alsa \
svc_dir=$svc_dir control_user=$uid control_group=$gid \
log_dir=/run/container-logs/$container.$vars[user] \
log_uid=0 log_gid=$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=$vars[user]
require fs_contentnl filename=$svc_dir/env/CONTAINER_NAME \
content=$container
}
confz_container_service_xsession_check() {
local uid gid container_user_dir svc_dir container
local -a fstab mnt_dirs
checkvars containers_dir svscan_dir image_name user display_number
defvar fstab_extra ''
defvar mnt_dirs_extra ''
container=xsession.$vars[display_number]
uid="${${(s.:.)"$(getent passwd $vars[user])"}[3]}" \
gid="${${(s.:.)"$(getent group $vars[user])"}[3]}" \
require fs_d filename=$vars[containers_dir]/user/$vars[user]
require fs_m filename=$vars[containers_dir]/user/$vars[user] mode=751
require fs_o filename=$vars[containers_dir]/user/$vars[user] owner=0:$gid
container_user_dir=$vars[containers_dir]/user/$vars[user]/$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/$vars[user]
require fs_m filename=$vars[containers_dir]/home/$vars[user] mode=751
require fs_o filename=$vars[containers_dir]/home/$vars[user] owner=0:$gid
require fs_l filename=$vars[containers_dir]/home/$vars[user]/$container \
destination=../../user/$vars[user]/$container/root/home/$vars[user]
mnt_dirs=( ns container-logs $=vars[mnt_dirs_extra] )
fstab=(
$vars[containers_dir]/systems/$vars[image_name]$'\t'$container_user_dir/root$'\tnone\tbind,ro,nosuid,nodev\t0 0'
/run/containers/$container.$vars[user]/home$'\t'$container_user_dir/root/home$'\tnone\tbind,nosuid,nodev\t0 0'
/run/containers/$container.$vars[user]/run$'\t'$container_user_dir/root/run$'\tnone\tbind,nosuid,nodev\t0 0'
/run/containers/$container.$vars[user]/tmp$'\t'$container_user_dir/root/tmp$'\tnone\tbind,nosuid,nodev\t0 0'
/run/containers/$container.$vars[user]/inbox$'\t'$container_user_dir/root/.inbox$'\tnone\tbind,ro,nosuid,nodev\t0 0'
/run/containers/$container.$vars[user]/mnt$'\t'$container_user_dir/root/mnt$'\tnone\tbind,ro,nosuid,nodev\t0 0'
/run/container-logs$'\t'$container_user_dir/root/mnt/container-logs$'\tnone\tbind,ro,nosuid,nodev\t0 0'
"${(f@)vars[fstab_extra]}"
)
svc_dir=$vars[svscan_dir]/container.xsession.$vars[display_number].$vars[user]
require container_service_preset preset=xsession \
svc_dir=$svc_dir control_user=$uid control_group=$gid \
log_dir=/run/container-logs/$container.$vars[user] \
log_uid=0 log_gid=$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=$vars[user]
require fs_contentnl filename=$svc_dir/env/CONTAINER_NAME \
content=$container
require fs_contentnl filename=$svc_dir/env/DISPLAY \
content=:$vars[display_number]
require fs_contentnl filename=$svc_dir/env/vtN \
content=$vars[display_number]
require fs_contentnl filename=$svc_dir/env/CONTAINER_MNT_DIRS \
content="$mnt_dirs"
}
# --- new image constructor
() {
local f d
for f in $^fpath/confz_containers_init*(N); do
d=$f:A:h:h/container_template
if [[ -d $d ]]; then
typeset -g container_template_dir=$d
break
fi
done
}
confz_container_template_file_check() {
checkvars template name root
defvar uid 0
defvar gid 0
defvar mode 0644
defvar target $vars[name]
[[ -f $container_template_dir/$vars[template]/$vars[name] ]] \
|| die "Template file not found: $container_template_dir/$vars[template]/$vars[name]"
[[ -f $vars[root]/$vars[target] ]] || return 1
require fs_m :mode filename=$vars[root]/$vars[target]
require fs_o owner=$vars[uid]:$vars[gid] filename=$vars[root]/$vars[target]
}
confz_container_template_file_do() {
cp -va $container_template_dir/$vars[template]/$vars[name] \
$vars[root]/$vars[target] || die
chown $vars[uid]:$vars[gid] $vars[root]/$vars[target] || die
chmod $vars[mode] $vars[root]/$vars[target] || die
}
confz_container_download_and_verify_check() {
checkvars containers_dir url checksum checksum_algo
defvar filename ${vars[url]:t}
local download_dir=$vars[containers_dir]/download-cache
require fs_d filename=$download_dir
do_command=(
$commands[cd] $download_dir
wget --unlink
-O $download_dir/$vars[filename]
--
$vars[url]
)
(cd $download_dir &&
$vars[checksum_algo]sum --quiet -c <<<"$vars[checksum] $vars[filename]")
}
confz_container_generic_layout_check() {
checkvars root
defvar uid 0
defvar gid 0
require fs_d filename="$vars[root]"
require fs_m filename="$vars[root]" mode=0755
require fs_o filename="$vars[root]" owner=$vars[uid]:$vars[gid]
require fs_d filename="$vars[root]/.inbox"
require fs_m filename="$vars[root]/.inbox" mode=0755
require fs_o filename="$vars[root]/.inbox" owner=$vars[uid]:$vars[gid]
require fs_d filename="$vars[root]/etc"
require fs_m filename="$vars[root]/etc" mode=0755
require fs_o filename="$vars[root]/etc" owner=$vars[uid]:$vars[gid]
require fs_l filename="$vars[root]/etc/resolv.conf" \
flags=\! destination="../run/resolv.conf"
require fs_d filename="$vars[root]/dev"
require fs_m filename="$vars[root]/dev" mode=0755
require fs_o filename="$vars[root]/dev" owner=$vars[uid]:$vars[gid]
require fs_d filename="$vars[root]/dev/pts"
require fs_m filename="$vars[root]/dev/pts" mode=0755
require fs_o filename="$vars[root]/dev/pts" owner=$vars[uid]:$vars[gid]
require fs_d filename="$vars[root]/dev/shm"
require fs_m filename="$vars[root]/dev/shm" mode=0755
require fs_o filename="$vars[root]/dev/shm" owner=$vars[uid]:$vars[gid]
require fs_d filename="$vars[root]/home"
require fs_m filename="$vars[root]/home" mode=0755
require fs_o filename="$vars[root]/home" owner=$vars[uid]:$vars[gid]
require fs_d filename="$vars[root]/mnt"
require fs_m filename="$vars[root]/mnt" mode=0755
require fs_o filename="$vars[root]/mnt" owner=$vars[uid]:$vars[gid]
# This is not required for regular run, /mnt is on tmpfs there
# but sysroot currently doesn't do that.
require fs_d filename="$vars[root]/mnt/ns"
require fs_m filename="$vars[root]/mnt/ns" mode=0755
require fs_o filename="$vars[root]/mnt/ns" owner=$vars[uid]:$vars[gid]
require fs_d filename="$vars[root]/run"
require fs_m filename="$vars[root]/run" mode=0755
require fs_o filename="$vars[root]/run" owner=$vars[uid]:$vars[gid]
require fs_d filename="$vars[root]/tmp"
# require fs_m filename="$vars[root]/tmp" mode=0755
require fs_o filename="$vars[root]/tmp" owner=$vars[uid]:$vars[gid]
}
# --- Alpine ---
confz_container_alpine_base_layout_check() {
checkvars root
defvar uid 0
defvar gid 0
require container_generic_layout :root :uid :gid
require fs_d filename="$vars[root]/etc"
require fs_m filename="$vars[root]/etc" mode=0755
require fs_o filename="$vars[root]/etc" owner=$vars[uid]:$vars[gid]
require fs_d filename="$vars[root]/etc/apk"
require fs_m filename="$vars[root]/etc/apk" mode=0755
require fs_o filename="$vars[root]/etc/apk" owner=$vars[uid]:$vars[gid]
require fs_l filename="$vars[root]/etc/mtab" destination="/proc/mounts"
# require fs_o filename="$vars[root]/etc/mtab" owner=$vars[uid]:$vars[gid]
require fs_d filename="$vars[root]/etc/profile.d"
require fs_m filename="$vars[root]/etc/profile.d" mode=0755
require fs_o filename="$vars[root]/etc/profile.d" owner=$vars[uid]:$vars[gid]
require fs_d filename="$vars[root]/lib"
require fs_m filename="$vars[root]/lib" mode=0755
require fs_o filename="$vars[root]/lib" owner=$vars[uid]:$vars[gid]
require fs_d filename="$vars[root]/lib/firmware"
require fs_m filename="$vars[root]/lib/firmware" mode=0755
require fs_o filename="$vars[root]/lib/firmware" owner=$vars[uid]:$vars[gid]
require fs_d filename="$vars[root]/lib/mdev"
require fs_m filename="$vars[root]/lib/mdev" mode=0755
require fs_o filename="$vars[root]/lib/mdev" owner=$vars[uid]:$vars[gid]
require fs_d filename="$vars[root]/opt"
require fs_m filename="$vars[root]/opt" mode=0755
require fs_o filename="$vars[root]/opt" owner=$vars[uid]:$vars[gid]
require fs_d filename="$vars[root]/proc"
require fs_m filename="$vars[root]/proc" mode=0755
require fs_o filename="$vars[root]/proc" owner=$vars[uid]:$vars[gid]
require fs_d filename="$vars[root]/root"
require fs_m filename="$vars[root]/root" mode=0700
require fs_o filename="$vars[root]/root" owner=$vars[uid]:$vars[gid]
require fs_d filename="$vars[root]/run"
require fs_m filename="$vars[root]/run" mode=0755
require fs_o filename="$vars[root]/run" owner=$vars[uid]:$vars[gid]
require fs_d filename="$vars[root]/sbin"
require fs_m filename="$vars[root]/sbin" mode=0755
require fs_o filename="$vars[root]/sbin" owner=$vars[uid]:$vars[gid]
require fs_d filename="$vars[root]/srv"
require fs_m filename="$vars[root]/srv" mode=0755
require fs_o filename="$vars[root]/srv" owner=$vars[uid]:$vars[gid]
require fs_d filename="$vars[root]/sys"
require fs_m filename="$vars[root]/sys" mode=0755
require fs_o filename="$vars[root]/sys" owner=$vars[uid]:$vars[gid]
require fs_d filename="$vars[root]/tmp"
require fs_m filename="$vars[root]/tmp" mode=1777
require fs_o filename="$vars[root]/tmp" owner=$vars[uid]:$vars[gid]
require fs_d filename="$vars[root]/usr"
require fs_m filename="$vars[root]/usr" mode=0755
require fs_o filename="$vars[root]/usr" owner=$vars[uid]:$vars[gid]
require fs_d filename="$vars[root]/usr/lib"
require fs_m filename="$vars[root]/usr/lib" mode=0755
require fs_o filename="$vars[root]/usr/lib" owner=$vars[uid]:$vars[gid]
require fs_d filename="$vars[root]/usr/local"
require fs_m filename="$vars[root]/usr/local" mode=0755
require fs_o filename="$vars[root]/usr/local" owner=$vars[uid]:$vars[gid]
require fs_d filename="$vars[root]/usr/local/bin"
require fs_m filename="$vars[root]/usr/local/bin" mode=0755
require fs_o filename="$vars[root]/usr/local/bin" owner=$vars[uid]:$vars[gid]
require fs_d filename="$vars[root]/usr/local/lib"
require fs_m filename="$vars[root]/usr/local/lib" mode=0755
require fs_o filename="$vars[root]/usr/local/lib" owner=$vars[uid]:$vars[gid]
require fs_d filename="$vars[root]/usr/local/share"
require fs_m filename="$vars[root]/usr/local/share" mode=0755
require fs_o filename="$vars[root]/usr/local/share" owner=$vars[uid]:$vars[gid]
require fs_d filename="$vars[root]/usr/sbin"
require fs_m filename="$vars[root]/usr/sbin" mode=0755
require fs_o filename="$vars[root]/usr/sbin" owner=$vars[uid]:$vars[gid]
require fs_d filename="$vars[root]/usr/share"
require fs_m filename="$vars[root]/usr/share" mode=0755
require fs_o filename="$vars[root]/usr/share" owner=$vars[uid]:$vars[gid]
require fs_d filename="$vars[root]/usr/share/man"
require fs_m filename="$vars[root]/usr/share/man" mode=0755
require fs_o filename="$vars[root]/usr/share/man" owner=$vars[uid]:$vars[gid]
require fs_d filename="$vars[root]/usr/share/misc"
require fs_m filename="$vars[root]/usr/share/misc" mode=0755
require fs_o filename="$vars[root]/usr/share/misc" owner=$vars[uid]:$vars[gid]
require fs_d filename="$vars[root]/var"
require fs_m filename="$vars[root]/var" mode=0755
require fs_o filename="$vars[root]/var" owner=$vars[uid]:$vars[gid]
require fs_d filename="$vars[root]/var/cache"
require fs_m filename="$vars[root]/var/cache" mode=0755
require fs_o filename="$vars[root]/var/cache" owner=$vars[uid]:$vars[gid]
require fs_d filename="$vars[root]/var/cache/misc"
require fs_m filename="$vars[root]/var/cache/misc" mode=0755
require fs_o filename="$vars[root]/var/cache/misc" owner=$vars[uid]:$vars[gid]
require fs_d filename="$vars[root]/var/empty"
require fs_m filename="$vars[root]/var/empty" mode=0555
require fs_o filename="$vars[root]/var/empty" owner=$vars[uid]:$vars[gid]
require fs_d filename="$vars[root]/var/lib"
require fs_m filename="$vars[root]/var/lib" mode=0755
require fs_o filename="$vars[root]/var/lib" owner=$vars[uid]:$vars[gid]
require fs_d filename="$vars[root]/var/lib/misc"
require fs_m filename="$vars[root]/var/lib/misc" mode=0755
require fs_o filename="$vars[root]/var/lib/misc" owner=$vars[uid]:$vars[gid]
require fs_d filename="$vars[root]/var/local"
require fs_m filename="$vars[root]/var/local" mode=0755
require fs_o filename="$vars[root]/var/local" owner=$vars[uid]:$vars[gid]
require fs_d filename="$vars[root]/var/lock"
require fs_m filename="$vars[root]/var/lock" mode=0755
require fs_o filename="$vars[root]/var/lock" owner=$vars[uid]:$vars[gid]
require fs_d filename="$vars[root]/var/lock/subsys"
require fs_m filename="$vars[root]/var/lock/subsys" mode=0755
require fs_o filename="$vars[root]/var/lock/subsys" owner=$vars[uid]:$vars[gid]
require fs_d filename="$vars[root]/var/log"
require fs_m filename="$vars[root]/var/log" mode=0755
require fs_o filename="$vars[root]/var/log" owner=$vars[uid]:$vars[gid]
require fs_d filename="$vars[root]/var/mail"
require fs_m filename="$vars[root]/var/mail" mode=0755
require fs_o filename="$vars[root]/var/mail" owner=$vars[uid]:$vars[gid]
require fs_d filename="$vars[root]/var/opt"
require fs_m filename="$vars[root]/var/opt" mode=0755
require fs_o filename="$vars[root]/var/opt" owner=$vars[uid]:$vars[gid]
require fs_l filename="$vars[root]/var/run" destination="../run"
# require fs_o filename="$vars[root]/var/run" owner=$vars[uid]:$vars[gid]
require fs_d filename="$vars[root]/var/spool"
require fs_m filename="$vars[root]/var/spool" mode=0755
require fs_o filename="$vars[root]/var/spool" owner=$vars[uid]:$vars[gid]
require fs_d filename="$vars[root]/var/tmp"
require fs_m filename="$vars[root]/var/tmp" mode=1777
require fs_o filename="$vars[root]/var/tmp" owner=$vars[uid]:$vars[gid]
}
confz_container_alpine_base_files_check() {
checkvars root mirror release repositories hostname locale
defvar uid 0
defvar gid 0
local -a repositories=( $vars[mirror]/$vars[release]/${^=vars[repositories]} )
require fs_contentnl filename="$vars[root]/etc/apk/repositories" \
content="${(F)repositories}"
require fs_m filename="$vars[root]/etc/apk/repositories" mode=0644
require fs_o filename="$vars[root]/etc/apk/repositories" owner=$vars[uid]:$vars[gid]
require fs_contentnl filename="$vars[root]/etc/hostname" \
content="$vars[hostname]"
require fs_m filename="$vars[root]/etc/hostname" mode=0644
require fs_o filename="$vars[root]/etc/hostname" owner=$vars[uid]:$vars[gid]
require container_template_file :root :uid :gid \
template=alpine name=etc/hosts
# require fs_contentnl filename="$vars[root]/etc/hosts" \
# content=$'127.0.0.1\tlocalhost localhost.localdomain\n::1\tlocalhost localhost.localdomain'
# require fs_m filename="$vars[root]/etc/hosts" mode=0644
# require fs_o filename="$vars[root]/etc/hosts" owner=$vars[uid]:$vars[gid]
require fs_contentnl filename="$vars[root]/etc/motd" \
content="Welcome to container image at ${(qqq)vars[root]}"
require fs_m filename="$vars[root]/etc/motd" mode=0644
require fs_o filename="$vars[root]/etc/motd" owner=$vars[uid]:$vars[gid]
require container_template_file :root :uid :gid \
template=alpine name=etc/profile
local -a locale_lines=(
"export CHARSET=${(q)vars[locale]}"
"export LANG=${(q)vars[locale]}"
"export LC_COLLATE=C"
)
require fs_contentnl filename="$vars[root]/etc/profile.d/locale.sh" \
content="${(F)locale_lines}"
require fs_m filename="$vars[root]/etc/profile.d/locale.sh" mode=0644
require fs_o filename="$vars[root]/etc/profile.d/locale.sh" owner=$vars[uid]:$vars[gid]
require container_template_file :root :uid :gid \
template=alpine name=etc/protocols
require container_template_file :root :uid :gid \
template=alpine name=etc/services
require container_template_file :root :uid :gid \
template=alpine name=etc/shells
# require fs_contentnl filename="$vars[root]/etc/shells" \
# content=$'# valid login shells\n/bin/sh\n/bin/ash\n/bin/zsh\n/bin/bash\n/bin/mksh'
# require fs_m filename="$vars[root]/etc/shells" mode=0644
# require fs_o filename="$vars[root]/etc/shells" owner=$vars[uid]:$vars[gid]
require fs_f filename="$vars[root]/etc/group"
# require fs_c filename="$vars[root]/etc/group" \
# content=""
require fs_m filename="$vars[root]/etc/group" mode=0644
require fs_o filename="$vars[root]/etc/group" owner=$vars[uid]:$vars[gid]
require fs_f filename="$vars[root]/etc/passwd"
# require fs_c filename="$vars[root]/etc/passwd" \
# content=""
require fs_m filename="$vars[root]/etc/passwd" mode=0644
require fs_o filename="$vars[root]/etc/passwd" owner=$vars[uid]:$vars[gid]
# require fs_c filename="$vars[root]/etc/shadow" \
# content=""
# require fs_m filename="$vars[root]/etc/shadow" mode=0640
# require fs_o filename="$vars[root]/etc/shadow" owner=$vars[uid]:$vars[gid]
}
confz_container_alpine_apk_check() {
checkvars sysroot_user root arch
defvar keys_dir /etc/apk/keys
defvar apk_executable apk
do_command=(
s6-setuidgid $vars[sysroot_user]
$vars[apk_executable]
--update-cache
--initdb
--arch $vars[arch]
--root $vars[root]
--keys-dir $vars[keys_dir]
--no-scripts
--no-chown
add alpine-keys apk-tools busybox
)
[[ -f $vars[root]/sbin/apk ]]
}
confz_container_alpine_image_check() {
checkvars containers_dir image_name arch
defvar mirror http://mirror.fit.cvut.cz/alpine
defvar release edge
defvar repositories main
defvar hostname $vars[image_name]
defvar locale C.UTF-8
require container_image_layout :containers_dir :image_name \
%uid %gid %root %sysroot_user
require container_alpine_base_layout :uid :gid :root
require container_alpine_base_files :uid :gid :root \
:mirror :release :repositories :hostname :locale
require container_alpine_apk :arch :root :sysroot_user
}
confz_container_alpine_packages_installed_check() {
checkvars containers_dir image_name packages svscan_dir
require container_service_sysroot \
:containers_dir :svscan_dir :image_name \
%sysroot_svc
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
do_command=(
$commands[cd] $vars[sysroot_svc] container_sysroot_run
/sbin/apk add --no-chown $missing
)
(( $#missing == 0 ))
}
# --- Void ---
confz_container_void_base_files_check() {
checkvars root
# checkvars hostname locale
defvar uid 0
defvar gid 0
local d
for d in $vars[root]{,/var{,/db{,/xbps{,/keys}}}}; do
require fs_d filename="$d"
require fs_m filename="$d" mode=0755
require fs_o filename="$d" owner=$vars[uid]:$vars[gid]
done
local f
for f in $container_template_dir/void/**/*(.); do
require container_template_file :root :uid :gid \
template=void name=${f#${container_template_dir}/void/}
done
# Alpine XBPS compatibility
require fs_l filename="$vars[root]/var/lib/xbps/db" \
flags=\!p destination="../../db"
}
confz_container_void_xbps_check() {
checkvars sysroot_user root arch mirror repository
defvar xbps_install_executable xbps-install
do_command=(
env XBPS_ARCH=$vars[arch]
s6-setuidgid $vars[sysroot_user]
$vars[xbps_install_executable]
--sync
--rootdir $vars[root]
--repository ${vars[mirror]#/}/$vars[repository]
--yes
base-files xbps dash coreutils
)
[[ -f $vars[root]/usr/bin/xbps-install && -f $vars[root]/usr/bin/sh ]]
}
confz_container_void_image_check() {
checkvars containers_dir image_name arch
defvar mirror https://repo-default.voidlinux.org/
defvar repository current
#defvar hostname $vars[image_name]
#defvar locale C.UTF-8
require container_image_layout :containers_dir :image_name \
%uid %gid %root %sysroot_user
require container_generic_layout :uid :gid :root
require container_void_base_files :uid :gid :root
require container_void_xbps :arch :mirror :repository \
:root :sysroot_user \?xbps_install_executable
}
confz_container_void_packages_installed_check() {
checkvars packages containers_dir image_name svscan_dir
require container_service_sysroot \
:containers_dir :svscan_dir :image_name \
%root %sysroot_svc
local -a missing
local pkg
for pkg in $=vars[packages]; do
[[ -f $vars[root]/var/db/xbps/.${pkg}-files.plist ]] \
|| missing+=( $pkg )
done
do_command=(
$commands[cd] $vars[sysroot_svc] container_sysroot_run
/usr/sbin/xbps-install --yes --sync -- $missing
)
(( $#missing == 0 ))
}
# --- Nix / NixOS ---
confz_container_nix_base_files_check() {
checkvars root hostname locale
defvar uid 0
defvar gid 0
require fs_contentnl filename="$vars[root]/etc/hostname" \
content="$vars[hostname]"
require fs_m filename="$vars[root]/etc/hostname" mode=0644
require fs_o filename="$vars[root]/etc/hostname" owner=$vars[uid]:$vars[gid]
require container_template_file :root :uid :gid \
template=alpine name=etc/hosts
require fs_contentnl filename="$vars[root]/etc/motd" \
content="Welcome to container image at ${(qqq)vars[root]}"
require fs_m filename="$vars[root]/etc/motd" mode=0644
require fs_o filename="$vars[root]/etc/motd" owner=$vars[uid]:$vars[gid]
require container_template_file :root :uid :gid \
template=alpine name=etc/profile
local -a locale_lines=(
"export CHARSET=${(q)vars[locale]}"
"export LANG=${(q)vars[locale]}"
"export LC_COLLATE=C"
)
require fs_d filename="$vars[root]/etc/profile.d"
require fs_m filename="$vars[root]/etc/profile.d" mode=0755
require fs_o filename="$vars[root]/etc/profile.d" owner=$vars[uid]:$vars[gid]
require fs_contentnl filename="$vars[root]/etc/profile.d/locale.sh" \
content="${(F)locale_lines}"
require fs_m filename="$vars[root]/etc/profile.d/locale.sh" mode=0644
require fs_o filename="$vars[root]/etc/profile.d/locale.sh" owner=$vars[uid]:$vars[gid]
require fs_l filename="$vars[root]/etc/profile.d/nix.sh" \
destination="/nix/var/nix/profiles/default/etc/profile.d/nix.sh"
# TODO: source Nix stuff from profile
require container_template_file :root :uid :gid \
template=alpine name=etc/protocols
require container_template_file :root :uid :gid \
template=alpine name=etc/services
require container_template_file :root :uid :gid \
template=alpine name=etc/shells
require fs_f filename="$vars[root]/etc/group"
# require fs_c filename="$vars[root]/etc/group" \
# content=""
require fs_m filename="$vars[root]/etc/group" mode=0644
require fs_o filename="$vars[root]/etc/group" owner=$vars[uid]:$vars[gid]
require fs_f filename="$vars[root]/etc/passwd"
# require fs_c filename="$vars[root]/etc/passwd" \
# content=""
require fs_m filename="$vars[root]/etc/passwd" mode=0644
require fs_o filename="$vars[root]/etc/passwd" owner=$vars[uid]:$vars[gid]
# symlink relevant executables for shebangs
require fs_d filename="$vars[root]/bin"
require fs_m filename="$vars[root]/bin" mode=0755
require fs_o filename="$vars[root]/bin" owner=$vars[uid]:$vars[gid]
# require fs_l filename="$vars[root]/bin/execlineb" \
# destination="/root/.nix-profile/bin/execlineb"
# require fs_l filename="$vars[root]/bin/zsh" \
# destination="/root/.nix-profile/bin/zsh"
}
confz_container_nix_image_from_release_check() {
checkvars containers_dir svscan_dir image_name system
defvar release 2.9.1
defvar checksum_algo sha256
defvar mirror https://releases.nixos.org/nix
case $vars[release] in
(2.9.1) case $vars[system] in
(x86_64-linux)
defvar checksum ea7b94637b251cdaadf932cef41c681aa3d2a15928877d8319ae6f35a440977d
;;
(i686-linux)
defvar checksum 41e38706a26736aa42acd3dbd57db7e354e722e4bd5f6d9c8069d1c98b6081be
;;
(aarch64-linux)
defvar checksum d706c6b710548b9c3ed4a409df3a7293da14f726dcc59849abd709e574cabeed
;;
(armv6l-linux)
defvar checksum d8483f0747dce74685fcffa628908a96e6d0f7b1166a97f0eef231f5faa86c22
;;
(armv7l-linux)
defvar checksum 6f7f285d5de8b8d7686b6925869e25c2ff40f16492190c0b773ebd357bd4c956
;;
esac
;;
esac
defvar alpine_arch ${vars[system]%-*}
unify url $vars[mirror]/nix-$vars[release]/nix-$vars[release]-$vars[system].tar.xz
(($+vars[checksum])) || die "No stored checksum for $url"
require container_nix_image :containers_dir :svscan_dir :image_name :url \
:checksum :checksum_algo :alpine_arch \?hostname \?locale
}
confz_container_nix_bootstrap_packages_check() {
checkvars sysroot_user root arch uid gid
defvar keys_dir /etc/apk/keys
defvar apk_executable apk
defvar mirror http://mirror.fit.cvut.cz/alpine
defvar release edge
defvar repositories main
local -a repositories=( $vars[mirror]/$vars[release]/${^=vars[repositories]} )
require fs_d filename="$vars[root]/etc/apk"
require fs_m filename="$vars[root]/etc/apk" mode=0755
require fs_o filename="$vars[root]/etc/apk" owner=$vars[uid]:$vars[gid]
require fs_contentnl filename="$vars[root]/etc/apk/repositories" \
content="${(F)repositories}"
require fs_m filename="$vars[root]/etc/apk/repositories" mode=0644
require fs_o filename="$vars[root]/etc/apk/repositories" owner=$vars[uid]:$vars[gid]
do_command=(
s6-setuidgid $vars[sysroot_user]
$vars[apk_executable]
--update-cache
--initdb
--arch $vars[arch]
--root $vars[root]
--keys-dir $vars[keys_dir]
--no-scripts
add alpine-keys busybox ca-certificates{,-bundle}
)
[[ -f $vars[root]/bin/busybox ]]
}
confz_container_nix_bootstrap_check() {
checkvars root sysroot_svc sysroot_user uid gid arch
require container_nix_bootstrap_packages \
:root :arch :uid :gid :sysroot_user \
\?keys_dir \?apk_executable \?mirror \?release \?repositories
do_command=(
$commands[cd] $vars[sysroot_svc] container_sysroot_run
/bin/busybox --install -s /bin
)
[[ -f $vars[root]/bin/test ]]
}
confz_container_nix_image_installed_check() {
checkvars root filename uid gid
require fs_r flags=r filename=$vars[root]/${vars[filename]%.tar.*}
require fs_d filename="$vars[root]/nix"
require fs_m filename="$vars[root]/nix" mode=0755
require fs_o filename="$vars[root]/nix" owner=$vars[uid]:$vars[gid]
[[ -d $vars[root]/nix/store ]]
}
confz_container_nix_image_installed_do() {
local download_dir=$vars[containers_dir]/download-cache
s6-setuidgid $vars[sysroot_user] \
tar -xpC "$vars[root]" -f "$download_dir/$vars[filename]" \
|| die "Unpacking ${(qqq)vars[filename]} failed"
$commands[cd] $vars[svscan_dir]/container.$vars[image_name].sysroot \
container_sysroot_run \
/${vars[filename]%.tar.*}/install \
|| die "Nix installation script failed"
rm -rf $vars[root]/${vars[filename]%.tar.*} \
|| die "Removing tarball directory failed"
}
confz_container_nix_image_check() {
checkvars containers_dir image_name url checksum svscan_dir alpine_arch
defvar checksum_algo sha256
defvar hostname $vars[image_name]
defvar locale C.UTF-8
# TODO: test if these actually do something
require container_service_sysroot \
:containers_dir :svscan_dir :image_name \
%root %uid %gid %sysroot_user %sysroot_svc
require container_download_and_verify :containers_dir \
:checksum :checksum_algo %filename :url
require container_generic_layout :uid :gid :root
require container_nix_base_files :uid :gid :root :hostname :locale
require container_nix_bootstrap :sysroot_svc :root :uid :gid :sysroot_user
\?arch=alpine_arch \
\?keys_dir=alpine_keys_dir \
\?mirror=alpine_mirrors \
\?release=alpine_release \
\?repositories=alpine_repositories \
\?apk_executable
require container_nix_image_installed :filename :root :uid :gid
require fs_l filename="$vars[root]/nix/var/nix/profiles/default" \
destination="per-user/root/profile"
require fs_o filename="$vars[root]/nix/var/nix/profiles/default" \
owner=$vars[uid]:$vars[gid]
}
confz_container_nix_bin_linked_check() {
checkvars containers_dir image_name
require container_image_layout :containers_dir :image_name %root
local profile_dir=$vars[root]/root/.nix-profile
local -A stat_info
zstat -L -H stat_info $profile_dir
# while it's a symlink
while (( $stat_info[mode] >> 12 == 10 )); do
if [[ $stat_info[link] == /* ]]; then
profile_dir=$vars[root]$stat_info[link]
else
profile_dir=${profile_dir:h}/$stat_info[link]
fi
zstat -L -H stat_info $profile_dir
done
[[ -d $profile_dir ]] || \
die "Could not find profile directory: ${(qqq)profile_dir}"
local b
for b in $profile_dir/bin/*; do
[[ -e $vars[root]/bin/$b:t ]] || \
require fs_l filename="$vars[root]/bin/${b:t}" \
destination=../root/.nix-profile/bin/$b:t
done
}
confz_container_nix_packages_installed_check() {
checkvars packages containers_dir image_name svscan_dir
require container_service_sysroot \
:containers_dir :svscan_dir :image_name \
%root %svscan_dir
local -A stat_info
# local profile_dir=$vars[root]/nix/var/nix/profiles/per-user/root/profile
local profile_dir=$vars[root]/root/.nix-profile
zstat -L -H stat_info $profile_dir
# while it's a symlink
while (( $stat_info[mode] >> 12 == 10 )); do
if [[ $stat_info[link] == /* ]]; then
profile_dir=$vars[root]$stat_info[link]
else
profile_dir=${profile_dir:h}/$stat_info[link]
fi
zstat -L -H stat_info $profile_dir
done
[[ -d $profile_dir ]] || \
die "Could not find profile directory: ${(qqq)profile_dir}"
local manifest_file=$profile_dir/manifest.nix
zstat -L -H stat_info $manifest_file
# while it's a symlink
while (( $stat_info[mode] >> 12 == 10 )); do
if [[ $stat_info[link] == /* ]]; then
manifest_file=$vars[root]$stat_info[link]
else
manifest_file=${manifest_file:h}/$stat_info[link]
fi
zstat -L -H stat_info $manifest_file
done
[[ -f $manifest_file ]] || \
die "Could not find manifest.nix file: ${(qqq)manifest_file}"
local -a world world_noversion missing
world=( "${(@f)$(
grep -o 'outPath = "[^"]*"' $manifest_file \
| uniq | sed 's|^outPath = "/nix/store/[^-]*-||;s|"$||'
)}" )
world_noversion=( "${world[@]%-bin}" )
world_noversion=( "${world_noversion[@]/%-[-0-9.]#/}" )
local pkg
for pkg in $=vars[packages]; do
(( $world[(I)${pkg}] )) || \
(( $world_noversion[(I)${pkg}] )) || \
missing+=( $pkg )
done
do_command=(
$commands[cd] $vars[sysroot_svc] container_sysroot_run
/root/.nix-profile/bin/nix-env --install $missing
# /var/lib/nix/profiles/default/bin/nix-env --install $missing
)
fail_reason="Following packages are not installed: $missing"
(( $#missing == 0 ))
}
#typeset -f -t confz_container_nix_packages_installed_check
# --- Debian ---
confz_container_debian_image_check() {
checkvars containers_dir image_name arch suite
defvar mirror http://ftp.cvut.cz/debian/
require container_image_layout :containers_dir :image_name \
%uid %gid %root %sysroot_user
require container_debootstrap :root :arch :mirror :suite \
:uid :gid
require container_generic_layout :uid :gid :root
#require container_debian_base_files :uid :gid :root
}
confz_container_debootstrap_check() {
checkvars root arch mirror suite uid gid
defvar variant minbase
defvar debootstrap_executable debootstrap
[[ -f $vars[root]/usr/bin/apt-get && -f $vars[root]/usr/bin/sh ]]
}
confz_container_debootstrap_do() {
local tmp_root=${vars[root]:h}/.debootstrap.${vars[root]:t}
if [[ -e $tmp_root ]]; then
rm -rf $tmp_root || return $?
fi
$vars[debootstrap_executable] --variant=$vars[variant] \
--include=fakeroot \
$vars[suite] $tmp_root $vars[mirror] || return $?
chown -R $vars[uid]:$vars[gid] $tmp_root || return $?
s6-rename $tmp_root $vars[root] || return $?
}
typeset -f -t confz_container_debootstrap_do
confz_container_debian_packages_installed_check() {
checkvars containers_dir image_name packages svscan_dir
require container_service_sysroot \
:containers_dir :svscan_dir :image_name \
%uid %gid %root %sysroot_user %sysroot_svc
local root=$vars[containers_dir]/systems/$vars[image_name]
local -a missing installed
local pkg
installed=( ${(f)"$(
awk '/^Package: /{p=$2} /^Status:.* installed/{print p}' $vars[root]/var/lib/dpkg/status
)"} )
for pkg in $=vars[packages]; do
(( $installed[(I)${pkg}] )) || missing+=( $pkg )
done
do_command=(
$commands[cd] $vars[sysroot_svc] container_sysroot_run
# /usr/bin/apt-get install --trivial-only -- $missing
/usr/bin/apt-get install --yes -- $missing
)
fail_reason="Following packages are not installed: $missing"
(( $#missing == 0 ))
}
confz_container_debian_packages_installed_with_fakeroot_check() {
checkvars containers_dir image_name packages svscan_dir
require container_service_sysroot \
:containers_dir :svscan_dir :image_name \
%uid %gid %root %sysroot_user %sysroot_svc
local root=$vars[containers_dir]/systems/$vars[image_name]
local -a missing installed
local pkg
installed=( ${(f)"$(
awk '/^Package: /{p=$2} /^Status:.* installed/{print p}' $vars[root]/var/lib/dpkg/status
)"} )
for pkg in $=vars[packages]; do
(( $installed[(I)${pkg}] )) || missing+=( $pkg )
done
do_command=(
$commands[cd] $vars[sysroot_svc] container_sysroot_run
/usr/bin/fakeroot-sysv /usr/bin/apt-get install --yes -- $missing
)
fail_reason="Following packages are not installed: $missing"
(( $#missing == 0 ))
}
confz_container_puppet_apt_repo_check() {
checkvars containers_dir svscan_dir image_name arch suite
defvar puppet_version 7
require container_service_sysroot \
:containers_dir :svscan_dir :image_name \
%uid %gid %root %sysroot_user %sysroot_svc
[[ -f $vars[root]/etc/apt/trusted.gpg.d/puppet$vars[puppet_version]-keyring.gpg \
&& -f $vars[root]/etc/apt/sources.list.d/puppet$vars[puppet_version].list \
&& -f $vars[root]/var/lib/apt/lists/apt.puppetlabs.com_dists_$vars[suite]_InRelease ]]
}
confz_container_puppet_apt_repo_do() {
local deb_file=puppet7-release-$vars[suite].deb
s6-setuidgid $vars[sysroot_user] \
wget --unlink -O $vars[root]/root/$deb_file \
https://apt.puppetlabs.com/$deb_file \
|| return $?
$commands[cd] $vars[sysroot_svc] container_sysroot_run \
/usr/bin/dpkg --force-not-root -i /root/$deb_file \
|| return $?
$commands[cd] $vars[sysroot_svc] container_sysroot_run \
/usr/bin/apt-get update \
|| return $?
}