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.
data/lib/bwrap/config.rb CHANGED
@@ -3,10 +3,20 @@
3
3
  require "bwrap/output"
4
4
  require "bwrap/version"
5
5
 
6
- # Represents configuration set by user for bwrap execution.
6
+ # Features classes, used through {Config#features}.
7
+ require_relative "config/features"
8
+
9
+ # Represents configuration used to tailor bwrap execution.
10
+ #
11
+ # @developer_note
12
+ # Logger methods (debug, warn and so on) can’t be used here as logger
13
+ # isn’t initialized before this class.
14
+ #
15
+ # For same reason, it’s not advised to execute anything here.
7
16
  #
8
- # Implementation NOTE: logger methods (debug, warn and so on) can’t be used here as logger
9
- # isn’t initialized before this class.
17
+ # Note that all attributes also have writers, even though they are not documented.
18
+ #
19
+ # @todo Add some documentation about syntax where necessary, like for #binaries_from.
10
20
  class Bwrap::Config
11
21
  attr_accessor :hostname
12
22
 
@@ -24,6 +34,9 @@ class Bwrap::Config
24
34
  # Given file as bound as /etc/machine_id.
25
35
  attr_accessor :machine_id
26
36
 
37
+ # Name of the user inside chroot.
38
+ #
39
+ # This is optional and defaults to no user.
27
40
  attr_accessor :user
28
41
 
29
42
  # Set to true to indicate we’re running a X.org application, meaning we need to do some extra holes,
@@ -32,22 +45,87 @@ class Bwrap::Config
32
45
  # @return [Boolean] Whether Xorg specific binds are used.
33
46
  attr_accessor :xorg_application
34
47
 
48
+ # Array of audio schemes usable inside chroot.
49
+ #
50
+ # Currently supports:
51
+ # - :pulseaudio
52
+ #
53
+ attr_accessor :audio
54
+
55
+ # @return [Boolean] true if network should be shared from host.
56
+ attr_accessor :share_net
57
+
58
+ # Causes libraries required by the executable given to {Bwrap#run} to be
59
+ # mounted inside sandbox.
60
+ #
61
+ # Often it is enough to use this flag instead of binding all system libraries
62
+ # using {#libdir_mounts=}
63
+ #
64
+ # @return [Boolean] true if Linux library loaders are mounted inside chroot
65
+ attr_accessor :full_system_mounts
66
+
67
+ # Set to true if basic system directories, like /usr/lib and /usr/lib64,
68
+ # should be bound inside chroot.
69
+ #
70
+ # /usr/bin can be mounted using {Config#binaries_from=}.
71
+ #
72
+ # Often it is enough to use {#full_system_mounts=} instead of binding all
73
+ # system libraries using this flag.
74
+ #
75
+ # @return [Boolean] true if libdirs are mounted to the chroot
76
+ attr_accessor :libdir_mounts
77
+
78
+ # Set to `true` if command given to {Bwrap::Bwrap#run} is expected to
79
+ # be inside sandbox, and not bound from host.
80
+ #
81
+ # @return [Boolean] `true` if executed command is inside sandbox
82
+ attr_accessor :command_inside_root
83
+
84
+ attr_accessor :extra_executables
85
+
35
86
  # Array of directories to be bind mounted and used to construct PATH environment variable.
36
87
  attr_reader :binaries_from
37
88
 
89
+ # TODO: Document this.
90
+ # TODO: I wonder if this should just be removed. I don’t know, this is a bit ...
91
+ # Well, I can see it can have some merit, but very hard to say.
38
92
  attr_reader :sandbox_directory
39
93
 
40
- # `Hash`[`Pathname`] => `Pathname` containing custom read-only binds.
94
+ # Use given directory as root. End result is similar to classic chroot.
95
+ attr_reader :root
96
+
97
+ # @overload ro_binds
98
+ # `Hash`[`Pathname`] => `Pathname` containing custom read-only binds.
99
+ # @overload ro_binds=
100
+ # Set given hash of paths to be bound with --ro-bind.
101
+ #
102
+ # Key is source path, value is destination path.
103
+ #
104
+ # Given source paths must exist.
41
105
  attr_reader :ro_binds
42
106
 
43
- # Path to temporary directory.
107
+ # @overload tmpdir
108
+ # Path to temporary directory.
109
+ #
110
+ # Defaults to Dir.tmpdir.
111
+ # @overload tmpdir=(dir)
112
+ # Sets given directory as temporary directory for certain operations.
44
113
  #
45
- # Defaults to Dir.tmpdir.
114
+ # @note Requires `dir` to be path to existing directory.
115
+ # @raise [RuntimeError] If given directory does not exist
116
+ # @param dir Path to temporary directory
46
117
  attr_reader :tmpdir
47
118
 
119
+ # Paths to be added to sandbox instance’s PATH environment variable.
120
+ #
121
+ # @see #add_env_path
122
+ attr_reader :env_paths
123
+
48
124
  def initialize
49
125
  @binaries_from = []
50
126
  @tmpdir = Dir.tmpdir
127
+ @audio = []
128
+ @env_paths = []
51
129
  end
52
130
 
53
131
  def binaries_from= array
@@ -61,6 +139,17 @@ class Bwrap::Config
61
139
  end
62
140
  end
63
141
 
142
+ # Enable or disable feature sets to control various aspects of sandboxing.
143
+ #
144
+ # @example To enable Ruby feature set
145
+ # @config.features.ruby = true
146
+ #
147
+ # @see {Features} List of available features
148
+ # @return [Features] Object used to toggle features
149
+ def features
150
+ @features ||= ::Bwrap::Config::Features.new
151
+ end
152
+
64
153
  def sandbox_directory= directory
65
154
  unless Dir.exist? directory
66
155
  raise "Given sandbox directory #{directory} does not exist. Please create it beforehand and setup to your needs."
@@ -69,14 +158,22 @@ class Bwrap::Config
69
158
  @sandbox_directory = directory
70
159
  end
71
160
 
72
- # Set given hash of paths to be bound with --ro-bind.
73
- #
74
- # Key is source path, value is destination path.
75
- #
76
- # Given source paths must exist.
161
+ # Directory used as writable root, akin to classic chroot.
162
+ def root= directory
163
+ unless Dir.exist? directory
164
+ raise "Given root directory #{directory} does not exist. Please create it beforehand and set up to your needs."
165
+ end
166
+
167
+ @root = directory
168
+ end
169
+
77
170
  def ro_binds= binds
78
171
  @ro_binds = {}
79
172
  binds.each do |source_path, destination_path|
173
+ if destination_path.nil?
174
+ raise "binds should be key-value storage of Strings, for example a Hash."
175
+ end
176
+
80
177
  source_path = Pathname.new source_path
81
178
  unless source_path.exist?
82
179
  raise "Given read only bind does not exist. Please check path “#{source_path}” is correct."
@@ -88,14 +185,17 @@ class Bwrap::Config
88
185
  end
89
186
  end
90
187
 
91
- # Sets given directory as temporary directory for certain operations.
92
- #
93
- # @note Requires `dir` to be path to existing directory.
94
- # @raise [RuntimeError] If given directory does not exist
95
- # @param dir Path to temporary directory
188
+ # See attr_accessor :tmpdir for documentation.
96
189
  def tmpdir= dir
97
190
  raise "Directory to be set as a temporary directory, “#{dir}”, does not exist." unless Dir.exist? dir
98
191
 
99
192
  @tmpdir = dir
100
193
  end
194
+
195
+ # Add a path to sandbox instance’s PATH environment variable.
196
+ #
197
+ # @param path [String] Path to be added added to PATH environment variable
198
+ def add_env_path path
199
+ @env_paths << path
200
+ end
101
201
  end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bwrap::Execution
4
+ # Unspecified execution related error.
5
+ class CommandError < StandardError
6
+ end
7
+
8
+ # Signifies that command execution has failed.
9
+ class ExecutionFailed < CommandError
10
+ end
11
+
12
+ # Thrown if given command was not found.
13
+ class CommandNotFound < CommandError
14
+ # Command that was looked at.
15
+ attr_reader :command
16
+
17
+ def initialize command:
18
+ @command = command
19
+ msg = "Failed to find #{command} from PATH."
20
+
21
+ super msg
22
+ end
23
+ end
24
+ end
@@ -3,11 +3,14 @@
3
3
  # force_encoding modifies string, so can’t freeze strings.
4
4
 
5
5
  require "bwrap/output"
6
+ require_relative "exceptions"
6
7
  require_relative "execution"
7
8
 
8
9
  # Methods that performs actual execution logic.
9
10
  #
10
- # @api internal
11
+ # @note This is kind of pseudo-internal API. Hopefully there won’t be breaking changes.
12
+ # But please use {Bwrap::Execution} instead of relying functionality of this class,
13
+ # outside of {.prepend_rootcmd}.
11
14
  class Bwrap::Execution::Execute
12
15
  include Bwrap::Output
13
16
 
@@ -95,7 +98,7 @@ class Bwrap::Execution::Execute
95
98
  # Stub to instruct implementation in subclass.
96
99
  def self.prepend_rootcmd command, rootcmd:
97
100
  raise NotImplementedError, "If rootcmd execution is necessary, monkey patch Bwrap::Execution::Execute " \
98
- "to add “self.prepend_rootcmd(command, rootcmd:)” method."
101
+ "to add “self.prepend_rootcmd(command, rootcmd:)” method."
99
102
  end
100
103
 
101
104
  # Used by `#handle_logging`.
@@ -1,8 +1,152 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "bwrap/version"
4
+ require "bwrap/output"
5
+ require_relative "exceptions"
6
+ require_relative "execute"
7
+ require_relative "path"
4
8
 
5
- # Generic execution functionality.
9
+ # Provides methods to execute commands and handle its output.
10
+ #
11
+ # Output can be controlled by using log levels of Output module.
12
+ #
13
+ # @example Executing a command
14
+ # class MyClass
15
+ # include Bwrap::Execution
16
+ #
17
+ # def my_method
18
+ # execute %w{ ls /dev/null }
6
19
  module Bwrap::Execution
7
- # Nyan.
8
- end
20
+ include Bwrap::Output
21
+ include Bwrap::Execution::Path
22
+
23
+ # Actual implementation of execution command. Can be used when static method is needed.
24
+ #
25
+ # @note When an array is given as a command, empty strings are passed as empty arguments.
26
+ #
27
+ # This means that `[ "foo", "bar" ]` passes one argument to "foo" command, when
28
+ # `[ "foo", "", "bar" ]` passes two arguments.
29
+ #
30
+ # This may or may not be what is assumed, so it can’t be fixed here. It is up to the
31
+ # command to decide how to handle empty arguments.
32
+ #
33
+ # Returns pid of executed command if wait is false.
34
+ # Returns command output if wait is true.
35
+ #
36
+ # fail == If true, an error is raised in case the command returns failure code.
37
+ #
38
+ # @param error if :show, warn()s output of the command is shown if execution failed.
39
+ #
40
+ # @see #execute
41
+ def self.do_execute command,
42
+ fail: true,
43
+ wait: true,
44
+ log: true,
45
+ direct_output: false,
46
+ env: {},
47
+ clear_env: false,
48
+ error: nil,
49
+ log_callback: 2,
50
+ rootcmd: nil
51
+ command = Execute.format_command command, rootcmd: rootcmd
52
+ Execute.handle_logging command, log_callback: log_callback, log: log, dry_run: @dry_run
53
+ return if @dry_run || Bwrap::Execution::Execute.dry_run
54
+
55
+ Execute.open_pipes direct_output
56
+
57
+ # If command is an array, there can’t be arrays inside the array.
58
+ # For convenience, the array is flattened here, so callers can construct commands more easily.
59
+ if command.respond_to? :flatten!
60
+ command.flatten!
61
+ end
62
+
63
+ # If command is string, splat operator (the *) does not do anything. If array, it expand the arguments.
64
+ # This causes spawning work correctly, as that’s how spawn() expects to have the argu
65
+ pid = spawn(env, *command, err: [ :child, :out ], out: Execute.w, unsetenv_others: clear_env)
66
+ output = Execute.finish_execution(log: log, wait: wait, direct_output: direct_output)
67
+ return pid unless wait
68
+
69
+ # This is instant return, but allows us to have $?/$CHILD_STATUS set.
70
+ Process.wait pid
71
+ @last_status = $CHILD_STATUS
72
+
73
+ output = Execute.process_output output: output
74
+ Execute.handle_execution_fail fail: fail, error: error, output: output
75
+ output
76
+ ensure
77
+ Execute.clean_variables
78
+ end
79
+
80
+ # Returns Process::Status instance of last execution.
81
+ #
82
+ # @note This only is able to return the status if wait is true, as otherwise caller is assumed to
83
+ # handle execution flow.
84
+ def self.last_status
85
+ @last_status
86
+ end
87
+
88
+ # Execute a command.
89
+ #
90
+ # This method can be used by including Execution module in a class that should be able to
91
+ # execute commands.
92
+ #
93
+ # @see .do_execute .do_execute for documentation of argument syntax
94
+ private def execute *args
95
+ # Mangle proper location to error message.
96
+ if args.last.is_a? Hash
97
+ args.last[:log_callback] = 3
98
+ else
99
+ args << { log_callback: 3 }
100
+ end
101
+ Bwrap::Execution.do_execute(*args)
102
+ end
103
+
104
+ # Same as ::execute, but uses log: false to avoid unnecessary output when we’re just getting a
105
+ # value for internal needs.
106
+ #
107
+ # Defaults to fail: false, since when one just wants to get the value, there is not that much
108
+ # need to unconditionally die if getting bad exit code.
109
+ private def execvalue *args, fail: false, rootcmd: nil, env: {}
110
+ # This logging handling is a bit of duplication from execute(), but to be extra safe, it is duplicated.
111
+ # The debug message contents will always be evaluated, so can just do it like this.
112
+ log_command = args[0].respond_to?(:join) && args[0].join(" ") || args[0]
113
+ log_command =
114
+ if log_command.frozen?
115
+ log_command.dup.force_encoding("UTF-8")
116
+ else
117
+ log_command.force_encoding("UTF-8")
118
+ end
119
+ if @dry_run
120
+ puts "Would execvalue “#{log_command}” at #{caller_locations(1, 1)[0]}"
121
+ return
122
+ end
123
+ trace "Execvaluing “#{log_command}” at #{caller_locations(1, 1)[0]}"
124
+ execute(*args, fail: fail, log: false, rootcmd: rootcmd, env: env)
125
+ end
126
+
127
+ private def exec_success?
128
+ $CHILD_STATUS.success?
129
+ end
130
+
131
+ private def exec_failure?
132
+ !exec_success?
133
+ end
134
+
135
+ # When running through bundler, don’t use whatever it defines as we’re running inside chroot.
136
+ private def clean_execute
137
+ if (Bundler&.bundler_major_version) >= 2
138
+ Bundler.with_unbundled_env do
139
+ yield 2
140
+ end
141
+ elsif Bundler&.bundler_major_version == 1
142
+ Bundler.with_clean_env do
143
+ yield 1
144
+ end
145
+ else
146
+ yield nil
147
+ end
148
+ rescue NameError
149
+ # If NameError is thrown, no Bundler is available.
150
+ yield nil
151
+ end
152
+ end
@@ -1,7 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "bwrap/version"
4
- require_relative "execution"
4
+
5
+ # Just declaring the module here so full Execution module
6
+ # doesn’t need to be required just to have labels.
7
+ #
8
+ # Most users probably should just require bwrap/execution directly
9
+ # instead of this file, but bwrap/output.rb benefits from this.
10
+ module Bwrap::Execution
11
+ end
5
12
 
6
13
  # Exit codes for exit status handling.
7
14
  #
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bwrap/output"
4
+ require_relative "exceptions"
5
+
6
+ # Path checking methods.
7
+ module Bwrap::Execution::Path
8
+ # Utilities to handle environment path operations.
9
+ #
10
+ # @api private
11
+ class Environment
12
+ # Loop through each path in global PATH environment variable to
13
+ # perform an operation in each path, for example to resolve
14
+ # absolute path to a command.
15
+ #
16
+ # NOTE: This has nothing to do with {Bwrap::Config#env_paths}, as the
17
+ # env paths looped are what the system has defined, in ENV["PATH"].
18
+ #
19
+ # Should be cross-platform.
20
+ #
21
+ # @yield Command appended to each path in PATH environment variable
22
+ # @yieldparam path [String] Full path to executable
23
+ def self.each_env_path command, env_path_var: ENV["PATH"]
24
+ exts = ENV["PATHEXT"] ? ENV["PATHEXT"].split(";") : [ "" ]
25
+
26
+ env_path_var.split(File::PATH_SEPARATOR).each do |env_path|
27
+ exts.each do |ext|
28
+ exe = File.join(env_path, "#{command}#{ext}")
29
+ yield exe
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ # Check if requested program can be found.
36
+ #
37
+ # Should work cross-platform and in restricted environments pretty well.
38
+ #
39
+ # @param command [String] executable to be resolved
40
+ # @param env_path_var [String] PATH environment variable as string.
41
+ # Defaults to `ENV["PATH"]`
42
+ private def command_available? command, env_path_var: ENV["PATH"]
43
+ # Special handling for absolute paths.
44
+ path = Pathname.new command
45
+ if path.absolute?
46
+ if path.executable? && !path.directory?
47
+ return true
48
+ end
49
+
50
+ return false
51
+ end
52
+
53
+ Bwrap::Execution::Path::Environment.each_env_path command, env_path_var: env_path_var do |exe|
54
+ return true if File.executable?(exe) && !File.directory?(exe)
55
+ end
56
+
57
+ false
58
+ end
59
+
60
+ # Returns path to given executable.
61
+ #
62
+ # @param (see #command_available?)
63
+ private def which command, fail: true, env_path_var: ENV["PATH"]
64
+ # Special handling for absolute paths.
65
+ path = Pathname.new command
66
+ if path.absolute?
67
+ if path.executable?
68
+ return command
69
+ end
70
+
71
+ raise Bwrap::Execution::CommandNotFound.new command: command if fail
72
+
73
+ return nil
74
+ end
75
+
76
+ Bwrap::Execution::Path::Environment.each_env_path command, env_path_var: env_path_var do |exe|
77
+ return exe if File.executable?(exe) && !File.directory?(exe)
78
+ end
79
+
80
+ return nil unless fail
81
+
82
+ raise Bwrap::Execution::CommandNotFound.new command: command
83
+ end
84
+ end
@@ -1,177 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "bwrap/version"
4
- require "bwrap/output"
5
- require_relative "execution/execute"
6
-
7
- # @abstract Module to be included in a class that needs to execute commands.
8
- #
9
- # Methods to execute processes.
3
+ # Declare Execution module here so Bwrap::Execution module is
4
+ # already declared for Execution module classes, to avoid
5
+ # a circular dependency.
10
6
  module Bwrap::Execution
11
- include Bwrap::Output
12
-
13
- # Unspecified execution related error.
14
- class CommandError < StandardError
15
- end
16
-
17
- # Signifies that command execution has failed.
18
- class ExecutionFailed < CommandError
19
- end
20
-
21
- # Actual implementation of execution command. Can be used when static method is needed.
22
- #
23
- # @note When an array is given as a command, empty strings are passed as empty arguments.
24
- #
25
- # This means that `[ "foo", "bar" ]` passes one argument to "foo" command, when
26
- # `[ "foo", "", "bar" ]` passes two arguments.
27
- #
28
- # This may or may not be what is assumed, so it can’t be fixed here. It is up to the
29
- # command to decide how to handle empty arguments.
30
- #
31
- # Returns pid of executed command if wait is false.
32
- # Returns command output if wait is true.
33
- #
34
- # fail == If true, an error is raised in case the command returns failure code.
35
- #
36
- # @param error if :show, warn()s output of the command is shown if execution failed.
37
- #
38
- # @see #execute
39
- def self.do_execute command,
40
- fail: true,
41
- wait: true,
42
- log: true,
43
- direct_output: false,
44
- env: {},
45
- clear_env: false,
46
- error: nil,
47
- log_callback: 2,
48
- rootcmd: nil
49
- command = Execute.format_command command, rootcmd: rootcmd
50
- Execute.handle_logging command, log_callback: log_callback, log: log, dry_run: @dry_run
51
- return if @dry_run || Bwrap::Execution::Execute.dry_run
52
-
53
- Execute.open_pipes direct_output
54
-
55
- # If command is an array, there can’t be arrays inside the array.
56
- # For convenience, the array is flattened here, so callers can construct commands more easily.
57
- if command.respond_to? :flatten!
58
- command.flatten!
59
- end
60
-
61
- # If command is string, splat operator (the *) does not do anything. If array, it expand the arguments.
62
- # This causes spawning work correctly, as that’s how spawn() expects to have the argu
63
- pid = spawn(env, *command, err: [ :child, :out ], out: Execute.w, unsetenv_others: clear_env)
64
- output = Execute.finish_execution(log: log, wait: wait, direct_output: direct_output)
65
- return pid unless wait
66
-
67
- # This is instant return, but allows us to have $?/$CHILD_STATUS set.
68
- Process.wait pid
69
- @last_status = $CHILD_STATUS
70
-
71
- output = Execute.process_output output: output
72
- Execute.handle_execution_fail fail: fail, error: error, output: output
73
- output
74
- ensure
75
- Execute.clean_variables
76
- end
77
-
78
- # Returns Process::Status instance of last execution.
79
- #
80
- # @note This only is able to return the status if wait is true, as otherwise caller is assumed to
81
- # handle execution flow.
82
- def self.last_status
83
- @last_status
84
- end
85
-
86
- # Check if requested program can be found.
87
- #
88
- # Should work cross-platform and in restricted environents pretty well.
89
- private def command_available? command
90
- exts = ENV["PATHEXT"] ? ENV["PATHEXT"].split(";") : [ "" ]
91
- ENV["PATH"].split(File::PATH_SEPARATOR).each do |path|
92
- exts.each do |ext|
93
- exe = File.join(path, "#{command}#{ext}")
94
- return true if File.executable?(exe) && !File.directory?(exe)
95
- end
96
- end
97
- false
98
- end
99
-
100
- # Returns path to given executable.
101
- private def which command, fail: true
102
- exts = ENV["PATHEXT"] ? ENV["PATHEXT"].split(";") : [ "" ]
103
- ENV["PATH"].split(File::PATH_SEPARATOR).each do |path|
104
- exts.each do |ext|
105
- exe = File.join(path, "#{command}#{ext}")
106
- return exe if File.executable?(exe) && !File.directory?(exe)
107
- end
108
- end
109
- error "Failed to find #{command} from PATH." if fail
110
- nil
111
- end
112
-
113
- # Execute a command.
114
- #
115
- # This method can be used by including Execution module in a class that should be able to
116
- # execute commands.
117
- #
118
- # @see .do_execute .do_execute for documentation of argument syntax
119
- private def execute *args
120
- # Mangle proper location to error message.
121
- if args.last.is_a? Hash
122
- args.last[:log_callback] = 3
123
- else
124
- args << { log_callback: 3 }
125
- end
126
- Bwrap::Execution.do_execute(*args)
127
- end
128
-
129
- # Same as ::execute, but uses log: false to avoid unnecessary output when we’re just getting a
130
- # value for internal needs.
131
- #
132
- # Defaults to fail: false, since when one just wants to get the value, there is not that much
133
- # need to unconditionally die if getting bad exit code.
134
- private def execvalue *args, fail: false, rootcmd: nil, env: {}
135
- # This logging handling is a bit of duplication from execute(), but to be extra safe, it is duplicated.
136
- # The debug message contents will always be evaluated, so can just do it like this.
137
- log_command = args[0].respond_to?(:join) && args[0].join(" ") || args[0]
138
- log_command =
139
- if log_command.frozen?
140
- log_command.dup.force_encoding("UTF-8")
141
- else
142
- log_command.force_encoding("UTF-8")
143
- end
144
- if @dry_run
145
- puts "Would execvalue “#{log_command}” at #{caller_locations(1, 1)[0]}"
146
- return
147
- end
148
- trace "Execvaluing “#{log_command}” at #{caller_locations(1, 1)[0]}"
149
- execute(*args, fail: fail, log: false, rootcmd: rootcmd, env: env)
150
- end
151
-
152
- private def exec_success?
153
- $CHILD_STATUS.success?
154
- end
155
-
156
- private def exec_failure?
157
- !exec_success?
158
- end
159
-
160
- # When running through bundler, don’t use whatever it defines as we’re running inside chroot.
161
- private def clean_execute
162
- if (Bundler&.bundler_major_version) >= 2
163
- Bundler.with_unbundled_env do
164
- yield 2
165
- end
166
- elsif Bundler&.bundler_major_version == 1
167
- Bundler.with_clean_env do
168
- yield 1
169
- end
170
- else
171
- yield nil
172
- end
173
- rescue NameError
174
- # If NameError is thrown, no Bundler is available.
175
- yield nil
176
- end
177
7
  end
8
+
9
+ require_relative "execution/execution"
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "output"
4
-
5
3
  # Methods to color CLI output.
6
4
  module Bwrap::Output::Colors
7
5
  # Outputs ANSI true color sequence.