Merge pull request #16030 from abbradar/fhs-refactor
Improvements for FHS user chrootenv
This commit is contained in:
commit
b341de88e9
|
@ -171,42 +171,18 @@ c = lib.makeOverridable f { a = 1; b = 2; }</programlisting>
|
||||||
|
|
||||||
|
|
||||||
<section xml:id="sec-fhs-environments">
|
<section xml:id="sec-fhs-environments">
|
||||||
<title>buildFHSChrootEnv/buildFHSUserEnv</title>
|
<title>buildFHSUserEnv</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
<function>buildFHSChrootEnv</function> and
|
<function>buildFHSUserEnv</function> provides a way to build and run
|
||||||
<function>buildFHSUserEnv</function> provide a way to build and run
|
FHS-compatible lightweight sandboxes. It creates an isolated root with
|
||||||
FHS-compatible lightweight sandboxes. They get their own isolated root with
|
bound <filename>/nix/store</filename>, so its footprint in terms of disk
|
||||||
binded <filename>/nix/store</filename>, so their footprint in terms of disk
|
|
||||||
space needed is quite small. This allows one to run software which is hard or
|
space needed is quite small. This allows one to run software which is hard or
|
||||||
unfeasible to patch for NixOS -- 3rd-party source trees with FHS assumptions,
|
unfeasible to patch for NixOS -- 3rd-party source trees with FHS assumptions,
|
||||||
games distributed as tarballs, software with integrity checking and/or external
|
games distributed as tarballs, software with integrity checking and/or external
|
||||||
self-updated binaries.
|
self-updated binaries. It uses Linux namespaces feature to create
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
<function>buildFHSChrootEnv</function> allows to create persistent
|
|
||||||
environments, which can be constructed, deconstructed and entered by
|
|
||||||
multiple users at once. A downside is that it requires
|
|
||||||
<literal>root</literal> access for both those who create and destroy and
|
|
||||||
those who enter it. It can be useful to create environments for daemons that
|
|
||||||
one can enter and observe.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
<function>buildFHSUserEnv</function> uses Linux namespaces feature to create
|
|
||||||
temporary lightweight environments which are destroyed after all child
|
temporary lightweight environments which are destroyed after all child
|
||||||
processes exit. It does not require root access, and can be useful to create
|
processes exit, without root user rights requirement. Accepted arguments are:
|
||||||
sandboxes and wrap applications.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Those functions both rely on <function>buildFHSEnv</function>, which creates
|
|
||||||
an actual directory structure given a list of necessary packages and extra
|
|
||||||
build commands.
|
|
||||||
<function>buildFHSChrootEnv</function> and <function>buildFHSUserEnv</function>
|
|
||||||
both accept those arguments which are passed to
|
|
||||||
<function>buildFHSEnv</function>:
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<variablelist>
|
<variablelist>
|
||||||
|
@ -220,14 +196,16 @@ c = lib.makeOverridable f { a = 1; b = 2; }</programlisting>
|
||||||
<term><literal>targetPkgs</literal></term>
|
<term><literal>targetPkgs</literal></term>
|
||||||
|
|
||||||
<listitem><para>Packages to be installed for the main host's architecture
|
<listitem><para>Packages to be installed for the main host's architecture
|
||||||
(i.e. x86_64 on x86_64 installations).</para></listitem>
|
(i.e. x86_64 on x86_64 installations). Along with libraries binaries are also
|
||||||
|
installed.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><literal>multiPkgs</literal></term>
|
<term><literal>multiPkgs</literal></term>
|
||||||
|
|
||||||
<listitem><para>Packages to be installed for all architectures supported by
|
<listitem><para>Packages to be installed for all architectures supported by
|
||||||
a host (i.e. i686 and x86_64 on x86_64 installations).</para></listitem>
|
a host (i.e. i686 and x86_64 on x86_64 installations). Only libraries are
|
||||||
|
installed by default.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
|
@ -240,29 +218,33 @@ c = lib.makeOverridable f { a = 1; b = 2; }</programlisting>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><literal>extraBuildCommandsMulti</literal></term>
|
<term><literal>extraBuildCommandsMulti</literal></term>
|
||||||
|
|
||||||
<listitem><para>Like <literal>extraBuildCommandsMulti</literal>, but
|
<listitem><para>Like <literal>extraBuildCommands</literal>, but
|
||||||
executed only on multilib architectures.</para></listitem>
|
executed only on multilib architectures.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><literal>extraOutputsToInstall</literal></term>
|
||||||
|
|
||||||
|
<listitem><para>Additional derivation outputs to be linked for both
|
||||||
|
target and multi-architecture packages.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><literal>extraInstallCommands</literal></term>
|
||||||
|
|
||||||
|
<listitem><para>Additional commands to be executed for finalizing the
|
||||||
|
derivation with runner script.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><literal>runScript</literal></term>
|
||||||
|
|
||||||
|
<listitem><para>A command that would be executed inside the sandbox and
|
||||||
|
passed all the command line arguments. It defaults to
|
||||||
|
<literal>bash</literal>.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
</variablelist>
|
</variablelist>
|
||||||
|
|
||||||
<para>
|
|
||||||
Additionally, <function>buildFHSUserEnv</function> accepts
|
|
||||||
<literal>runScript</literal> parameter, which is a command that would be
|
|
||||||
executed inside the sandbox and passed all the command line arguments. It
|
|
||||||
default to <literal>bash</literal>.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
It also uses <literal>CHROOTENV_EXTRA_BINDS</literal> environment variable
|
|
||||||
for binding extra directories in the sandbox to outside places. The format of
|
|
||||||
the variable is <literal>/mnt=test-mnt:/data</literal>, where
|
|
||||||
<literal>/mnt</literal> would be mounted as <literal>/test-mnt</literal>
|
|
||||||
and <literal>/data</literal> would be mounted as <literal>/data</literal>.
|
|
||||||
<literal>extraBindMounts</literal> array argument to
|
|
||||||
<function>buildFHSUserEnv</function> function is prepended to this variable.
|
|
||||||
Latter entries take priority if defined several times -- i.e. in case of
|
|
||||||
<literal>/data=data1:/data=data2</literal> the actual bind path would be
|
|
||||||
<literal>/data2</literal>.
|
|
||||||
</para>
|
|
||||||
<para>
|
<para>
|
||||||
One can create a simple environment using a <literal>shell.nix</literal>
|
One can create a simple environment using a <literal>shell.nix</literal>
|
||||||
like that:
|
like that:
|
||||||
|
|
|
@ -1,48 +0,0 @@
|
||||||
{ stdenv } : { env, extraInstallCommands ? "" } :
|
|
||||||
|
|
||||||
let
|
|
||||||
# References to shell scripts that set up or tear down the environment
|
|
||||||
initSh = ./init.sh.in;
|
|
||||||
mountSh = ./mount.sh.in;
|
|
||||||
loadSh = ./load.sh.in;
|
|
||||||
umountSh = ./umount.sh.in;
|
|
||||||
destroySh = ./destroy.sh.in;
|
|
||||||
|
|
||||||
name = env.pname;
|
|
||||||
|
|
||||||
in stdenv.mkDerivation {
|
|
||||||
name = "${name}-chrootenv";
|
|
||||||
preferLocalBuild = true;
|
|
||||||
buildCommand = ''
|
|
||||||
mkdir -p $out/bin
|
|
||||||
cd $out/bin
|
|
||||||
|
|
||||||
sed -e "s|@chrootEnv@|${env}|g" \
|
|
||||||
-e "s|@name@|${name}|g" \
|
|
||||||
-e "s|@shell@|${stdenv.shell}|g" \
|
|
||||||
${initSh} > init-${name}-chrootenv
|
|
||||||
chmod +x init-${name}-chrootenv
|
|
||||||
|
|
||||||
sed -e "s|@shell@|${stdenv.shell}|g" \
|
|
||||||
-e "s|@name@|${name}|g" \
|
|
||||||
${mountSh} > mount-${name}-chrootenv
|
|
||||||
chmod +x mount-${name}-chrootenv
|
|
||||||
|
|
||||||
sed -e "s|@shell@|${stdenv.shell}|g" \
|
|
||||||
-e "s|@name@|${name}|g" \
|
|
||||||
${loadSh} > load-${name}-chrootenv
|
|
||||||
chmod +x load-${name}-chrootenv
|
|
||||||
|
|
||||||
sed -e "s|@shell@|${stdenv.shell}|g" \
|
|
||||||
-e "s|@name@|${name}|g" \
|
|
||||||
${umountSh} > umount-${name}-chrootenv
|
|
||||||
chmod +x umount-${name}-chrootenv
|
|
||||||
|
|
||||||
sed -e "s|@chrootEnv@|${env}|g" \
|
|
||||||
-e "s|@shell@|${stdenv.shell}|g" \
|
|
||||||
-e "s|@name@|${name}|g" \
|
|
||||||
${destroySh} > destroy-${name}-chrootenv
|
|
||||||
chmod +x destroy-${name}-chrootenv
|
|
||||||
${extraInstallCommands}
|
|
||||||
'';
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
#! @shell@ -e
|
|
||||||
|
|
||||||
chrootenvDest=/run/chrootenv/@name@
|
|
||||||
|
|
||||||
# Remove bind mount points
|
|
||||||
rmdir $chrootenvDest/{dev,nix/store,nix,proc,sys,host-etc,home,var,run,tmp}
|
|
||||||
|
|
||||||
# Remove symlinks to the software that should be part of the chroot system profile
|
|
||||||
for i in @chrootEnv@/*
|
|
||||||
do
|
|
||||||
if [ "$i" != "@chrootEnv@/etc" ] && [ "$i" != "@chrootEnv@/var" ]
|
|
||||||
then
|
|
||||||
rm $chrootenvDest/$(basename $i)
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# Remove the remaining folders
|
|
||||||
rm -Rf $chrootenvDest/{etc,root}
|
|
||||||
rm -Rf /tmp/chrootenv-@name@
|
|
||||||
|
|
||||||
# Remove the chroot environment folder
|
|
||||||
rmdir $chrootenvDest
|
|
|
@ -1,22 +0,0 @@
|
||||||
#! @shell@ -e
|
|
||||||
|
|
||||||
chrootenvDest=/run/chrootenv/@name@
|
|
||||||
|
|
||||||
# Create some mount points for stuff that must be bind mounted
|
|
||||||
mkdir -p $chrootenvDest/{nix/store,dev,proc,sys,host-etc,host-tmp,home,var,run}
|
|
||||||
|
|
||||||
# Symlink the software that should be part of the chroot system profile
|
|
||||||
for i in @chrootEnv@/*
|
|
||||||
do
|
|
||||||
if [ "$i" != "@chrootEnv@/var" ]
|
|
||||||
then
|
|
||||||
ln -s "$i" "$chrootenvDest"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# Create root folder
|
|
||||||
mkdir $chrootenvDest/root
|
|
||||||
|
|
||||||
# Create tmp folder
|
|
||||||
mkdir -m1777 $chrootenvDest/tmp
|
|
||||||
mkdir -m1777 -p /tmp/chrootenv-@name@
|
|
|
@ -1,13 +0,0 @@
|
||||||
#! @shell@ -e
|
|
||||||
|
|
||||||
chrootenvDest=/run/chrootenv/@name@
|
|
||||||
|
|
||||||
# Enter the LFS chroot environment
|
|
||||||
sudo chroot --userspec "$USER:${GROUPS[0]}" --groups "${GROUPS[0]}" $chrootenvDest /usr/bin/env -i \
|
|
||||||
TERM="$TERM" \
|
|
||||||
DISPLAY="$DISPLAY" \
|
|
||||||
HOME="$HOME" \
|
|
||||||
XDG_RUNTIME_DIR="$XDG_RUNTIME_DIR" \
|
|
||||||
LANG="$LANG" \
|
|
||||||
SSL_CERT_FILE="$SSL_CERT_FILE" \
|
|
||||||
/bin/bash --login
|
|
|
@ -1,34 +0,0 @@
|
||||||
#! @shell@ -e
|
|
||||||
|
|
||||||
chrootenvDest=/run/chrootenv/@name@
|
|
||||||
|
|
||||||
# Bind mount the Nix store
|
|
||||||
mount --bind /nix/store $chrootenvDest/nix/store
|
|
||||||
|
|
||||||
# Bind mount some kernel related stuff
|
|
||||||
mount --bind /dev $chrootenvDest/dev
|
|
||||||
mount --bind /dev/pts $chrootenvDest/dev/pts
|
|
||||||
mount --bind /dev/shm $chrootenvDest/dev/shm
|
|
||||||
mount --bind /proc $chrootenvDest/proc
|
|
||||||
mount --bind /sys $chrootenvDest/sys
|
|
||||||
|
|
||||||
# Bind mount home directories
|
|
||||||
mount --bind /home $chrootenvDest/home
|
|
||||||
|
|
||||||
# Bind mount state directories
|
|
||||||
mount --bind /var $chrootenvDest/var
|
|
||||||
mount --rbind /run $chrootenvDest/run
|
|
||||||
|
|
||||||
# Bind mount the host system's /etc
|
|
||||||
mount --bind /etc $chrootenvDest/host-etc
|
|
||||||
|
|
||||||
# Bind mount the host system's /tmp
|
|
||||||
mount --bind /tmp $chrootenvDest/host-tmp
|
|
||||||
|
|
||||||
# Bind mount /tmp
|
|
||||||
mount --bind /tmp/chrootenv-@name@ $chrootenvDest/tmp
|
|
||||||
|
|
||||||
# Expose sockets in /tmp
|
|
||||||
for i in /tmp/.*-unix; do
|
|
||||||
ln -s "/host-tmp/$(basename "$i")" "$chrootenvDest/$i"
|
|
||||||
done
|
|
|
@ -1,6 +0,0 @@
|
||||||
#! @shell@ -e
|
|
||||||
|
|
||||||
chrootenvDest=/run/chrootenv/@name@
|
|
||||||
|
|
||||||
# Unmount all (r)bind mounts
|
|
||||||
umount -l $chrootenvDest/{dev/pts,dev/shm,dev,nix/store,proc,sys,host-etc,host-tmp,home,var,tmp,run}
|
|
|
@ -2,16 +2,15 @@
|
||||||
|
|
||||||
# Bind mounts hierarchy: from => to (relative)
|
# Bind mounts hierarchy: from => to (relative)
|
||||||
# If 'to' is nil, path will be the same
|
# If 'to' is nil, path will be the same
|
||||||
mounts = { '/nix/store' => nil,
|
mounts = { '/' => 'host',
|
||||||
'/dev' => nil,
|
|
||||||
'/proc' => nil,
|
'/proc' => nil,
|
||||||
'/sys' => nil,
|
'/sys' => nil,
|
||||||
'/etc' => 'host-etc',
|
'/nix' => nil,
|
||||||
'/tmp' => 'host-tmp',
|
'/tmp' => nil,
|
||||||
'/home' => nil,
|
|
||||||
'/var' => nil,
|
'/var' => nil,
|
||||||
'/run' => nil,
|
'/run' => nil,
|
||||||
'/root' => nil,
|
'/dev' => nil,
|
||||||
|
'/home' => nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
# Propagate environment variables
|
# Propagate environment variables
|
||||||
|
@ -62,12 +61,15 @@ $mount = make_fcall 'mount', [Fiddle::TYPE_VOIDP,
|
||||||
Fiddle::TYPE_INT
|
Fiddle::TYPE_INT
|
||||||
|
|
||||||
# Read command line args
|
# Read command line args
|
||||||
abort "Usage: chrootenv swdir program args..." unless ARGV.length >= 2
|
abort "Usage: chrootenv program args..." unless ARGV.length >= 1
|
||||||
swdir = Pathname.new ARGV[0]
|
execp = ARGV
|
||||||
execp = ARGV.drop 1
|
|
||||||
|
|
||||||
# Populate extra mounts
|
# Populate extra mounts
|
||||||
if not ENV["CHROOTENV_EXTRA_BINDS"].nil?
|
if not ENV["CHROOTENV_EXTRA_BINDS"].nil?
|
||||||
|
$stderr.puts "CHROOTENV_EXTRA_BINDS is discussed for deprecation."
|
||||||
|
$stderr.puts "If you have a usecase, please drop a note in issue #16030."
|
||||||
|
$stderr.puts "Notice that we now bind-mount host FS to '/host' and symlink all directories from it to '/' by default."
|
||||||
|
|
||||||
for extra in ENV["CHROOTENV_EXTRA_BINDS"].split(':')
|
for extra in ENV["CHROOTENV_EXTRA_BINDS"].split(':')
|
||||||
paths = extra.split('=')
|
paths = extra.split('=')
|
||||||
if not paths.empty?
|
if not paths.empty?
|
||||||
|
@ -132,24 +134,6 @@ if $cpid == 0
|
||||||
Dir.chroot root
|
Dir.chroot root
|
||||||
Dir.chdir '/'
|
Dir.chdir '/'
|
||||||
|
|
||||||
# Symlink swdir hierarchy
|
|
||||||
mount_dirs = Set.new mounts.map { |_, v| Pathname.new v }
|
|
||||||
link_swdir = lambda do |swdir, prefix|
|
|
||||||
swdir.find do |path|
|
|
||||||
rel = prefix.join path.relative_path_from(swdir)
|
|
||||||
# Don't symlink anything in binded or symlinked directories
|
|
||||||
Find.prune if mount_dirs.include? rel or rel.symlink?
|
|
||||||
if not rel.directory?
|
|
||||||
# File does not exist; make a symlink and bail out
|
|
||||||
rel.make_symlink path
|
|
||||||
Find.prune
|
|
||||||
end
|
|
||||||
# Recursively follow symlinks
|
|
||||||
link_swdir.call path.readlink, rel if path.symlink?
|
|
||||||
end
|
|
||||||
end
|
|
||||||
link_swdir.call swdir, Pathname.new('')
|
|
||||||
|
|
||||||
# New environment
|
# New environment
|
||||||
new_env = Hash[ envvars.map { |x| [x, ENV[x]] } ]
|
new_env = Hash[ envvars.map { |x| [x, ENV[x]] } ]
|
||||||
|
|
||||||
|
|
|
@ -1,28 +1,29 @@
|
||||||
{ runCommand, lib, writeText, writeScriptBin, stdenv, ruby } :
|
{ callPackage, runCommand, lib, writeScript, stdenv, coreutils, ruby }:
|
||||||
{ env, runScript ? "bash", extraBindMounts ? [], extraInstallCommands ? "", meta ? {}, passthru ? {} } :
|
|
||||||
|
let buildFHSEnv = callPackage ./env.nix { }; in
|
||||||
|
|
||||||
|
args@{ name, runScript ? "bash", extraBindMounts ? [], extraInstallCommands ? "", meta ? {}, passthru ? {}, ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
name = env.pname;
|
env = buildFHSEnv (removeAttrs args [ "runScript" "extraBindMounts" "extraInstallCommands" "meta" "passthru" ]);
|
||||||
|
|
||||||
# Sandboxing script
|
# Sandboxing script
|
||||||
chroot-user = writeScriptBin "chroot-user" ''
|
chroot-user = writeScript "chroot-user" ''
|
||||||
#! ${ruby}/bin/ruby
|
#! ${ruby}/bin/ruby
|
||||||
${builtins.readFile ./chroot-user.rb}
|
${builtins.readFile ./chroot-user.rb}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
init = run: writeText "${name}-init" ''
|
init = run: writeScript "${name}-init" ''
|
||||||
source /etc/profile
|
#! ${stdenv.shell}
|
||||||
|
for i in ${env}/* /host/*; do
|
||||||
# Make /tmp directory
|
path="/''${i##*/}"
|
||||||
mkdir -m 1777 /tmp
|
[ -e "$path" ] || ${coreutils}/bin/ln -s "$i" "$path"
|
||||||
|
|
||||||
# Expose sockets in /tmp
|
|
||||||
for i in /host-tmp/.*-unix; do
|
|
||||||
ln -s "$i" "/tmp/$(basename "$i")"
|
|
||||||
done
|
done
|
||||||
|
|
||||||
[ -d "$1" ] && [ -r "$1" ] && cd "$1"
|
[ -d "$1" ] && [ -r "$1" ] && cd "$1"
|
||||||
shift
|
shift
|
||||||
|
|
||||||
|
source /etc/profile
|
||||||
exec ${run} "$@"
|
exec ${run} "$@"
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
@ -32,7 +33,7 @@ in runCommand name {
|
||||||
env = runCommand "${name}-shell-env" {
|
env = runCommand "${name}-shell-env" {
|
||||||
shellHook = ''
|
shellHook = ''
|
||||||
export CHROOTENV_EXTRA_BINDS="${lib.concatStringsSep ":" extraBindMounts}:$CHROOTENV_EXTRA_BINDS"
|
export CHROOTENV_EXTRA_BINDS="${lib.concatStringsSep ":" extraBindMounts}:$CHROOTENV_EXTRA_BINDS"
|
||||||
exec ${chroot-user}/bin/chroot-user ${env} bash ${init "bash"} "$(pwd)"
|
exec ${chroot-user} ${init "bash"} "$(pwd)"
|
||||||
'';
|
'';
|
||||||
} ''
|
} ''
|
||||||
echo >&2 ""
|
echo >&2 ""
|
||||||
|
@ -46,7 +47,7 @@ in runCommand name {
|
||||||
cat <<EOF >$out/bin/${name}
|
cat <<EOF >$out/bin/${name}
|
||||||
#! ${stdenv.shell}
|
#! ${stdenv.shell}
|
||||||
export CHROOTENV_EXTRA_BINDS="${lib.concatStringsSep ":" extraBindMounts}:\$CHROOTENV_EXTRA_BINDS"
|
export CHROOTENV_EXTRA_BINDS="${lib.concatStringsSep ":" extraBindMounts}:\$CHROOTENV_EXTRA_BINDS"
|
||||||
exec ${chroot-user}/bin/chroot-user ${env} bash ${init runScript} "\$(pwd)" "\$@"
|
exec ${chroot-user} ${init runScript} "\$(pwd)" "\$@"
|
||||||
EOF
|
EOF
|
||||||
chmod +x $out/bin/${name}
|
chmod +x $out/bin/${name}
|
||||||
${extraInstallCommands}
|
${extraInstallCommands}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{ nixpkgs, nixpkgs_i686, system
|
{ stdenv, buildEnv, writeText, pkgs, pkgsi686Linux, system }:
|
||||||
} :
|
|
||||||
{ name, profile ? ""
|
{ name, profile ? ""
|
||||||
, pkgs ? null, targetPkgs ? pkgs: [], multiPkgs ? pkgs: []
|
, targetPkgs ? pkgs: [], multiPkgs ? pkgs: []
|
||||||
, extraBuildCommands ? "", extraBuildCommandsMulti ? ""
|
, extraBuildCommands ? "", extraBuildCommandsMulti ? ""
|
||||||
, extraOutputsToInstall ? []
|
, extraOutputsToInstall ? []
|
||||||
}:
|
}:
|
||||||
|
@ -22,37 +22,32 @@
|
||||||
# /lib will link to /lib32
|
# /lib will link to /lib32
|
||||||
|
|
||||||
let
|
let
|
||||||
isMultiBuild = pkgs == null && multiPkgs != null && system == "x86_64-linux";
|
is64Bit = system == "x86_64-linux";
|
||||||
|
isMultiBuild = multiPkgs != null && is64Bit;
|
||||||
isTargetBuild = !isMultiBuild;
|
isTargetBuild = !isMultiBuild;
|
||||||
|
|
||||||
# support deprecated "pkgs" option.
|
|
||||||
targetPkgs' =
|
|
||||||
if pkgs != null
|
|
||||||
then builtins.trace "buildFHSEnv: 'pkgs' option is deprecated, use 'targetPkgs'" (pkgs': pkgs)
|
|
||||||
else targetPkgs;
|
|
||||||
|
|
||||||
# list of packages (usually programs) which are only be installed for the
|
# list of packages (usually programs) which are only be installed for the
|
||||||
# host's architecture
|
# host's architecture
|
||||||
targetPaths = targetPkgs' nixpkgs ++ (if multiPkgs == null then [] else multiPkgs nixpkgs);
|
targetPaths = targetPkgs pkgs ++ (if multiPkgs == null then [] else multiPkgs pkgs);
|
||||||
|
|
||||||
# list of packages which are installed for both x86 and x86_64 on x86_64
|
# list of packages which are installed for both x86 and x86_64 on x86_64
|
||||||
# systems
|
# systems
|
||||||
multiPaths = multiPkgs nixpkgs_i686;
|
multiPaths = multiPkgs pkgsi686Linux;
|
||||||
|
|
||||||
# base packages of the chroot
|
# base packages of the chroot
|
||||||
# these match the host's architecture, glibc_multi is used for multilib
|
# these match the host's architecture, glibc_multi is used for multilib
|
||||||
# builds.
|
# builds.
|
||||||
basePkgs = with nixpkgs;
|
basePkgs = with pkgs;
|
||||||
[ (if isMultiBuild then glibc_multi else glibc)
|
[ (if isMultiBuild then glibc_multi else glibc)
|
||||||
gcc.cc.lib bashInteractive coreutils less shadow su
|
(toString gcc.cc.lib) bashInteractive coreutils less shadow su
|
||||||
gawk diffutils findutils gnused gnugrep
|
gawk diffutils findutils gnused gnugrep
|
||||||
gnutar gzip bzip2 xz glibcLocales
|
gnutar gzip bzip2 xz glibcLocales
|
||||||
];
|
];
|
||||||
baseMultiPkgs = with nixpkgs_i686;
|
baseMultiPkgs = with pkgsi686Linux;
|
||||||
[ gcc.cc.lib
|
[ (toString gcc.cc.lib)
|
||||||
];
|
];
|
||||||
|
|
||||||
etcProfile = nixpkgs.writeText "profile" ''
|
etcProfile = writeText "profile" ''
|
||||||
export PS1='${name}-chrootenv:\u@\h:\w\$ '
|
export PS1='${name}-chrootenv:\u@\h:\w\$ '
|
||||||
export LOCALE_ARCHIVE='/usr/lib/locale/locale-archive'
|
export LOCALE_ARCHIVE='/usr/lib/locale/locale-archive'
|
||||||
export LD_LIBRARY_PATH='/run/opengl-driver/lib:/run/opengl-driver-32/lib:/usr/lib:/usr/lib32'
|
export LD_LIBRARY_PATH='/run/opengl-driver/lib:/run/opengl-driver-32/lib:/usr/lib:/usr/lib32'
|
||||||
|
@ -67,7 +62,7 @@ let
|
||||||
'';
|
'';
|
||||||
|
|
||||||
# Compose /etc for the chroot environment
|
# Compose /etc for the chroot environment
|
||||||
etcPkg = nixpkgs.stdenv.mkDerivation {
|
etcPkg = stdenv.mkDerivation {
|
||||||
name = "${name}-chrootenv-etc";
|
name = "${name}-chrootenv-etc";
|
||||||
buildCommand = ''
|
buildCommand = ''
|
||||||
mkdir -p $out/etc
|
mkdir -p $out/etc
|
||||||
|
@ -77,38 +72,38 @@ let
|
||||||
ln -s ${etcProfile} profile
|
ln -s ${etcProfile} profile
|
||||||
|
|
||||||
# compatibility with NixOS
|
# compatibility with NixOS
|
||||||
ln -s /host-etc/static static
|
ln -s /host/etc/static static
|
||||||
|
|
||||||
# symlink some NSS stuff
|
# symlink some NSS stuff
|
||||||
ln -s /host-etc/passwd passwd
|
ln -s /host/etc/passwd passwd
|
||||||
ln -s /host-etc/group group
|
ln -s /host/etc/group group
|
||||||
ln -s /host-etc/shadow shadow
|
ln -s /host/etc/shadow shadow
|
||||||
ln -s /host-etc/hosts hosts
|
ln -s /host/etc/hosts hosts
|
||||||
ln -s /host-etc/resolv.conf resolv.conf
|
ln -s /host/etc/resolv.conf resolv.conf
|
||||||
ln -s /host-etc/nsswitch.conf nsswitch.conf
|
ln -s /host/etc/nsswitch.conf nsswitch.conf
|
||||||
|
|
||||||
# symlink sudo and su stuff
|
# symlink sudo and su stuff
|
||||||
ln -s /host-etc/login.defs login.defs
|
ln -s /host/etc/login.defs login.defs
|
||||||
ln -s /host-etc/sudoers sudoers
|
ln -s /host/etc/sudoers sudoers
|
||||||
ln -s /host-etc/sudoers.d sudoers.d
|
ln -s /host/etc/sudoers.d sudoers.d
|
||||||
|
|
||||||
# symlink other core stuff
|
# symlink other core stuff
|
||||||
ln -s /host-etc/localtime localtime
|
ln -s /host/etc/localtime localtime
|
||||||
ln -s /host-etc/machine-id machine-id
|
ln -s /host/etc/machine-id machine-id
|
||||||
ln -s /host-etc/os-release os-release
|
ln -s /host/etc/os-release os-release
|
||||||
|
|
||||||
# symlink PAM stuff
|
# symlink PAM stuff
|
||||||
ln -s /host-etc/pam.d pam.d
|
ln -s /host/etc/pam.d pam.d
|
||||||
|
|
||||||
# symlink fonts stuff
|
# symlink fonts stuff
|
||||||
ln -s /host-etc/fonts fonts
|
ln -s /host/etc/fonts fonts
|
||||||
|
|
||||||
# symlink ALSA stuff
|
# symlink ALSA stuff
|
||||||
ln -s /host-etc/asound.conf asound.conf
|
ln -s /host/etc/asound.conf asound.conf
|
||||||
|
|
||||||
# symlink SSL certs
|
# symlink SSL certs
|
||||||
mkdir -p ssl
|
mkdir -p ssl
|
||||||
ln -s /host-etc/ssl/certs ssl/certs
|
ln -s /host/etc/ssl/certs ssl/certs
|
||||||
|
|
||||||
# symlink /etc/mtab -> /proc/mounts (compat for old userspace progs)
|
# symlink /etc/mtab -> /proc/mounts (compat for old userspace progs)
|
||||||
ln -s /proc/mounts mtab
|
ln -s /proc/mounts mtab
|
||||||
|
@ -116,26 +111,25 @@ let
|
||||||
};
|
};
|
||||||
|
|
||||||
# Composes a /usr-like directory structure
|
# Composes a /usr-like directory structure
|
||||||
staticUsrProfileTarget = nixpkgs.buildEnv {
|
staticUsrProfileTarget = buildEnv {
|
||||||
name = "${name}-usr-target";
|
name = "${name}-usr-target";
|
||||||
paths = [ etcPkg ] ++ basePkgs ++ targetPaths;
|
paths = [ etcPkg ] ++ basePkgs ++ targetPaths;
|
||||||
extraOutputsToInstall = [ "lib" "out" ] ++ extraOutputsToInstall;
|
extraOutputsToInstall = [ "out" "lib" "bin" ] ++ extraOutputsToInstall;
|
||||||
ignoreCollisions = true;
|
ignoreCollisions = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
staticUsrProfileMulti = nixpkgs.buildEnv {
|
staticUsrProfileMulti = buildEnv {
|
||||||
name = "${name}-usr-multi";
|
name = "${name}-usr-multi";
|
||||||
paths = baseMultiPkgs ++ multiPaths;
|
paths = baseMultiPkgs ++ multiPaths;
|
||||||
extraOutputsToInstall = [ "lib" "out" ] ++ extraOutputsToInstall;
|
extraOutputsToInstall = [ "out" "lib" ] ++ extraOutputsToInstall;
|
||||||
ignoreCollisions = true;
|
ignoreCollisions = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
# setup library paths only for the targeted architecture
|
# setup library paths only for the targeted architecture
|
||||||
setupLibDirs_target = ''
|
setupLibDirs_target = ''
|
||||||
mkdir -m0755 lib
|
# link content of targetPaths
|
||||||
|
cp -rsHf ${staticUsrProfileTarget}/lib lib
|
||||||
# copy content of targetPaths
|
ln -s lib lib${if is64Bit then "64" else "32"}
|
||||||
cp -rsHf ${staticUsrProfileTarget}/lib/* lib/
|
|
||||||
'';
|
'';
|
||||||
|
|
||||||
# setup /lib, /lib32 and /lib64
|
# setup /lib, /lib32 and /lib64
|
||||||
|
@ -184,7 +178,7 @@ let
|
||||||
done
|
done
|
||||||
'';
|
'';
|
||||||
|
|
||||||
in nixpkgs.stdenv.mkDerivation {
|
in stdenv.mkDerivation {
|
||||||
name = "${name}-fhs";
|
name = "${name}-fhs";
|
||||||
buildCommand = ''
|
buildCommand = ''
|
||||||
mkdir -p $out
|
mkdir -p $out
|
||||||
|
@ -196,7 +190,4 @@ in nixpkgs.stdenv.mkDerivation {
|
||||||
${if isMultiBuild then extraBuildCommandsMulti else ""}
|
${if isMultiBuild then extraBuildCommandsMulti else ""}
|
||||||
'';
|
'';
|
||||||
preferLocalBuild = true;
|
preferLocalBuild = true;
|
||||||
passthru = {
|
|
||||||
pname = name;
|
|
||||||
};
|
|
||||||
}
|
}
|
|
@ -118,29 +118,7 @@ in
|
||||||
|
|
||||||
buildEnv = callPackage ../build-support/buildenv { }; # not actually a package
|
buildEnv = callPackage ../build-support/buildenv { }; # not actually a package
|
||||||
|
|
||||||
buildFHSEnv = callPackage ../build-support/build-fhs-chrootenv/env.nix {
|
buildFHSUserEnv = callPackage ../build-support/build-fhs-userenv { };
|
||||||
nixpkgs = pkgs;
|
|
||||||
nixpkgs_i686 = pkgsi686Linux;
|
|
||||||
};
|
|
||||||
|
|
||||||
chrootFHSEnv = callPackage ../build-support/build-fhs-chrootenv { };
|
|
||||||
userFHSEnv = callPackage ../build-support/build-fhs-userenv {
|
|
||||||
ruby = ruby_2_1;
|
|
||||||
};
|
|
||||||
|
|
||||||
buildFHSChrootEnv = args: chrootFHSEnv {
|
|
||||||
env = buildFHSEnv (removeAttrs args [ "extraInstallCommands" ]);
|
|
||||||
extraInstallCommands = args.extraInstallCommands or "";
|
|
||||||
};
|
|
||||||
|
|
||||||
buildFHSUserEnv = args: userFHSEnv {
|
|
||||||
env = buildFHSEnv (removeAttrs args [ "runScript" "extraBindMounts" "extraInstallCommands" "meta" "passthru" ]);
|
|
||||||
runScript = args.runScript or "bash";
|
|
||||||
extraBindMounts = args.extraBindMounts or [];
|
|
||||||
extraInstallCommands = args.extraInstallCommands or "";
|
|
||||||
meta = args.meta or {};
|
|
||||||
passthru = args.passthru or {};
|
|
||||||
};
|
|
||||||
|
|
||||||
buildMaven = callPackage ../build-support/build-maven.nix {};
|
buildMaven = callPackage ../build-support/build-maven.nix {};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue