build-fhs-userenv: add extraBindMounts support
This commit is contained in:
parent
aeabfbe846
commit
5897433b31
@ -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)
|
||||||
|
@ -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)"
|
||||||
'';
|
'';
|
||||||
} ''
|
} ''
|
||||||
|
Loading…
x
Reference in New Issue
Block a user