build-fhs-userenv: add extraBindMounts support

This commit is contained in:
Nikolay Amiantov 2015-10-06 15:30:17 +03:00
parent aeabfbe846
commit 5897433b31
2 changed files with 33 additions and 18 deletions

View file

@ -1,18 +1,18 @@
#!/usr/bin/env ruby
# Bind mounts hierarchy: [from, to (relative)]
# Bind mounts hierarchy: from => to (relative)
# If 'to' is nil, path will be the same
mounts = [ ['/nix/store', nil],
['/dev', nil],
['/proc', nil],
['/sys', nil],
['/etc', 'host-etc'],
['/tmp', 'host-tmp'],
['/home', nil],
['/var', nil],
['/run', nil],
['/root', nil],
]
mounts = { '/nix/store' => nil,
'/dev' => nil,
'/proc' => nil,
'/sys' => nil,
'/etc' => 'host-etc',
'/tmp' => 'host-tmp',
'/home' => nil,
'/var' => nil,
'/run' => nil,
'/root' => nil,
}
# Propagate environment variables
envvars = [ 'TERM',
@ -65,8 +65,22 @@ abort "Usage: chrootenv swdir program args..." unless ARGV.length >= 2
swdir = Pathname.new ARGV[0]
execp = ARGV.drop 1
# Populate extra mounts
if not ENV["CHROOTENV_EXTRA_BINDS"].nil?
for extra in ENV["CHROOTENV_EXTRA_BINDS"].split(':')
paths = extra.split('=')
if not paths.empty?
if paths.size <= 2
mounts[paths[0]] = paths[1]
else
$stderr.puts "Ignoring invalid entry in CHROOTENV_EXTRA_BINDS: #{extra}"
end
end
end
end
# Set destination paths for mounts
mounts.map! { |x| [x[0], x[1].nil? ? x[0].sub(/^\/*/, '') : x[1]] }
mounts = mounts.map { |k, v| [k, v.nil? ? k.sub(/^\/*/, '') : v] }.to_h
# Create temporary directory for root and chdir
root = Dir.mktmpdir 'chrootenv'
@ -97,10 +111,10 @@ if $cpid == 0
write_file '/proc/self/gid_map', "#{gid} #{gid} 1"
# Do rbind mounts.
mounts.each do |x|
to = "#{root}/#{x[1]}"
mounts.each do |from, rto|
to = "#{root}/#{rto}"
FileUtils.mkdir_p to
$mount.call x[0], to, nil, MS_BIND | MS_REC, nil
$mount.call from, to, nil, MS_BIND | MS_REC, nil
end
# Chroot!
@ -108,7 +122,7 @@ if $cpid == 0
Dir.chdir '/'
# Symlink swdir hierarchy
mount_dirs = Set.new mounts.map { |x| Pathname.new x[1] }
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)

View file

@ -1,4 +1,4 @@
{ runCommand, writeText, writeScriptBin, stdenv, ruby } : { env, runScript ? "bash" } :
{ runCommand, lib, writeText, writeScriptBin, stdenv, ruby } : { env, runScript ? "bash", extraBindMounts ? [] } :
let
name = env.pname;
@ -27,6 +27,7 @@ in runCommand name {
passthru.env =
runCommand "${name}-shell-env" {
shellHook = ''
export CHROOTENV_EXTRA_BINDS="${lib.makeSearchPath extraBindMounts}:$CHROOTENV_EXTRA_BINDS"
exec ${chroot-user}/bin/chroot-user ${env} bash -l ${init "bash"} "$(pwd)"
'';
} ''