aboutsummaryrefslogtreecommitdiff
path: root/nixpkgs/pkgs/build-support/build-fhs-userenv-bubblewrap/default.nix
diff options
context:
space:
mode:
Diffstat (limited to 'nixpkgs/pkgs/build-support/build-fhs-userenv-bubblewrap/default.nix')
-rw-r--r--nixpkgs/pkgs/build-support/build-fhs-userenv-bubblewrap/default.nix123
1 files changed, 123 insertions, 0 deletions
diff --git a/nixpkgs/pkgs/build-support/build-fhs-userenv-bubblewrap/default.nix b/nixpkgs/pkgs/build-support/build-fhs-userenv-bubblewrap/default.nix
new file mode 100644
index 00000000000..c7cfd27d3fa
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/build-fhs-userenv-bubblewrap/default.nix
@@ -0,0 +1,123 @@
+{ callPackage, runCommandLocal, writeShellScriptBin, stdenv, coreutils, bubblewrap }:
+
+let buildFHSEnv = callPackage ./env.nix { }; in
+
+args @ {
+ name,
+ runScript ? "bash",
+ extraInstallCommands ? "",
+ meta ? {},
+ passthru ? {},
+ ...
+}:
+
+with builtins;
+let
+ env = buildFHSEnv (removeAttrs args [
+ "runScript" "extraInstallCommands" "meta" "passthru"
+ ]);
+
+ chrootenv = callPackage ./chrootenv {};
+
+ etcBindFlags = let
+ files = [
+ # NixOS Compatibility
+ "static"
+ # Users, Groups, NSS
+ "passwd"
+ "group"
+ "shadow"
+ "hosts"
+ "resolv.conf"
+ "nsswitch.conf"
+ # Sudo & Su
+ "login.defs"
+ "sudoers"
+ "sudoers.d"
+ # Time
+ "localtime"
+ "zoneinfo"
+ # Other Core Stuff
+ "machine-id"
+ "os-release"
+ # PAM
+ "pam.d"
+ # Fonts
+ "fonts"
+ # ALSA
+ "asound.conf"
+ # SSL
+ "ssl/certs"
+ "pki"
+ ];
+ in concatStringsSep " \\\n "
+ (map (file: "--ro-bind-try /etc/${file} /etc/${file}") files);
+
+ init = run: writeShellScriptBin "${name}-init" ''
+ source /etc/profile
+ exec ${run} "$@"
+ '';
+
+ bwrapCmd = { initArgs ? "" }: ''
+ blacklist="/nix /dev /proc /etc"
+ ro_mounts=""
+ for i in ${env}/*; do
+ path="/''${i##*/}"
+ if [[ $path == '/etc' ]]; then
+ continue
+ fi
+ ro_mounts="$ro_mounts --ro-bind $i $path"
+ blacklist="$blacklist $path"
+ done
+
+ if [[ -d ${env}/etc ]]; then
+ for i in ${env}/etc/*; do
+ path="/''${i##*/}"
+ ro_mounts="$ro_mounts --ro-bind $i /etc$path"
+ done
+ fi
+
+ 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-bind /dev /dev \
+ --proc /proc \
+ --chdir "$(pwd)" \
+ --unshare-all \
+ --share-net \
+ --die-with-parent \
+ --ro-bind /nix /nix \
+ ${etcBindFlags} \
+ $ro_mounts \
+ $auto_mounts \
+ ${init runScript}/bin/${name}-init ${initArgs}
+ '';
+
+ bin = writeShellScriptBin name (bwrapCmd { initArgs = ''"$@"''; });
+
+in runCommandLocal name {
+ inherit meta;
+
+ passthru = passthru // {
+ env = runCommandLocal "${name}-shell-env" {
+ shellHook = bwrapCmd {};
+ } ''
+ echo >&2 ""
+ echo >&2 "*** User chroot 'env' attributes are intended for interactive nix-shell sessions, not for building! ***"
+ echo >&2 ""
+ exit 1
+ '';
+ };
+} ''
+ mkdir -p $out/bin
+ ln -s ${bin}/bin/${name} $out/bin/${name}
+ ${extraInstallCommands}
+''