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 #!/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 # If 'to' is nil, path will be the same
mounts = [ ['/nix/store', nil], mounts = { '/nix/store' => nil,
['/dev', nil], '/dev' => nil,
['/proc', nil], '/proc' => nil,
['/sys', nil], '/sys' => nil,
['/etc', 'host-etc'], '/etc' => 'host-etc',
['/tmp', 'host-tmp'], '/tmp' => 'host-tmp',
['/home', nil], '/home' => nil,
['/var', nil], '/var' => nil,
['/run', nil], '/run' => nil,
['/root', nil], '/root' => nil,
] }
# Propagate environment variables # Propagate environment variables
envvars = [ 'TERM', envvars = [ 'TERM',
@ -65,8 +65,22 @@ abort "Usage: chrootenv swdir program args..." unless ARGV.length >= 2
swdir = Pathname.new ARGV[0] swdir = Pathname.new ARGV[0]
execp = ARGV.drop 1 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 # 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 # Create temporary directory for root and chdir
root = Dir.mktmpdir 'chrootenv' root = Dir.mktmpdir 'chrootenv'
@ -97,10 +111,10 @@ if $cpid == 0
write_file '/proc/self/gid_map', "#{gid} #{gid} 1" write_file '/proc/self/gid_map', "#{gid} #{gid} 1"
# Do rbind mounts. # Do rbind mounts.
mounts.each do |x| mounts.each do |from, rto|
to = "#{root}/#{x[1]}" to = "#{root}/#{rto}"
FileUtils.mkdir_p to 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 end
# Chroot! # Chroot!
@ -108,7 +122,7 @@ if $cpid == 0
Dir.chdir '/' Dir.chdir '/'
# Symlink swdir hierarchy # 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| link_swdir = lambda do |swdir, prefix|
swdir.find do |path| swdir.find do |path|
rel = prefix.join path.relative_path_from(swdir) 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 let
name = env.pname; name = env.pname;
@ -27,6 +27,7 @@ in runCommand name {
passthru.env = passthru.env =
runCommand "${name}-shell-env" { runCommand "${name}-shell-env" {
shellHook = '' shellHook = ''
export CHROOTENV_EXTRA_BINDS="${lib.makeSearchPath extraBindMounts}:$CHROOTENV_EXTRA_BINDS"
exec ${chroot-user}/bin/chroot-user ${env} bash -l ${init "bash"} "$(pwd)" exec ${chroot-user}/bin/chroot-user ${env} bash -l ${init "bash"} "$(pwd)"
''; '';
} '' } ''