bwrap 1.0.0.pre.alpha2 → 1.0.0.pre.beta1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +34 -0
- data/README.md +2 -0
- data/lib/bwrap/args/args.rb +5 -1
- data/lib/bwrap/args/bind/library.rb +125 -0
- data/lib/bwrap/args/bind/mime.rb +58 -0
- data/lib/bwrap/args/bind.rb +84 -28
- data/lib/bwrap/args/construct.rb +69 -35
- data/lib/bwrap/args/environment.rb +32 -1
- data/lib/bwrap/args/features.rb +103 -0
- data/lib/bwrap/args/library.rb +137 -0
- data/lib/bwrap/args/machine_id.rb +3 -2
- data/lib/bwrap/args/mount.rb +11 -3
- data/lib/bwrap/bwrap.rb +150 -0
- data/lib/bwrap/config/features.rb +81 -0
- data/lib/bwrap/config.rb +116 -16
- data/lib/bwrap/execution/exceptions.rb +24 -0
- data/lib/bwrap/execution/execute.rb +5 -2
- data/lib/bwrap/execution/execution.rb +147 -3
- data/lib/bwrap/execution/labels.rb +8 -1
- data/lib/bwrap/execution/path.rb +84 -0
- data/lib/bwrap/execution.rb +5 -173
- data/lib/bwrap/output/colors.rb +0 -2
- data/lib/bwrap/output/log.rb +4 -6
- data/lib/bwrap/output/output_impl.rb +181 -0
- data/lib/bwrap/output.rb +7 -149
- data/lib/bwrap/version.rb +1 -2
- data/lib/bwrap.rb +25 -71
- data.tar.gz.sig +0 -0
- metadata +17 -21
- metadata.gz.sig +0 -0
- data/lib/bwrap/output/output.rb +0 -8
@@ -0,0 +1,103 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "bwrap/output"
|
4
|
+
require_relative "args"
|
5
|
+
require_relative "library"
|
6
|
+
|
7
|
+
# Feature parameter construction.
|
8
|
+
#
|
9
|
+
# @see Config::Features
|
10
|
+
class Bwrap::Args::Features < Hash
|
11
|
+
include Bwrap::Output
|
12
|
+
|
13
|
+
# Implementation for Bash feature set.
|
14
|
+
#
|
15
|
+
# @api private
|
16
|
+
class BashBinds
|
17
|
+
# Mounts stuff like /bin/bash.
|
18
|
+
def bash_mounts
|
19
|
+
mounts = []
|
20
|
+
|
21
|
+
if File.file? "/bin/bash"
|
22
|
+
mounts << "--ro-bind" << "/bin/bash" << "/bin/bash"
|
23
|
+
end
|
24
|
+
if File.file? "/usr/bin/bash"
|
25
|
+
mounts << "--ro-bind" << "/usr/bin/bash" << "/usr/bin/bash"
|
26
|
+
end
|
27
|
+
|
28
|
+
mounts
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Implementation for Ruby feature set.
|
33
|
+
#
|
34
|
+
# @api private
|
35
|
+
class RubyBinds
|
36
|
+
# Returns mounts needed by Ruby feature set.
|
37
|
+
attr_reader :mounts
|
38
|
+
|
39
|
+
# Bind system paths so scripts works inside sandbox.
|
40
|
+
def sitedir_mounts
|
41
|
+
mounts = []
|
42
|
+
mounts << "--ro-bind" << RbConfig::CONFIG["sitedir"] << RbConfig::CONFIG["sitedir"]
|
43
|
+
mounts << "--ro-bind" << RbConfig::CONFIG["rubyhdrdir"] << RbConfig::CONFIG["rubyhdrdir"]
|
44
|
+
mounts << "--ro-bind" << RbConfig::CONFIG["rubylibdir"] << RbConfig::CONFIG["rubylibdir"]
|
45
|
+
mounts << "--ro-bind" << RbConfig::CONFIG["vendordir"] << RbConfig::CONFIG["vendordir"]
|
46
|
+
|
47
|
+
mounts
|
48
|
+
end
|
49
|
+
|
50
|
+
# Create binds for required system libraries.
|
51
|
+
#
|
52
|
+
# These are in path like /usr/lib64/ruby/2.5.0/x86_64-linux-gnu/,
|
53
|
+
# and as they are mostly shared libraries, they may have some extra
|
54
|
+
# dependencies that also need to be bound inside the sandbox.
|
55
|
+
def stdlib_mounts stdlib
|
56
|
+
library_mounts = []
|
57
|
+
library = Bwrap::Args::Library.new
|
58
|
+
stdlib.each do |lib|
|
59
|
+
path = "#{RbConfig::CONFIG["rubyarchdir"]}/#{lib}.so"
|
60
|
+
|
61
|
+
library.needed_libraries(path).each do |requisite_library|
|
62
|
+
library_mounts << "--ro-bind" << requisite_library << requisite_library
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
library_mounts
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# `Array` of parameters passed to bwrap.
|
71
|
+
attr_writer :args
|
72
|
+
|
73
|
+
# Instance of {Config}.
|
74
|
+
attr_writer :config
|
75
|
+
|
76
|
+
# Resolves binds required by different features.
|
77
|
+
#
|
78
|
+
# Currently implemented feature sets:
|
79
|
+
# - ruby
|
80
|
+
def feature_binds
|
81
|
+
bash_binds
|
82
|
+
ruby_binds
|
83
|
+
end
|
84
|
+
|
85
|
+
private def bash_binds
|
86
|
+
return unless @config.features.bash.enabled?
|
87
|
+
|
88
|
+
binds = BashBinds.new
|
89
|
+
|
90
|
+
@args.append binds.bash_mounts
|
91
|
+
end
|
92
|
+
|
93
|
+
# @note This does not allow development headers needed for compilation for now.
|
94
|
+
# I’ll look at it after I have an use for it.
|
95
|
+
private def ruby_binds
|
96
|
+
return unless @config.features.ruby.enabled?
|
97
|
+
|
98
|
+
binds = RubyBinds.new
|
99
|
+
|
100
|
+
@args.append binds.sitedir_mounts
|
101
|
+
@args.append binds.stdlib_mounts(@config.features.ruby.stdlib)
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "bwrap/execution"
|
4
|
+
require "bwrap/output"
|
5
|
+
require_relative "args"
|
6
|
+
|
7
|
+
# Class to clean up namespace for implementation specific reasons.
|
8
|
+
#
|
9
|
+
# @api private
|
10
|
+
class Bwrap::Args::Library
|
11
|
+
include Bwrap::Execution
|
12
|
+
include Bwrap::Output
|
13
|
+
|
14
|
+
# NOTE: This caching can be made more efficient, but need to look at it later, what to do about it.
|
15
|
+
@@needed_libraries_cache ||= []
|
16
|
+
|
17
|
+
# Empties {@@needed_libraries_cache}.
|
18
|
+
def self.clear_needed_libraries_cache
|
19
|
+
@@needed_libraries_cache.clear
|
20
|
+
end
|
21
|
+
|
22
|
+
# Otherwise similar to {#needed_libraries}, but checks used libc to handle musl executables.
|
23
|
+
#
|
24
|
+
# @param executable [String] Path to the executable to find dependencies for
|
25
|
+
def libraries_needed_by executable
|
26
|
+
# %i == interpreter, the library used to load the executable by kernel.
|
27
|
+
# %F == Path to given file.
|
28
|
+
output_format = "%i::SEPARATOR::%F"
|
29
|
+
scanelf_command = %W{ scanelf --nobanner --quiet --format #{output_format} }
|
30
|
+
scanelf_command << executable
|
31
|
+
|
32
|
+
data = execvalue scanelf_command
|
33
|
+
data = data.strip
|
34
|
+
interpreter, _executable_path = data.split "::SEPARATOR::"
|
35
|
+
interpreter = Pathname.new interpreter
|
36
|
+
|
37
|
+
if interpreter.basename.to_s[0..6] == "ld-musl"
|
38
|
+
musl_needed_libraries executable
|
39
|
+
else
|
40
|
+
# For glibc, scanelf can return full paths for us most of time.
|
41
|
+
needed_libraries executable
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# @param binary_paths [String, Array] one or more paths to be resolved
|
46
|
+
#
|
47
|
+
# @todo Maybe caching should be done here too?
|
48
|
+
def musl_needed_libraries binary_paths
|
49
|
+
trace "Finding musl libraries #{binary_paths} requires"
|
50
|
+
@needed_libraries = []
|
51
|
+
|
52
|
+
if binary_paths.is_a? String
|
53
|
+
binary_paths = [ binary_paths ]
|
54
|
+
end
|
55
|
+
|
56
|
+
binary_paths.each do |binary_path|
|
57
|
+
output = execvalue %W{ ldd #{binary_path} }
|
58
|
+
lines = output.split "\n"
|
59
|
+
_interpreter_line = lines.shift
|
60
|
+
|
61
|
+
lines.each do |line|
|
62
|
+
parse_ldd_line line
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
@needed_libraries
|
67
|
+
end
|
68
|
+
|
69
|
+
# Used by {Bwrap::Args::Bind#libs_command_requires}.
|
70
|
+
#
|
71
|
+
# @param binary_paths [String, Array] one or more paths to be resolved
|
72
|
+
def needed_libraries binary_paths
|
73
|
+
trace "Finding libraries #{binary_paths} requires"
|
74
|
+
@needed_libraries = []
|
75
|
+
|
76
|
+
# %i == interpreter, the library used to load the executable by kernel.
|
77
|
+
output_format = "%F::SEPARATOR::%n"
|
78
|
+
scanelf_command = %W{ scanelf --nobanner --quiet --format #{output_format} --ldcache --needed }
|
79
|
+
|
80
|
+
if binary_paths.is_a? String
|
81
|
+
binary_paths = [ binary_paths ]
|
82
|
+
end
|
83
|
+
|
84
|
+
# Check if the exe is already resolved.
|
85
|
+
binary_paths.delete_if do |binary_path|
|
86
|
+
@@needed_libraries_cache.include? binary_path
|
87
|
+
end
|
88
|
+
|
89
|
+
return [] if binary_paths.empty?
|
90
|
+
|
91
|
+
data = execvalue(scanelf_command + binary_paths)
|
92
|
+
trace "scanelf found following libraries: #{data}"
|
93
|
+
|
94
|
+
lines = data.split "\n"
|
95
|
+
lines.each do |line|
|
96
|
+
parse_scanelf_line line
|
97
|
+
end
|
98
|
+
|
99
|
+
@needed_libraries
|
100
|
+
end
|
101
|
+
|
102
|
+
# Used by {#needed_libraries}.
|
103
|
+
private def parse_scanelf_line line
|
104
|
+
binary_path, libraries_line = line.split "::SEPARATOR::"
|
105
|
+
libraries = libraries_line.split ","
|
106
|
+
|
107
|
+
(@needed_libraries & libraries).each do |library|
|
108
|
+
verb "Binding #{library} as dependency of #{binary_path}"
|
109
|
+
end
|
110
|
+
|
111
|
+
@needed_libraries |= libraries
|
112
|
+
|
113
|
+
# Also check if requisite libraries needs some libraries.
|
114
|
+
inner = Bwrap::Args::Library.new
|
115
|
+
@needed_libraries |= inner.needed_libraries libraries
|
116
|
+
|
117
|
+
@@needed_libraries_cache |= libraries
|
118
|
+
end
|
119
|
+
|
120
|
+
# Used by {#musl_needed_libraries}.
|
121
|
+
private def parse_ldd_line line
|
122
|
+
line = line.strip
|
123
|
+
_library_name, library_data = line.split " => "
|
124
|
+
|
125
|
+
matches = library_data.match(/(.*) \(0x[0-9a-f]+\)/)
|
126
|
+
library_path = matches[1]
|
127
|
+
|
128
|
+
unless @needed_libraries.include? library_path
|
129
|
+
@needed_libraries << library_path
|
130
|
+
end
|
131
|
+
|
132
|
+
# Also check if requisite libraries needs some libraries.
|
133
|
+
inner = Bwrap::Args::Library.new
|
134
|
+
@needed_libraries |= inner.musl_needed_libraries library_path
|
135
|
+
end
|
136
|
+
end
|
137
|
+
# class Library ended
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "securerandom"
|
4
|
+
require "tempfile"
|
4
5
|
|
5
6
|
require "bwrap/output"
|
6
7
|
require_relative "args"
|
@@ -24,7 +25,7 @@ class Bwrap::Args::MachineId
|
|
24
25
|
# Returning [] means that execute() will ignore this fully.
|
25
26
|
# Nil would be converted to empty string, causing spawn() to pass it as argument, causing
|
26
27
|
# bwrap to misbehave.
|
27
|
-
return
|
28
|
+
return unless @config.machine_id
|
28
29
|
|
29
30
|
machine_id = @config.machine_id
|
30
31
|
|
@@ -51,7 +52,7 @@ class Bwrap::Args::MachineId
|
|
51
52
|
debug "Using random machine id as /etc/machine-id"
|
52
53
|
|
53
54
|
@machine_id_file = Tempfile.new "bwrap-random_machine_id-", @config.tmpdir
|
54
|
-
@machine_id_file.write SecureRandom.uuid.
|
55
|
+
@machine_id_file.write SecureRandom.uuid.delete("-", "")
|
55
56
|
@machine_id_file.flush
|
56
57
|
|
57
58
|
%W{ --ro-bind-data #{machine_id_file.fileno} /etc/machine-id }
|
data/lib/bwrap/args/mount.rb
CHANGED
@@ -4,21 +4,29 @@ require_relative "args"
|
|
4
4
|
|
5
5
|
# Bind arguments for bwrap.
|
6
6
|
module Bwrap::Args::Mount
|
7
|
+
# Arguments for readwrite-binding {Config#root} as /.
|
8
|
+
private def root_mount
|
9
|
+
return unless @config.root
|
10
|
+
|
11
|
+
debug "Binding #{@config.root} as /"
|
12
|
+
@args.append %W{ --bind #{@config.root} / }
|
13
|
+
end
|
14
|
+
|
7
15
|
# Arguments for mounting devtmpfs to /dev.
|
8
16
|
private def dev_mount
|
9
17
|
debug "Mounting new devtmpfs to /dev"
|
10
|
-
%w{ --dev /dev }
|
18
|
+
@args.append %w{ --dev /dev }
|
11
19
|
end
|
12
20
|
|
13
21
|
# Arguments for mounting procfs to /proc.
|
14
22
|
private def proc_mount
|
15
23
|
debug "Mounting new procfs to /proc"
|
16
|
-
%w{ --proc /proc }
|
24
|
+
@args.append %w{ --proc /proc }
|
17
25
|
end
|
18
26
|
|
19
27
|
# Arguments for mounting tmpfs to /tmp.
|
20
28
|
private def tmp_as_tmpfs
|
21
29
|
debug "Mounting tmpfs to /tmp"
|
22
|
-
%w{ --tmpfs /tmp }
|
30
|
+
@args.append %w{ --tmpfs /tmp }
|
23
31
|
end
|
24
32
|
end
|
data/lib/bwrap/bwrap.rb
ADDED
@@ -0,0 +1,150 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#require "deep-cover" if ENV["DEEP_COVER"]
|
4
|
+
|
5
|
+
require "bwrap/version"
|
6
|
+
require "bwrap/args/construct"
|
7
|
+
require "bwrap/config"
|
8
|
+
require "bwrap/execution"
|
9
|
+
|
10
|
+
# Executes given command under {https://github.com/containers/bubblewrap bwrap}
|
11
|
+
# using given configuration.
|
12
|
+
#
|
13
|
+
# @see ::Bwrap Bwrap module for usage example
|
14
|
+
class Bwrap::Bwrap
|
15
|
+
include Bwrap::Execution
|
16
|
+
|
17
|
+
# @param config [Bwrap::Config] Configuration used to tailor bwrap
|
18
|
+
def initialize config
|
19
|
+
# TODO: Ensure that costruct.rb and utilities it uses does not enforce Config to be valid object.
|
20
|
+
# Create a test for that also. Well, as long as that makes sense. If it doesn’t work, validate
|
21
|
+
# Config object to be valid here.
|
22
|
+
@config = config
|
23
|
+
end
|
24
|
+
|
25
|
+
# Parses command line arguments given to caller script.
|
26
|
+
#
|
27
|
+
# @note This method automatically sets output levels according parsed
|
28
|
+
# options. It is also possible to set the levels manually using
|
29
|
+
# {Bwrap::Output.handle_output_options}, for example with flags
|
30
|
+
# parsed with optparse’s `OptionParser`, found in Ruby’s standard
|
31
|
+
# library.
|
32
|
+
#
|
33
|
+
# @warning Requires optimist gem to be installed, which is not a dependency of this gem.
|
34
|
+
def parse_command_line_arguments
|
35
|
+
options = parse_options
|
36
|
+
|
37
|
+
Bwrap::Output.handle_output_options options
|
38
|
+
end
|
39
|
+
|
40
|
+
# Binds and executes given command available on running system inside bwrap.
|
41
|
+
#
|
42
|
+
# If {Config#root} has been set, given executable is scanned for necessary
|
43
|
+
# libraries and they are bound inside sandbox. This often reduces amount of
|
44
|
+
# global binds, but some miscellaneous things may need custom handling.
|
45
|
+
#
|
46
|
+
# @see Config#features about binding bigger feature sets to sandbox.
|
47
|
+
#
|
48
|
+
# Executed command is constructed using configuration passed to constructor.
|
49
|
+
# After execution has completed, bwrap will also shut down.
|
50
|
+
#
|
51
|
+
# @param command [String, Array] Command to be executed inside bwrap along with necessary arguments
|
52
|
+
# @see #run_inside_root to execute a command that already is inside sandbox.
|
53
|
+
def run command
|
54
|
+
construct = Bwrap::Args::Construct.new
|
55
|
+
construct.command = command
|
56
|
+
construct.config = @config
|
57
|
+
bwrap_args = construct.construct_bwrap_args
|
58
|
+
|
59
|
+
exec_command = [ "bwrap" ]
|
60
|
+
exec_command += bwrap_args
|
61
|
+
exec_command.append command
|
62
|
+
exec_command += @cli_args if @cli_args
|
63
|
+
|
64
|
+
execute exec_command
|
65
|
+
|
66
|
+
construct.cleanup
|
67
|
+
end
|
68
|
+
|
69
|
+
# Convenience method to executes a command that is inside bwrap.
|
70
|
+
#
|
71
|
+
# Given command is expected to already be inside {Config#root}.
|
72
|
+
#
|
73
|
+
# Calling this method is equivalent to setting {Config#command_inside_root} to `true`.
|
74
|
+
#
|
75
|
+
# @note This may have a bit unintuitive usage, as most things are checked anyway, so this is not
|
76
|
+
# akin to running something inside a chroot, but rather for convenience.
|
77
|
+
#
|
78
|
+
# @param command [String, Array] Command to be executed inside bwrap along with necessary arguments
|
79
|
+
# @see #run to execute a command that needs to be bound to the sandbox.
|
80
|
+
def run_inside_root command
|
81
|
+
if @config
|
82
|
+
config = @config.dup
|
83
|
+
config.command_inside_root = true
|
84
|
+
else
|
85
|
+
config = nil
|
86
|
+
end
|
87
|
+
|
88
|
+
construct = Bwrap::Args::Construct.new
|
89
|
+
construct.command = command
|
90
|
+
construct.config = config
|
91
|
+
bwrap_args = construct.construct_bwrap_args
|
92
|
+
|
93
|
+
exec_command = [ "bwrap" ]
|
94
|
+
exec_command += bwrap_args
|
95
|
+
exec_command.append command
|
96
|
+
exec_command += @cli_args if @cli_args
|
97
|
+
|
98
|
+
execute exec_command
|
99
|
+
|
100
|
+
construct.cleanup
|
101
|
+
end
|
102
|
+
|
103
|
+
# Parses global bwrap flags using Optimist.
|
104
|
+
#
|
105
|
+
# Sets instance variable `@cli_args`.
|
106
|
+
#
|
107
|
+
# @warning Requires optimist gem to be installed, which is not a dependency of this gem.
|
108
|
+
#
|
109
|
+
# @api private
|
110
|
+
# @return [Hash] options parsed by `Optimist.options`
|
111
|
+
private def parse_options
|
112
|
+
begin
|
113
|
+
require "optimist"
|
114
|
+
rescue LoadError => e
|
115
|
+
puts "Failed to load optimist gem. In order to use Bwrap::Bwrap#parse_command_line_arguments, " \
|
116
|
+
"ensure optimist gem is present for example in your Gemfile."
|
117
|
+
puts
|
118
|
+
raise e
|
119
|
+
end
|
120
|
+
|
121
|
+
options = Optimist.options do
|
122
|
+
version ::Bwrap::VERSION
|
123
|
+
|
124
|
+
banner "Usage:"
|
125
|
+
banner " #{$PROGRAM_NAME} [global options]\n \n"
|
126
|
+
banner "Global options:"
|
127
|
+
opt :verbose,
|
128
|
+
"Show verbose output",
|
129
|
+
short: "v"
|
130
|
+
opt :debug,
|
131
|
+
"Show debug output (useful when debugging a problem)",
|
132
|
+
short: "d"
|
133
|
+
opt :trace,
|
134
|
+
"Show trace output (noisiest, probably not useful for most of time)",
|
135
|
+
short: :none
|
136
|
+
opt :version,
|
137
|
+
"Print version and exit",
|
138
|
+
short: "V"
|
139
|
+
opt :help,
|
140
|
+
"Show help message",
|
141
|
+
short: "h"
|
142
|
+
|
143
|
+
educate_on_error
|
144
|
+
end
|
145
|
+
|
146
|
+
@cli_args = ARGV.dup
|
147
|
+
|
148
|
+
options
|
149
|
+
end
|
150
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Bwrap::Config
|
4
|
+
# Methods to enable or disable feature sets to control various aspects of sandboxing.
|
5
|
+
class Features
|
6
|
+
# Defines Bash feature set.
|
7
|
+
class Bash
|
8
|
+
def enabled?
|
9
|
+
@enabled
|
10
|
+
end
|
11
|
+
|
12
|
+
def enable
|
13
|
+
@enabled = true
|
14
|
+
end
|
15
|
+
|
16
|
+
# Disable Bash feature set.
|
17
|
+
def disable
|
18
|
+
@enabled = false
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Defines Ruby feature set.
|
23
|
+
class Ruby
|
24
|
+
# Extra libraries to be loaded from `RbConfig::CONFIG["rubyarchdir"]`.
|
25
|
+
#
|
26
|
+
# @note This is only required to be called if extra dependencies are necessary.
|
27
|
+
# For example, psych.so requires libyaml.so.
|
28
|
+
#
|
29
|
+
# @note There is stdlib= method also. Yardoc is broken.
|
30
|
+
#
|
31
|
+
# @return [Array] list of needed libraries.
|
32
|
+
attr_reader :stdlib
|
33
|
+
|
34
|
+
def initialize
|
35
|
+
@stdlib = []
|
36
|
+
end
|
37
|
+
|
38
|
+
# @see enabled=
|
39
|
+
def enabled?
|
40
|
+
@enabled
|
41
|
+
end
|
42
|
+
|
43
|
+
# Enable Ruby feature set.
|
44
|
+
#
|
45
|
+
# Among others, binds `RbConfig::CONFIG["sitedir"]` so scripts works.
|
46
|
+
#
|
47
|
+
# @note This does not allow development headers needed for compilation for now.
|
48
|
+
# I’ll look at it after I have an use for it.
|
49
|
+
def enable
|
50
|
+
@enabled = true
|
51
|
+
end
|
52
|
+
|
53
|
+
# Disable Ruby feature set.
|
54
|
+
def disable
|
55
|
+
@enabled = false
|
56
|
+
end
|
57
|
+
|
58
|
+
# @see #stdlib
|
59
|
+
def stdlib= libs
|
60
|
+
# Just a little check to have error earlier.
|
61
|
+
libs.each do |lib|
|
62
|
+
unless File.exist? "#{RbConfig::CONFIG["rubyarchdir"]}/#{lib}.so"
|
63
|
+
raise "Library “#{lib}” passed to Bwrap::Config::Ruby.stdlib= does not exist."
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
@stdlib = libs
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# @return [Bash] Instance of feature class for Bash
|
72
|
+
def bash
|
73
|
+
@bash ||= Bash.new
|
74
|
+
end
|
75
|
+
|
76
|
+
# @return [Ruby] Instance of feature class for Ruby
|
77
|
+
def ruby
|
78
|
+
@ruby ||= Ruby.new
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|