cognizant 0.0.2 → 0.0.3
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 +7 -0
- data/.gitignore +1 -0
- data/.travis.yml +17 -0
- data/Gemfile +4 -1
- data/{LICENSE → License.md} +4 -2
- data/Rakefile +5 -0
- data/Readme.md +95 -0
- data/bin/cognizant +76 -122
- data/bin/cognizantd +28 -61
- data/cognizant.gemspec +8 -4
- data/examples/apps/redis-server.cz +42 -0
- data/examples/apps/redis-server.yml +29 -0
- data/examples/apps/redis-server_dsl.cz +54 -0
- data/examples/apps/resque.cz +17 -0
- data/examples/apps/thin.cz +32 -0
- data/examples/apps/thin.yml +48 -0
- data/examples/cognizantd.yml +18 -47
- data/features/child_process.feature +62 -0
- data/features/commands.feature +65 -0
- data/features/cpu_usage.feature +45 -0
- data/features/daemon.feature +12 -0
- data/features/flapping.feature +39 -0
- data/features/memory_usage.feature +45 -0
- data/features/shell.feature +30 -0
- data/features/step_definitions/common_steps.rb +14 -0
- data/features/step_definitions/daemon_steps.rb +25 -0
- data/features/step_definitions/shell_steps.rb +96 -0
- data/features/support/env.rb +54 -0
- data/lib/cognizant.rb +1 -5
- data/lib/cognizant/application.rb +122 -0
- data/lib/cognizant/application/dsl_proxy.rb +23 -0
- data/lib/cognizant/client.rb +61 -0
- data/lib/cognizant/commands.rb +164 -0
- data/lib/cognizant/commands/actions.rb +30 -0
- data/lib/cognizant/commands/help.rb +10 -0
- data/lib/cognizant/commands/load.rb +10 -0
- data/lib/cognizant/commands/shutdown.rb +7 -0
- data/lib/cognizant/commands/status.rb +11 -0
- data/lib/cognizant/commands/use.rb +15 -0
- data/lib/cognizant/controller.rb +17 -0
- data/lib/cognizant/daemon.rb +279 -0
- data/lib/cognizant/interface.rb +17 -0
- data/lib/cognizant/log.rb +25 -0
- data/lib/cognizant/process.rb +138 -94
- data/lib/cognizant/process/actions.rb +30 -41
- data/lib/cognizant/process/actions/restart.rb +73 -17
- data/lib/cognizant/process/actions/start.rb +35 -12
- data/lib/cognizant/process/actions/stop.rb +38 -17
- data/lib/cognizant/process/attributes.rb +41 -10
- data/lib/cognizant/process/children.rb +36 -0
- data/lib/cognizant/process/{condition_check.rb → condition_delegate.rb} +11 -13
- data/lib/cognizant/process/conditions.rb +7 -4
- data/lib/cognizant/process/conditions/cpu_usage.rb +5 -6
- data/lib/cognizant/process/conditions/memory_usage.rb +2 -6
- data/lib/cognizant/process/dsl_proxy.rb +23 -0
- data/lib/cognizant/process/execution.rb +16 -9
- data/lib/cognizant/process/pid.rb +16 -6
- data/lib/cognizant/process/status.rb +14 -2
- data/lib/cognizant/process/trigger_delegate.rb +57 -0
- data/lib/cognizant/process/triggers.rb +19 -0
- data/lib/cognizant/process/triggers/flapping.rb +68 -0
- data/lib/cognizant/process/triggers/transition.rb +22 -0
- data/lib/cognizant/process/triggers/trigger.rb +15 -0
- data/lib/cognizant/shell.rb +142 -0
- data/lib/cognizant/system.rb +16 -0
- data/lib/cognizant/system/ps.rb +1 -1
- data/lib/cognizant/system/signal.rb +2 -2
- data/lib/cognizant/util/dsl_proxy_methods_handler.rb +25 -0
- data/lib/cognizant/util/fixnum_percent.rb +5 -0
- data/lib/cognizant/util/transform_hash_keys.rb +33 -0
- data/lib/cognizant/validations.rb +142 -142
- data/lib/cognizant/version.rb +1 -1
- metadata +131 -71
- data/README.md +0 -221
- data/examples/redis-server.rb +0 -28
- data/examples/resque.rb +0 -10
- data/images/logo-small.png +0 -0
- data/images/logo.png +0 -0
- data/images/logo.pxm +0 -0
- data/lib/cognizant/logging.rb +0 -33
- data/lib/cognizant/process/conditions/flapping.rb +0 -57
- data/lib/cognizant/process/conditions/trigger_condition.rb +0 -52
- data/lib/cognizant/server.rb +0 -14
- data/lib/cognizant/server/commands.rb +0 -80
- data/lib/cognizant/server/daemon.rb +0 -277
- data/lib/cognizant/server/interface.rb +0 -86
- data/lib/cognizant/util/symbolize_hash_keys.rb +0 -19
@@ -33,26 +33,35 @@ module Cognizant
|
|
33
33
|
|
34
34
|
# The grace time period in seconds for the process to start within.
|
35
35
|
# Covers the time period for the input and start command. After the
|
36
|
-
# timeout is over, the process
|
36
|
+
# timeout is over, the process is considered as not started and it
|
37
37
|
# re-enters the auto start lifecycle based on conditions.
|
38
|
-
# @return [String] Defaults to
|
38
|
+
# @return [String] Defaults to 30
|
39
39
|
attr_accessor :start_timeout
|
40
40
|
|
41
41
|
# The command to run after the process is started.
|
42
42
|
# @return [String] Defaults to nil
|
43
43
|
attr_accessor :start_after_command
|
44
44
|
|
45
|
+
def reset_attributes!
|
46
|
+
self.start_env = {}
|
47
|
+
self.start_before_command = nil
|
48
|
+
self.start_command = nil
|
49
|
+
self.start_with_input = nil
|
50
|
+
self.start_with_input_file = nil
|
51
|
+
self.start_with_input_command = nil
|
52
|
+
self.start_timeout = 30
|
53
|
+
self.start_after_command = nil
|
54
|
+
super
|
55
|
+
end
|
56
|
+
|
45
57
|
def start_process
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
end
|
51
|
-
execute_action(
|
52
|
-
result_handler,
|
58
|
+
# We skip so that we're not reinformed about the required transition by the tick.
|
59
|
+
skip_ticks_for(self.start_timeout)
|
60
|
+
|
61
|
+
options = {
|
53
62
|
name: self.name,
|
54
|
-
daemonize: self.daemonize
|
55
|
-
env:
|
63
|
+
daemonize: self.daemonize,
|
64
|
+
env: self.env.merge(self.start_env),
|
56
65
|
logfile: self.logfile,
|
57
66
|
errfile: self.errfile,
|
58
67
|
before: self.start_before_command,
|
@@ -62,7 +71,21 @@ module Cognizant
|
|
62
71
|
input_command: self.start_with_input_command,
|
63
72
|
after: self.start_after_command,
|
64
73
|
timeout: self.start_timeout
|
65
|
-
|
74
|
+
}
|
75
|
+
handle_action('_start_result_handler', options)
|
76
|
+
end
|
77
|
+
|
78
|
+
# @private
|
79
|
+
def _start_result_handler(result, time_left = 0)
|
80
|
+
if result.respond_to?(:succeeded?) and result.succeeded?
|
81
|
+
write_pid(result.pid) if self.daemonize and result.pid != 0
|
82
|
+
end
|
83
|
+
|
84
|
+
# Reset cached pid to read from file or command.
|
85
|
+
@process_pid = nil
|
86
|
+
|
87
|
+
# Rollback the pending skips.
|
88
|
+
skip_ticks_for(-time_left) if time_left > 0
|
66
89
|
end
|
67
90
|
end
|
68
91
|
end
|
@@ -18,10 +18,10 @@ module Cognizant
|
|
18
18
|
|
19
19
|
# The signals to pass to the process one by one attempting to stop it.
|
20
20
|
# Each signal is passed within the timeout period over equally
|
21
|
-
#
|
21
|
+
# divided intervals (min. 2 seconds). Override with signals without
|
22
22
|
# "KILL" to never force kill the process.
|
23
23
|
# e.g. ["TERM", "INT"]
|
24
|
-
# @return [Array] Defaults to ["
|
24
|
+
# @return [Array] Defaults to ["QUIT", "TERM", "INT"]
|
25
25
|
attr_accessor :stop_signals
|
26
26
|
|
27
27
|
# The grace time period in seconds for the process to stop within.
|
@@ -29,29 +29,50 @@ module Cognizant
|
|
29
29
|
# timeout is over, the process is checked for running status and if
|
30
30
|
# not stopped, it re-enters the auto start lifecycle based on
|
31
31
|
# conditions.
|
32
|
-
# @return [String] Defaults to
|
32
|
+
# @return [String] Defaults to 30
|
33
33
|
attr_accessor :stop_timeout
|
34
34
|
|
35
35
|
# The command to run after the process is stopped.
|
36
36
|
# @return [String] Defaults to nil
|
37
37
|
attr_accessor :stop_after_command
|
38
38
|
|
39
|
+
def reset_attributes!
|
40
|
+
self.stop_env = {}
|
41
|
+
self.stop_before_command = nil
|
42
|
+
self.stop_command = nil
|
43
|
+
self.stop_signals = ["QUIT", "TERM", "INT"]
|
44
|
+
self.stop_timeout = 30
|
45
|
+
self.stop_after_command = nil
|
46
|
+
super
|
47
|
+
end
|
48
|
+
|
39
49
|
def stop_process
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
50
|
+
# We skip so that we're not reinformed about the required transition by the tick.
|
51
|
+
skip_ticks_for(self.stop_timeout)
|
52
|
+
|
53
|
+
options = {
|
54
|
+
env: self.env.merge(self.stop_env),
|
55
|
+
before: self.stop_before_command,
|
56
|
+
command: self.stop_command,
|
57
|
+
signals: self.stop_signals,
|
58
|
+
after: self.stop_after_command,
|
59
|
+
timeout: self.stop_timeout
|
60
|
+
}
|
61
|
+
handle_action('_stop_result_handler', options)
|
62
|
+
end
|
63
|
+
|
64
|
+
# @private
|
65
|
+
def _stop_result_handler(result, time_left = 0)
|
66
|
+
# If it is a boolean and value is true OR if it's an execution result and it succeeded.
|
67
|
+
if (!!result == result and result) or (result.respond_to?(:succeeded?) and result.succeeded?)
|
68
|
+
unlink_pid if not pid_running? and self.daemonize
|
45
69
|
end
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
after: self.stop_after_command,
|
53
|
-
timeout: self.stop_timeout
|
54
|
-
)
|
70
|
+
|
71
|
+
# Reset cached pid to read from file or command.
|
72
|
+
@process_pid = nil
|
73
|
+
|
74
|
+
# Rollback the pending skips.
|
75
|
+
skip_ticks_for(-time_left) if time_left > 0
|
55
76
|
end
|
56
77
|
end
|
57
78
|
end
|
@@ -2,10 +2,12 @@ module Cognizant
|
|
2
2
|
class Process
|
3
3
|
module Attributes
|
4
4
|
# Unique name for the process.
|
5
|
+
# Note: For child processes, this value is set automatically.
|
5
6
|
# @return [String]
|
6
7
|
attr_accessor :name
|
7
8
|
|
8
9
|
# Group classification for the process.
|
10
|
+
# Note: This is not system process group. See `gid` attribute instead.
|
9
11
|
# @return [String] Defaults to nil
|
10
12
|
attr_accessor :group
|
11
13
|
|
@@ -16,11 +18,23 @@ module Cognizant
|
|
16
18
|
# @return [true, false] Defaults to true
|
17
19
|
attr_accessor :daemonize
|
18
20
|
|
19
|
-
# Whether or not to auto start the process
|
20
|
-
#
|
21
|
+
# Whether or not to auto start the process when beginning monitoring.
|
22
|
+
# Afterwards, auto start is automatically managed based on user initiated
|
23
|
+
# stop or restart requests.
|
24
|
+
# Note: For child processes, this value is automatically set to false.
|
21
25
|
# @return [true, false] Defaults to true
|
22
26
|
attr_accessor :autostart
|
23
27
|
|
28
|
+
# The command to check the running status of the process with. The exit
|
29
|
+
# status of the command is used to determine the status.
|
30
|
+
# e.g. "/usr/bin/redis-cli PING"
|
31
|
+
# @return [String] Defaults to nil
|
32
|
+
attr_accessor :ping_command
|
33
|
+
|
34
|
+
# The command that returns the pid of the process.
|
35
|
+
# @return [String] Defaults to nil
|
36
|
+
attr_accessor :pid_command
|
37
|
+
|
24
38
|
# The pid lock file for the process. Required when daemonize is set to
|
25
39
|
# false.
|
26
40
|
# @return [String] Defaults to value of pids_dir/name.pid
|
@@ -67,15 +81,32 @@ module Cognizant
|
|
67
81
|
# @return [Array] Defaults to []
|
68
82
|
attr_accessor :groups
|
69
83
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
# @return [String] Defaults to nil
|
74
|
-
attr_accessor :ping_command
|
84
|
+
def daemonize!
|
85
|
+
@daemonize = true
|
86
|
+
end
|
75
87
|
|
76
|
-
|
77
|
-
|
78
|
-
|
88
|
+
def autostart!
|
89
|
+
@autostart = true
|
90
|
+
end
|
91
|
+
|
92
|
+
# @private
|
93
|
+
def reset_attributes!
|
94
|
+
self.name = nil
|
95
|
+
self.group = nil
|
96
|
+
self.daemonize = true
|
97
|
+
self.autostart = false
|
98
|
+
self.ping_command = nil
|
99
|
+
self.pid_command = nil
|
100
|
+
self.pidfile = nil
|
101
|
+
self.logfile = nil
|
102
|
+
self.errfile = nil
|
103
|
+
self.env = {}
|
104
|
+
self.chroot = nil
|
105
|
+
self.chdir = nil
|
106
|
+
self.uid = nil
|
107
|
+
self.gid = nil
|
108
|
+
self.groups = []
|
109
|
+
end
|
79
110
|
end
|
80
111
|
end
|
81
112
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Cognizant
|
2
|
+
class Process
|
3
|
+
module Children
|
4
|
+
def refresh_children!
|
5
|
+
# First prune the list of dead children.
|
6
|
+
@children.delete_if do |child|
|
7
|
+
!child.process_running?
|
8
|
+
end
|
9
|
+
|
10
|
+
# Add new found children to the list.
|
11
|
+
new_children_pids = Cognizant::System.get_children(@process_pid) - @children.map(&:cached_pid)
|
12
|
+
|
13
|
+
unless new_children_pids.empty?
|
14
|
+
Log[self].info "Existing children: #{@children.collect{ |c| c.cached_pid }.join(",")}. Got new children: #{new_children_pids.inspect} for #{@process_pid}."
|
15
|
+
end
|
16
|
+
|
17
|
+
# Construct a new process wrapper for each new found children.
|
18
|
+
new_children_pids.each do |child_pid|
|
19
|
+
create_child_process(child_pid)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def create_child_process(child_pid)
|
24
|
+
name = "<child(pid:#{child_pid})>"
|
25
|
+
attributes = @child_process_attributes.merge({ name: name, autostart: false }) # We do not have control over child process' lifecycle, so avoid even attempting to maintain its state with autostart.
|
26
|
+
|
27
|
+
child = Cognizant::Process.new(nil, attributes, &@child_process_block)
|
28
|
+
child.instance_variable_set(:@application, @application)
|
29
|
+
# TODO: Reset pidfile?
|
30
|
+
child.write_pid(child_pid)
|
31
|
+
@children << child
|
32
|
+
child.monitor
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -3,30 +3,28 @@ require "cognizant/util/rotational_array"
|
|
3
3
|
|
4
4
|
module Cognizant
|
5
5
|
class Process
|
6
|
-
class
|
6
|
+
class ConditionDelegate
|
7
7
|
class HistoryValue < Struct.new(:value, :critical); end
|
8
8
|
|
9
9
|
# No need to recreate one every tick.
|
10
10
|
EMPTY_ARRAY = [].freeze
|
11
11
|
|
12
|
-
attr_accessor :
|
13
|
-
def initialize(condition_name, options = {}, &block)
|
14
|
-
@condition_name = condition_name
|
15
|
-
|
16
|
-
if block
|
17
|
-
@do = Array(block)
|
18
|
-
else
|
19
|
-
@do = options.has_key?(:do) ? Array(options.delete(:do)) : [:restart]
|
20
|
-
end
|
12
|
+
attr_accessor :name
|
21
13
|
|
14
|
+
def initialize(name, options = {}, &block)
|
15
|
+
@name = name
|
22
16
|
@every = options.delete(:every).to_i
|
23
|
-
|
17
|
+
|
18
|
+
@times = options.delete(:times) || 1
|
24
19
|
@times = [@times, @times] unless @times.is_a?(Array) # handles :times => 5
|
25
20
|
@times.map(&:to_i)
|
26
21
|
|
22
|
+
@do = options.has_key?(:do) ? [options.delete(:do)] : [:restart]
|
23
|
+
@do = [block] if block
|
24
|
+
|
27
25
|
clear_history!
|
28
26
|
|
29
|
-
@condition = Cognizant::Process::Conditions[@
|
27
|
+
@condition = Cognizant::Process::Conditions[@name].new(options)
|
30
28
|
end
|
31
29
|
|
32
30
|
def run(pid, tick_number = Time.now.to_i)
|
@@ -52,7 +50,7 @@ module Cognizant
|
|
52
50
|
|
53
51
|
def to_s
|
54
52
|
data = @history.collect { |v| v and "#{v.value}#{'*' unless v.critical}" }.join(", ")
|
55
|
-
"#{@
|
53
|
+
"#{@name}: [#{data}]\n"
|
56
54
|
end
|
57
55
|
end
|
58
56
|
end
|
@@ -1,15 +1,18 @@
|
|
1
1
|
require "cognizant/process/conditions/poll_condition"
|
2
|
-
require "cognizant/process/conditions/trigger_condition"
|
3
2
|
|
4
|
-
Dir["#{File.dirname(__FILE__)}/conditions/*.rb"].each do |
|
5
|
-
require
|
3
|
+
Dir["#{File.dirname(__FILE__)}/conditions/*.rb"].each do |condition|
|
4
|
+
require condition
|
6
5
|
end
|
7
6
|
|
8
7
|
module Cognizant
|
9
8
|
class Process
|
10
9
|
module Conditions
|
11
10
|
def self.[](name)
|
12
|
-
|
11
|
+
begin
|
12
|
+
const_get(name.to_s.camelcase)
|
13
|
+
rescue NameError
|
14
|
+
nil
|
15
|
+
end
|
13
16
|
end
|
14
17
|
end
|
15
18
|
end
|
@@ -4,16 +4,15 @@ module Cognizant
|
|
4
4
|
class Process
|
5
5
|
module Conditions
|
6
6
|
class CpuUsage < PollCondition
|
7
|
-
def initialize(options = {})
|
8
|
-
@above = options[:above].to_f
|
9
|
-
end
|
10
|
-
|
11
7
|
def run(pid)
|
12
|
-
|
8
|
+
# Check for current value for the given process pid.
|
9
|
+
Cognizant::System.cpu_usage(pid).to_f
|
13
10
|
end
|
14
11
|
|
15
12
|
def check(value)
|
16
|
-
value
|
13
|
+
# Evaluate the value with threshold.
|
14
|
+
# The result of this decides condition invoking.
|
15
|
+
value > @options[:above].to_f
|
17
16
|
end
|
18
17
|
end
|
19
18
|
end
|
@@ -7,16 +7,12 @@ module Cognizant
|
|
7
7
|
MB_LABEL = "MB"
|
8
8
|
KB_LABEL = "KB"
|
9
9
|
|
10
|
-
def initialize(options = {})
|
11
|
-
@above = options[:above].to_f
|
12
|
-
end
|
13
|
-
|
14
10
|
def run(pid)
|
15
|
-
System.memory_usage(pid).to_f
|
11
|
+
Cognizant::System.memory_usage(pid).to_f
|
16
12
|
end
|
17
13
|
|
18
14
|
def check(value)
|
19
|
-
value.kilobytes > @above
|
15
|
+
value.kilobytes > @options[:above].to_f
|
20
16
|
end
|
21
17
|
|
22
18
|
def format_value(value)
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'cognizant/util/dsl_proxy_methods_handler'
|
2
|
+
|
3
|
+
module Cognizant
|
4
|
+
class Process
|
5
|
+
class DSLProxy
|
6
|
+
include Cognizant::Util::DSLProxyMethodsHandler
|
7
|
+
|
8
|
+
def initialize(process, &dsl_block)
|
9
|
+
super
|
10
|
+
@process = process
|
11
|
+
instance_eval(&dsl_block)
|
12
|
+
end
|
13
|
+
|
14
|
+
def check(condition_name, options, &block)
|
15
|
+
@process.check(condition_name, options, &block)
|
16
|
+
end
|
17
|
+
|
18
|
+
def monitor_children(&child_process_block)
|
19
|
+
@process.monitor_children(&child_process_block)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'cognizant/util/transform_hash_keys'
|
2
|
+
|
1
3
|
module Cognizant
|
2
4
|
class Process
|
3
5
|
module Execution
|
@@ -29,15 +31,13 @@ module Cognizant
|
|
29
31
|
if options[:daemonize]
|
30
32
|
# Create a new session to detach from the controlling terminal.
|
31
33
|
unless ::Process.setsid
|
32
|
-
|
34
|
+
Log[self].error "Cannot detach #{options[:name]} from controlling terminal"
|
33
35
|
end
|
34
36
|
|
35
37
|
# TODO: Set pgroup: true so that the spawned process is the group leader, and it's death would kill all children as well.
|
36
38
|
|
37
39
|
# Prevent inheriting signals from parent process.
|
38
|
-
|
39
|
-
Signal.trap('INT', 'SIG_DFL')
|
40
|
-
Signal.trap('HUP', 'SIG_DFL')
|
40
|
+
setup_execution_traps
|
41
41
|
|
42
42
|
# Give the process a name.
|
43
43
|
$0 = options[:name] if options[:name]
|
@@ -52,7 +52,7 @@ module Cognizant
|
|
52
52
|
|
53
53
|
# TODO: Run popen as spawned process before privileges are dropped for increased abilities?
|
54
54
|
stdin_data = options[:input] if options[:input]
|
55
|
-
stdin_data = IO.popen(options[:input_command]).
|
55
|
+
stdin_data = IO.popen(options[:input_command]).read if options[:input_command]
|
56
56
|
|
57
57
|
if stdin_data
|
58
58
|
stdin, stdin_w = IO.pipe
|
@@ -72,8 +72,8 @@ module Cognizant
|
|
72
72
|
})
|
73
73
|
|
74
74
|
# Spawn a process to execute the command.
|
75
|
-
process_pid = ::Process.spawn(options[:env]
|
76
|
-
#
|
75
|
+
process_pid = ::Process.spawn(options[:env].deep_stringify_keys!, command, spawn_options)
|
76
|
+
# Log[self].debug "process_pid: #{process_pid} (#{command})"
|
77
77
|
pid_w.write(process_pid)
|
78
78
|
|
79
79
|
if options[:daemonize]
|
@@ -116,11 +116,11 @@ module Cognizant
|
|
116
116
|
|
117
117
|
# Collect and return stdout, stderr and exitcode.
|
118
118
|
return ExecutionResult.new(
|
119
|
-
|
119
|
+
nil,
|
120
120
|
out_r.read,
|
121
121
|
err_r.read,
|
122
122
|
status.exitstatus,
|
123
|
-
status.exitstatus.zero?
|
123
|
+
status.exitstatus ? status.exitstatus.zero? : false # TODO: What rare case would not have status.existatus?
|
124
124
|
)
|
125
125
|
end
|
126
126
|
end
|
@@ -164,6 +164,13 @@ module Cognizant
|
|
164
164
|
|
165
165
|
private
|
166
166
|
|
167
|
+
def setup_execution_traps
|
168
|
+
Signal.trap('TERM', 'SIG_DFL')
|
169
|
+
Signal.trap('INT', 'SIG_DFL')
|
170
|
+
Signal.trap('QUIT', 'SIG_DFL')
|
171
|
+
Signal.trap('HUP', 'SIG_DFL')
|
172
|
+
end
|
173
|
+
|
167
174
|
def construct_spawn_options(options, overrides = {})
|
168
175
|
spawn_options = {}
|
169
176
|
[:chdir, :umask].each do |o|
|