build-fhs-userenv: add extraBindMounts support
This commit is contained in:
parent
aeabfbe846
commit
5897433b31
2 changed files with 33 additions and 18 deletions
|
@ -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)
|
||||
|
|
|
@ -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)"
|
||||
'';
|
||||
} ''
|
||||
|
|
Loading…
Reference in a new issue