bwrap 1.0.0.pre.alpha2 → 1.0.0.pre.beta1

Sign up to get free protection for your applications and to get access to all the features.
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.