cheetah 0.5.2 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +6 -0
- data/VERSION +1 -1
- data/lib/cheetah/version.rb +1 -1
- data/lib/cheetah.rb +58 -53
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bd4cbe464be1d5ee56434c1a380d958cf0cbcb40095d8f21fcfb3cf7b2320db2
|
4
|
+
data.tar.gz: 3572805d086b24911c1feb6169b5911723a918fcf1ca0547d2f28984e0827ade
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 032f86dbf253379e1663e01d03f8a5a013a13829e4bb5b9c3f880d73611a2c92176e51086402b604cfd20a30d28dfa1571766b9fa2e4eb5377e4c12a6bda1b39
|
7
|
+
data.tar.gz: 1ecf8c2ff66d2eef73b658f925bbb5a7c6292861ce4fd52a9f2ed6fab91e49f3ba25fe5cd84f8da294b6340887872c9ef5100f2799fa8f8c319afbcead8ced3e
|
data/CHANGELOG
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
1.0.0
|
data/lib/cheetah/version.rb
CHANGED
data/lib/cheetah.rb
CHANGED
@@ -5,7 +5,7 @@ require "logger"
|
|
5
5
|
require "shellwords"
|
6
6
|
require "stringio"
|
7
7
|
|
8
|
-
require File.expand_path(File.dirname(__FILE__)
|
8
|
+
require File.expand_path("#{File.dirname(__FILE__)}/cheetah/version")
|
9
9
|
|
10
10
|
# Your swiss army knife for executing external commands in Ruby safely and
|
11
11
|
# conveniently.
|
@@ -121,6 +121,7 @@ module Cheetah
|
|
121
121
|
#
|
122
122
|
# @abstract
|
123
123
|
# @param [Process::Status] status the executed command exit status
|
124
|
+
# @param [Boolean] allowed_status whether the exit code is in the list of allowed exit codes
|
124
125
|
abstract_method :record_status
|
125
126
|
end
|
126
127
|
|
@@ -135,7 +136,7 @@ module Cheetah
|
|
135
136
|
|
136
137
|
def record_stderr(_stderr); end
|
137
138
|
|
138
|
-
def record_status(_status);
|
139
|
+
def record_status(_status, _allowed_status); end
|
139
140
|
end
|
140
141
|
|
141
142
|
# A default recorder. It uses the `Logger::INFO` level for normal messages and
|
@@ -150,6 +151,8 @@ module Cheetah
|
|
150
151
|
}.freeze
|
151
152
|
|
152
153
|
def initialize(logger)
|
154
|
+
super()
|
155
|
+
|
153
156
|
@logger = logger
|
154
157
|
|
155
158
|
@stream_used = { stdin: false, stdout: false, stderr: false }
|
@@ -172,19 +175,19 @@ module Cheetah
|
|
172
175
|
log_stream_increment(:stderr, stderr)
|
173
176
|
end
|
174
177
|
|
175
|
-
def record_status(status)
|
178
|
+
def record_status(status, allowed_status)
|
176
179
|
log_stream_remainder(:stdin)
|
177
180
|
log_stream_remainder(:stdout)
|
178
181
|
log_stream_remainder(:stderr)
|
179
182
|
|
180
|
-
@logger.send
|
183
|
+
@logger.send allowed_status ? :info : :error,
|
181
184
|
"Status: #{status.exitstatus}"
|
182
185
|
end
|
183
186
|
|
184
187
|
protected
|
185
188
|
|
186
189
|
def format_commands(commands)
|
187
|
-
|
190
|
+
"\"#{commands.map { |c| Shellwords.join(c) }.join(' | ')}\""
|
188
191
|
end
|
189
192
|
|
190
193
|
def log_stream_increment(stream, data)
|
@@ -402,14 +405,19 @@ module Cheetah
|
|
402
405
|
select_loop(streams, pipes, recorder)
|
403
406
|
_pid, status = Process.wait2(pid)
|
404
407
|
|
405
|
-
# when more exit status are allowed, then
|
406
|
-
# not
|
407
|
-
|
408
|
+
# when more exit status are allowed, then pass it below that it did
|
409
|
+
# not fail (bsc#1153749)
|
410
|
+
success = allowed_status?(status, options)
|
408
411
|
|
409
412
|
begin
|
410
|
-
|
413
|
+
report_errors(commands, status, streams, streamed) if !success
|
411
414
|
ensure
|
412
|
-
|
415
|
+
# backward compatibility for recorders with just single parameter
|
416
|
+
if recorder.method(:record_status).arity == 1
|
417
|
+
recorder.record_status(status)
|
418
|
+
else
|
419
|
+
recorder.record_status(status, success)
|
420
|
+
end
|
413
421
|
end
|
414
422
|
|
415
423
|
build_result(streams, status, options)
|
@@ -417,12 +425,11 @@ module Cheetah
|
|
417
425
|
|
418
426
|
private
|
419
427
|
|
420
|
-
def
|
421
|
-
|
428
|
+
def allowed_status?(status, options)
|
429
|
+
exit_status = status.exitstatus
|
430
|
+
return exit_status.zero? unless allowed_exitstatus?(options)
|
422
431
|
|
423
|
-
|
424
|
-
options[:allowed_exitstatus].include?(exitstatus)
|
425
|
-
end
|
432
|
+
options[:allowed_exitstatus].include?(exit_status)
|
426
433
|
end
|
427
434
|
|
428
435
|
# Parts of Cheetah.run
|
@@ -519,51 +526,49 @@ module Cheetah
|
|
519
526
|
|
520
527
|
def fork_commands_recursive(commands, pipes, options)
|
521
528
|
fork do
|
522
|
-
|
523
|
-
|
524
|
-
options = chroot_step(options)
|
525
|
-
|
526
|
-
if commands.size == 1
|
527
|
-
from_pipe(STDIN, pipes[:stdin])
|
528
|
-
else
|
529
|
-
pipe_to_child = IO.pipe
|
530
|
-
|
531
|
-
fork_commands_recursive(commands[0..-2],
|
532
|
-
{
|
533
|
-
stdin: pipes[:stdin],
|
534
|
-
stdout: pipe_to_child,
|
535
|
-
stderr: pipes[:stderr]
|
536
|
-
},
|
537
|
-
options)
|
538
|
-
|
539
|
-
pipes[:stdin][READ].close
|
540
|
-
pipes[:stdin][WRITE].close
|
541
|
-
|
542
|
-
from_pipe(STDIN, pipe_to_child)
|
543
|
-
end
|
529
|
+
# support chrooting
|
530
|
+
options = chroot_step(options)
|
544
531
|
|
545
|
-
|
546
|
-
|
532
|
+
if commands.size == 1
|
533
|
+
from_pipe($stdin, pipes[:stdin])
|
534
|
+
else
|
535
|
+
pipe_to_child = IO.pipe
|
547
536
|
|
548
|
-
|
537
|
+
fork_commands_recursive(commands[0..-2],
|
538
|
+
{
|
539
|
+
stdin: pipes[:stdin],
|
540
|
+
stdout: pipe_to_child,
|
541
|
+
stderr: pipes[:stderr]
|
542
|
+
},
|
543
|
+
options)
|
549
544
|
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
# depends when failed, if pipe is already redirected or not, so lets find it
|
556
|
-
output = pipes[:stderr][WRITE].closed? ? STDERR : pipes[:stderr][WRITE]
|
557
|
-
output.puts e.message
|
545
|
+
pipes[:stdin][READ].close
|
546
|
+
pipes[:stdin][WRITE].close
|
547
|
+
|
548
|
+
from_pipe($stdin, pipe_to_child)
|
549
|
+
end
|
558
550
|
|
559
|
-
|
551
|
+
into_pipe($stdout, pipes[:stdout])
|
552
|
+
into_pipe($stderr, pipes[:stderr])
|
553
|
+
|
554
|
+
close_fds
|
555
|
+
|
556
|
+
command, *args = commands.last
|
557
|
+
with_env(options[:env]) do
|
558
|
+
exec([command, command], *args)
|
560
559
|
end
|
560
|
+
rescue SystemCallError => e
|
561
|
+
# depends when failed, if pipe is already redirected or not, so lets find it
|
562
|
+
output = pipes[:stderr][WRITE].closed? ? $stderr : pipes[:stderr][WRITE]
|
563
|
+
output.puts e.message
|
564
|
+
|
565
|
+
exit!(127)
|
561
566
|
end
|
562
567
|
end
|
563
568
|
|
564
569
|
# closes all open fds starting with 3 and above
|
565
570
|
def close_fds
|
566
|
-
#
|
571
|
+
# NOTE: this will work only if unix has /proc filesystem. If it does not
|
567
572
|
# have it, it won't close other fds.
|
568
573
|
Dir.glob("/proc/self/fd/*").each do |path|
|
569
574
|
fd = File.basename(path).to_i
|
@@ -655,7 +660,7 @@ module Cheetah
|
|
655
660
|
end
|
656
661
|
end
|
657
662
|
|
658
|
-
def
|
663
|
+
def report_errors(commands, status, streams, streamed)
|
659
664
|
return if status.success?
|
660
665
|
|
661
666
|
stderr_part = if streamed[:stderr]
|
@@ -664,7 +669,7 @@ module Cheetah
|
|
664
669
|
" (no error output)"
|
665
670
|
else
|
666
671
|
lines = streams[:stderr].string.split("\n")
|
667
|
-
":
|
672
|
+
": #{lines.first}#{lines.size > 1 ? ' (...)' : ''}"
|
668
673
|
end
|
669
674
|
|
670
675
|
raise ExecutionFailed.new(
|
@@ -707,7 +712,7 @@ module Cheetah
|
|
707
712
|
end
|
708
713
|
|
709
714
|
def format_commands(commands)
|
710
|
-
|
715
|
+
"\"#{commands.map { |c| Shellwords.join(c) }.join(' | ')}\""
|
711
716
|
end
|
712
717
|
end
|
713
718
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cheetah
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Majda
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-12-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: abstract_method
|
@@ -77,7 +77,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
77
77
|
requirements:
|
78
78
|
- - ">="
|
79
79
|
- !ruby/object:Gem::Version
|
80
|
-
version: '
|
80
|
+
version: '2.5'
|
81
81
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
82
|
requirements:
|
83
83
|
- - ">="
|
@@ -85,7 +85,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
85
85
|
version: '0'
|
86
86
|
requirements: []
|
87
87
|
rubyforge_project:
|
88
|
-
rubygems_version: 2.7.6.
|
88
|
+
rubygems_version: 2.7.6.3
|
89
89
|
signing_key:
|
90
90
|
specification_version: 4
|
91
91
|
summary: Your swiss army knife for executing external commands in Ruby safely and
|