Class: Mountfd::UserNamespace
- Inherits:
-
Object
- Object
- Mountfd::UserNamespace
- Defined in:
- lib/mountfd/user_namespace.rb,
sig/mountfd.rbs
Constant Summary collapse
- MAX_RANGES =
340
Class Method Summary collapse
- .create(uid: {0 => Process.uid}, gid: {0 => Process.gid}, helper: :auto) ⇒ UserNamespace
- .from_path(path) ⇒ UserNamespace
- .from_pid(pid) ⇒ UserNamespace
- .normalize(mapping) ⇒ Array[[Integer, Integer, Integer]]
Instance Method Summary collapse
- #close ⇒ nil
- #closed? ⇒ Boolean
- #fileno ⇒ Integer
-
#initialize(handle) ⇒ UserNamespace
constructor
A new instance of UserNamespace.
Constructor Details
#initialize(handle) ⇒ UserNamespace
Returns a new instance of UserNamespace.
76 77 78 |
# File 'lib/mountfd/user_namespace.rb', line 76 def initialize(handle) @handle = handle end |
Class Method Details
.create(uid: {0 => Process.uid}, gid: {0 => Process.gid}, helper: :auto) ⇒ UserNamespace
7 8 9 10 11 12 13 14 15 16 17 18 |
# File 'lib/mountfd/user_namespace.rb', line 7 def self.create(uid: {0 => Process.uid}, gid: {0 => Process.gid}, helper: :auto) uid_map = normalize(uid) gid_map = normalize(gid) use_helper = case helper when :auto then helpers_available? && !Process.euid.zero? when true, false then helper else raise ArgumentError, "helper must be :auto, true, or false" end new(Native.user_namespace(format(uid_map), format(gid_map), use_helper)) rescue SystemCallError => error raise IdmapError, "user namespace: #{error.}", cause: error end |
.from_path(path) ⇒ UserNamespace
21 |
# File 'lib/mountfd/user_namespace.rb', line 21 def self.from_path(path) = new(Native.open_handle(File.path(path))) |
.from_pid(pid) ⇒ UserNamespace
20 |
# File 'lib/mountfd/user_namespace.rb', line 20 def self.from_pid(pid) = from_path("/proc/#{Integer(pid)}/ns/user") |
.normalize(mapping) ⇒ Array[[Integer, Integer, Integer]]
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/mountfd/user_namespace.rb', line 23 def self.normalize(mapping) ranges = if mapping.is_a?(Hash) mapping.map do |inside, outside| if outside.is_a?(Array) && outside.length != 2 raise ArgumentError, "hash mapping values must be an ID or [ID, length]" end outside, length = outside.is_a?(Array) ? outside : [outside, 1] [inside, outside, length] end elsif mapping.is_a?(Array) && mapping.length == 3 && mapping.none? { _1.is_a?(Array) } [mapping] else Array(mapping) end ranges = ranges.map do |range| raise ArgumentError, "each namespace mapping must contain three integers" unless range.is_a?(Array) && range.length == 3 range.map { Integer(_1) } end.sort_by(&:first) raise ArgumentError, "a namespace mapping requires at least one range" if ranges.empty? raise ArgumentError, "namespace mappings are limited to #{MAX_RANGES} ranges" if ranges.length > MAX_RANGES ranges.each do |inside, outside, length| raise ArgumentError, "mapping IDs must be non-negative" if inside.negative? || outside.negative? raise ArgumentError, "mapping length must be positive" unless length.positive? if inside + length > 2**32 || outside + length > 2**32 raise ArgumentError, "mapping ranges must fit unsigned 32-bit IDs" end end validate_non_overlapping!(ranges, 0, "inside") validate_non_overlapping!(ranges, 1, "outside") ranges end |
Instance Method Details
#close ⇒ nil
82 |
# File 'lib/mountfd/user_namespace.rb', line 82 def close = @handle.close |
#closed? ⇒ Boolean
81 |
# File 'lib/mountfd/user_namespace.rb', line 81 def closed? = @handle.closed? |
#fileno ⇒ Integer
80 |
# File 'lib/mountfd/user_namespace.rb', line 80 def fileno = @handle.fileno |