fhs-userenv-bubblewrap: change to using bubblewrap over chrootenv

This commit is contained in:
Michael Eden 2019-02-20 10:22:17 -05:00 committed by Atemu
parent fafbfd2305
commit 2ddb43ec24
2 changed files with 72 additions and 39 deletions

View file

@ -1,36 +1,70 @@
{ callPackage, runCommandLocal, writeScript, stdenv, coreutils }:
{ callPackage, runCommandLocal, writeShellScriptBin, stdenv, coreutils, bubblewrap }:
let buildFHSEnv = callPackage ./env.nix { }; in
args@{ name, runScript ? "bash", extraInstallCommands ? "", meta ? {}, passthru ? {}, ... }:
args @ {
name,
runScript ? "bash",
extraInstallCommands ? "",
meta ? {},
passthru ? {},
...
}:
with builtins;
let
env = buildFHSEnv (removeAttrs args [ "runScript" "extraInstallCommands" "meta" "passthru" ]);
env = buildFHSEnv (removeAttrs args [
"runScript" "extraInstallCommands" "meta" "passthru"
]);
chrootenv = callPackage ./chrootenv {};
init = run: writeScript "${name}-init" ''
#! ${stdenv.shell}
for i in ${env}/* /host/*; do
path="/''${i##*/}"
[ -e "$path" ] || ${coreutils}/bin/ln -s "$i" "$path"
done
[ -d "$1" ] && [ -r "$1" ] && cd "$1"
shift
init = run: writeShellScriptBin "${name}-init" ''
source /etc/profile
exec ${run} "$@"
'';
bwrap_cmd = { init_args ? "" }: ''
blacklist="/nix /dev /proc"
ro_mounts=""
for i in ${env}/*; do
path="/''${i##*/}"
ro_mounts="$ro_mounts --ro-bind $i $path"
blacklist="$blacklist $path"
done
auto_mounts=""
# loop through all directories in the root
for dir in /*; do
# if it is a directory and it is not in the blacklist
if [[ -d "$dir" ]] && grep -v "$dir" <<< "$blacklist" >/dev/null; then
# add it to the mount list
auto_mounts="$auto_mounts --bind $dir $dir"
fi
done
exec ${bubblewrap}/bin/bwrap \
--dev /dev \
--proc /proc \
--chdir "$(pwd)" \
--unshare-all \
--share-net \
--die-with-parent \
--ro-bind /nix /nix \
--ro-bind /etc /host-etc \
$ro_mounts \
$auto_mounts \
${init runScript}/bin/${name}-init ${init_args}
'';
bin = writeShellScriptBin name (bwrap_cmd { init_args = ''"$@"''; });
in runCommandLocal name {
inherit meta;
passthru = passthru // {
env = runCommandLocal "${name}-shell-env" {
shellHook = ''
exec ${chrootenv}/bin/chrootenv ${init runScript} "$(pwd)"
'';
shellHook = bwrap_cmd {};
} ''
echo >&2 ""
echo >&2 "*** User chroot 'env' attributes are intended for interactive nix-shell sessions, not for building! ***"
@ -40,10 +74,6 @@ in runCommandLocal name {
};
} ''
mkdir -p $out/bin
cat <<EOF >$out/bin/${name}
#! ${stdenv.shell}
exec ${chrootenv}/bin/chrootenv ${init runScript} "\$(pwd)" "\$@"
EOF
chmod +x $out/bin/${name}
ln -s ${bin}/bin/${name} $out/bin/${name}
${extraInstallCommands}
''

View file

@ -79,39 +79,42 @@ let
ln -s ${etcProfile} profile
# compatibility with NixOS
ln -s /host/etc/static static
ln -s /host-etc/static static
# symlink some NSS stuff
ln -s /host/etc/passwd passwd
ln -s /host/etc/group group
ln -s /host/etc/shadow shadow
ln -s /host/etc/hosts hosts
ln -s /host/etc/resolv.conf resolv.conf
ln -s /host/etc/nsswitch.conf nsswitch.conf
ln -s /host-etc/passwd passwd
ln -s /host-etc/group group
ln -s /host-etc/shadow shadow
ln -s /host-etc/hosts hosts
ln -s /host-etc/resolv.conf resolv.conf
ln -s /host-etc/nsswitch.conf nsswitch.conf
# symlink sudo and su stuff
ln -s /host/etc/login.defs login.defs
ln -s /host/etc/sudoers sudoers
ln -s /host/etc/sudoers.d sudoers.d
ln -s /host-etc/login.defs login.defs
ln -s /host-etc/sudoers sudoers
ln -s /host-etc/sudoers.d sudoers.d
# symlink other core stuff
ln -s /host/etc/localtime localtime
ln -s /host/etc/zoneinfo zoneinfo
ln -s /host/etc/machine-id machine-id
ln -s /host/etc/os-release os-release
ln -s /host-etc/localtime localtime
ln -s /host-etc/zoneinfo zoneinfo
ln -s /host-etc/machine-id machine-id
ln -s /host-etc/os-release os-release
# symlink PAM stuff
ln -s /host/etc/pam.d pam.d
ln -s /host-etc/pam.d pam.d
# symlink fonts stuff
ln -s /host/etc/fonts fonts
ln -s /host-etc/fonts fonts
# symlink ALSA stuff
ln -s /host/etc/asound.conf asound.conf
ln -s /host-etc/asound.conf asound.conf
# symlink SSL certs
mkdir -p ssl
ln -s /host/etc/ssl/certs ssl/certs
ln -s /host-etc/ssl/certs ssl/certs
# Fedora stores certs in another directory
ln -s /host-etc/pki pki
# symlink /etc/mtab -> /proc/mounts (compat for old userspace progs)
ln -s /proc/mounts mtab