epi 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/epi +1 -1
- data/lib/epi/cli/command.rb +7 -0
- data/lib/epi/cli/commands/concerns/daemon.rb +33 -0
- data/lib/epi/cli/commands/config.rb +11 -3
- data/lib/epi/cli/commands/daemon.rb +14 -0
- data/lib/epi/cli/commands/help.rb +0 -0
- data/lib/epi/cli/commands/job.rb +1 -1
- data/lib/epi/cli/commands/restart.rb +16 -0
- data/lib/epi/cli/commands/start.rb +15 -0
- data/lib/epi/cli/commands/status.rb +6 -2
- data/lib/epi/cli/commands/stop.rb +16 -0
- data/lib/epi/cli.rb +1 -1
- data/lib/epi/connection.rb +7 -0
- data/lib/epi/core_ext/inflector.rb +1 -1
- data/lib/epi/daemon/receiver.rb +37 -0
- data/lib/epi/{server → daemon}/responder.rb +14 -5
- data/lib/epi/{server → daemon}/responders/config.rb +14 -2
- data/lib/epi/{server → daemon}/responders/job.rb +5 -6
- data/lib/epi/{server → daemon}/responders/shutdown.rb +1 -1
- data/lib/epi/daemon/responders/start.rb +19 -0
- data/lib/epi/{server → daemon}/responders/status.rb +4 -2
- data/lib/epi/daemon/responders/stop_all.rb +20 -0
- data/lib/epi/daemon/sender.rb +74 -0
- data/lib/epi/{server.rb → daemon.rb} +26 -27
- data/lib/epi/data.rb +4 -5
- data/lib/epi/job.rb +60 -2
- data/lib/epi/job_description.rb +6 -8
- data/lib/epi/jobs.rb +30 -2
- data/lib/epi/launch.rb +1 -1
- data/lib/epi/logging.rb +33 -0
- data/lib/epi/process_status.rb +1 -1
- data/lib/epi/running_process.rb +21 -3
- data/lib/epi/trigger.rb +53 -0
- data/lib/epi/triggers/concerns/comparison.rb +43 -0
- data/lib/epi/triggers/memory.rb +16 -0
- data/lib/epi/triggers/touch.rb +37 -0
- data/lib/epi/triggers/uptime.rb +12 -0
- data/lib/epi/version.rb +1 -1
- data/lib/epi.rb +4 -22
- metadata +26 -26
- data/lib/epi/cli/commands/server.rb +0 -38
- data/lib/epi/server/receiver.rb +0 -46
- data/lib/epi/server/responders/command.rb +0 -15
- data/lib/epi/server/sender.rb +0 -64
data/lib/epi/job.rb
CHANGED
@@ -15,6 +15,7 @@ module Epi
|
|
15
15
|
|
16
16
|
def initialize(job_description, state)
|
17
17
|
@job_description = job_description
|
18
|
+
@triggers = job_description.triggers.map { |t| Trigger.make self, *t }
|
18
19
|
@expected_count = state['expected_count'] || job_description.initial_processes
|
19
20
|
@pids = state['pids']
|
20
21
|
@dying_pids = state['dying_pids']
|
@@ -76,25 +77,80 @@ module Epi
|
|
76
77
|
stop_one while running_count > expected_count
|
77
78
|
end
|
78
79
|
|
80
|
+
def run_triggers!
|
81
|
+
@triggers.each &:try
|
82
|
+
end
|
83
|
+
|
84
|
+
def shutdown!(&callback)
|
85
|
+
count = running_count
|
86
|
+
if count > 0
|
87
|
+
count.times do
|
88
|
+
stop_one do
|
89
|
+
count -= 1
|
90
|
+
callback.call if callback && count == 0
|
91
|
+
end
|
92
|
+
end
|
93
|
+
else
|
94
|
+
callback.call if callback
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
79
98
|
def terminate!
|
80
99
|
self.expected_count = 0
|
81
100
|
sync!
|
82
101
|
end
|
83
102
|
|
103
|
+
def restart!
|
104
|
+
count = expected_count
|
105
|
+
if count > 0
|
106
|
+
self.expected_count = 0
|
107
|
+
sync!
|
108
|
+
self.expected_count = count
|
109
|
+
sync!
|
110
|
+
end
|
111
|
+
self
|
112
|
+
end
|
113
|
+
|
114
|
+
def running_processes
|
115
|
+
pids.map do |proc_id, pid|
|
116
|
+
[proc_id, ProcessStatus[pid] || RunningProcess.new(pid)]
|
117
|
+
end.to_h
|
118
|
+
end
|
119
|
+
|
84
120
|
def running_count
|
85
121
|
pids.count
|
86
122
|
end
|
87
123
|
|
124
|
+
def dying_count
|
125
|
+
dying_pids.count
|
126
|
+
end
|
127
|
+
|
128
|
+
# Replace a running process with a new one
|
129
|
+
# @param pid [Fixnum] PID of the process to replace
|
130
|
+
def replace(pid, &callback)
|
131
|
+
stop_one pid do
|
132
|
+
start_one while running_count < expected_count
|
133
|
+
callback.call if callback
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
88
137
|
private
|
89
138
|
|
90
139
|
def start_one
|
91
140
|
proc_id, pid = job_description.launch
|
92
141
|
pids[proc_id] = pid
|
93
142
|
Data.write pid_key(proc_id), pid
|
143
|
+
Jobs.by_pid[pid] = self
|
94
144
|
end
|
95
145
|
|
96
|
-
def stop_one
|
97
|
-
|
146
|
+
def stop_one(pid = nil, &callback)
|
147
|
+
if pid
|
148
|
+
proc_id = pids.key pid
|
149
|
+
raise Exceptions::Fatal, "Process #{pid} isn't managed by job #{id}" unless proc_id
|
150
|
+
pids.delete proc_id
|
151
|
+
else
|
152
|
+
proc_id, pid = pids.shift
|
153
|
+
end
|
98
154
|
dying_pids[proc_id] = pid
|
99
155
|
work = proc do
|
100
156
|
ProcessStatus[pid].kill job_description.kill_timeout
|
@@ -102,6 +158,8 @@ module Epi
|
|
102
158
|
done = proc do
|
103
159
|
dying_pids.delete proc_id
|
104
160
|
Data.write pid_key(proc_id), nil
|
161
|
+
Jobs.by_pid.delete pid
|
162
|
+
callback.call if callback
|
105
163
|
end
|
106
164
|
EventMachine.defer work, done
|
107
165
|
end
|
data/lib/epi/job_description.rb
CHANGED
@@ -56,11 +56,11 @@ module Epi
|
|
56
56
|
'Must be a non-negative number' unless value.is_a?(Numeric) && value >= 0
|
57
57
|
end
|
58
58
|
|
59
|
-
attr_reader :id
|
59
|
+
attr_reader :id, :triggers
|
60
60
|
|
61
61
|
def initialize(id)
|
62
62
|
@id = id
|
63
|
-
@
|
63
|
+
@triggers = []
|
64
64
|
@props = {}
|
65
65
|
end
|
66
66
|
|
@@ -78,15 +78,13 @@ module Epi
|
|
78
78
|
end
|
79
79
|
|
80
80
|
def reconfigure
|
81
|
-
@
|
81
|
+
@triggers = []
|
82
82
|
yield self
|
83
|
+
# TODO: trigger an update of existing/running jobs
|
83
84
|
end
|
84
85
|
|
85
|
-
def on(
|
86
|
-
|
87
|
-
args: args,
|
88
|
-
handler: handler
|
89
|
-
}
|
86
|
+
def on(trigger_name, *args, &handler)
|
87
|
+
@triggers << [trigger_name, args, handler]
|
90
88
|
end
|
91
89
|
|
92
90
|
def pid_key(proc_id)
|
data/lib/epi/jobs.rb
CHANGED
@@ -8,13 +8,14 @@ module Epi
|
|
8
8
|
class << self
|
9
9
|
extend Forwardable
|
10
10
|
|
11
|
-
delegate [:[], :[]=, :delete, :each_value, :map] => :@jobs
|
11
|
+
delegate [:[], :[]=, :delete, :each_value, :map, :find, :count] => :@jobs
|
12
12
|
|
13
|
-
attr_reader :configuration_files
|
13
|
+
attr_reader :configuration_files, :by_pid
|
14
14
|
|
15
15
|
def reset!
|
16
16
|
@configuration_files = {}
|
17
17
|
@jobs = {}
|
18
|
+
@by_pid = {}
|
18
19
|
end
|
19
20
|
|
20
21
|
def beat!
|
@@ -37,6 +38,13 @@ module Epi
|
|
37
38
|
# Sync each job with its expectations
|
38
39
|
each_value &:sync!
|
39
40
|
|
41
|
+
# Snapshot processes again, so that triggers have access to
|
42
|
+
# newly-spawned processes
|
43
|
+
ProcessStatus.take!
|
44
|
+
|
45
|
+
# Run job triggers
|
46
|
+
each_value &:run_triggers!
|
47
|
+
|
40
48
|
# Write state of each job to data file
|
41
49
|
Data.jobs = map { |id, job| [id.to_s, job.state] }.to_h
|
42
50
|
Data.save
|
@@ -45,6 +53,26 @@ module Epi
|
|
45
53
|
@next_beat = EventMachine.add_timer(5) { beat! } # TODO: make interval configurable
|
46
54
|
end
|
47
55
|
|
56
|
+
def shutdown!(&callback)
|
57
|
+
EventMachine.cancel_timer @next_beat if @next_beat
|
58
|
+
ProcessStatus.take!
|
59
|
+
remaining = count
|
60
|
+
if remaining > 0
|
61
|
+
each_value do |job|
|
62
|
+
job.shutdown! do
|
63
|
+
remaining -= 1
|
64
|
+
callback.call if callback && remaining == 0
|
65
|
+
end
|
66
|
+
end
|
67
|
+
else
|
68
|
+
callback.call if callback
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def running_process_count
|
73
|
+
each_value.map(&:running_count).reduce(:+) || 0
|
74
|
+
end
|
75
|
+
|
48
76
|
def job_descriptions
|
49
77
|
configuration_files.values.inject({}) { |all, conf_file| all.merge! conf_file.job_descriptions }
|
50
78
|
end
|
data/lib/epi/launch.rb
CHANGED
@@ -53,7 +53,7 @@ module Epi
|
|
53
53
|
|
54
54
|
# Run the command and read the resulting PID from its STDOUT
|
55
55
|
IO.popen(env, cmd) { |p| p.read }.to_i.tap do |pid|
|
56
|
-
logger.
|
56
|
+
logger.info "Process #{pid} started: #{`ps -p #{pid} -o command=`.chomp}"
|
57
57
|
end
|
58
58
|
end
|
59
59
|
end
|
data/lib/epi/logging.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
module Epi
|
2
|
+
|
3
|
+
class << self
|
4
|
+
|
5
|
+
DEFAULT_LEVEL = 'info'
|
6
|
+
|
7
|
+
def logger
|
8
|
+
@logger ||= make_logger
|
9
|
+
end
|
10
|
+
|
11
|
+
def logger=(value)
|
12
|
+
@logger = Logger === value ? value : make_logger(value)
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def make_logger(target = nil)
|
18
|
+
Logger.new(target || ENV['EPI_LOG'] || default_log_path).tap do |logger|
|
19
|
+
logger.level = log_level
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def default_log_path
|
24
|
+
Data.home.join('epi.log').to_s
|
25
|
+
end
|
26
|
+
|
27
|
+
def log_level
|
28
|
+
Logger::Severity.const_get (ENV['EPI_LOG_LEVEL'] || DEFAULT_LEVEL).upcase
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
data/lib/epi/process_status.rb
CHANGED
data/lib/epi/running_process.rb
CHANGED
@@ -42,10 +42,11 @@ module Epi
|
|
42
42
|
Epi.logger
|
43
43
|
end
|
44
44
|
|
45
|
-
def initialize(pid, ps_line
|
46
|
-
@pid = pid
|
45
|
+
def initialize(pid, ps_line: nil, job: nil)
|
46
|
+
@pid = pid.to_i
|
47
47
|
@ps_line = ps_line
|
48
48
|
@props = {}
|
49
|
+
@job = job
|
49
50
|
reload! unless ps_line
|
50
51
|
end
|
51
52
|
|
@@ -96,6 +97,12 @@ module Epi
|
|
96
97
|
@started_at ||= Time.parse parts[5..9].join ' '
|
97
98
|
end
|
98
99
|
|
100
|
+
# Duration the process has been running (in seconds)
|
101
|
+
# @return [Float]
|
102
|
+
def uptime
|
103
|
+
Time.now - started_at
|
104
|
+
end
|
105
|
+
|
99
106
|
# Name of the user that owns the process
|
100
107
|
# @return [String]
|
101
108
|
def user
|
@@ -136,17 +143,28 @@ module Epi
|
|
136
143
|
else
|
137
144
|
signal = timeout ? 'KILL' : 'TERM'
|
138
145
|
logger.info "Sending #{signal} to process #{pid}"
|
139
|
-
Process.kill signal, pid
|
146
|
+
Process.kill signal, pid rescue Errno::ESRCH false
|
140
147
|
sleep 0.2 while `ps -p #{pid} > /dev/null 2>&1; echo $?`.chomp.to_i == 0
|
141
148
|
logger.info "Process #{pid} terminated by signal #{signal}"
|
142
149
|
end
|
143
150
|
self
|
144
151
|
end
|
145
152
|
|
153
|
+
# Kill a running process immediately and synchronously with kill -9
|
154
|
+
# @return [RunningProcess]
|
146
155
|
def kill!
|
147
156
|
kill true
|
148
157
|
end
|
149
158
|
|
159
|
+
def job
|
160
|
+
@job ||= Jobs.by_pid[pid]
|
161
|
+
end
|
162
|
+
|
163
|
+
def restart!
|
164
|
+
raise Exceptions::Fatal, 'Cannot restart this process because it is not managed by a job' unless job
|
165
|
+
job.replace pid
|
166
|
+
end
|
167
|
+
|
150
168
|
private
|
151
169
|
|
152
170
|
def parts
|
data/lib/epi/trigger.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
module Epi
|
2
|
+
class Trigger
|
3
|
+
|
4
|
+
def self.make(job, name, args, handler)
|
5
|
+
klass_name = name.camelize
|
6
|
+
klass = Triggers.const_defined?(klass_name) && Triggers.const_get(klass_name)
|
7
|
+
raise Exceptions::Fatal, "No trigger exists named #{name}" unless Class === klass && klass < self
|
8
|
+
klass.new job, handler, *args
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_reader :job, :args
|
12
|
+
|
13
|
+
def initialize(job, handler, *args)
|
14
|
+
@job = job
|
15
|
+
@handler = handler
|
16
|
+
@args = args
|
17
|
+
end
|
18
|
+
|
19
|
+
def logger
|
20
|
+
Epi.logger
|
21
|
+
end
|
22
|
+
|
23
|
+
def message
|
24
|
+
nil
|
25
|
+
end
|
26
|
+
|
27
|
+
def try
|
28
|
+
case self
|
29
|
+
when ProcessTrigger then job.running_processes.each_value { |process| try_with process }
|
30
|
+
when JobTrigger then try_with nil
|
31
|
+
else nil
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def try_with(process)
|
36
|
+
args = [process].reject(&:nil?)
|
37
|
+
if test *args
|
38
|
+
text = "Trigger on job #{job.id}"
|
39
|
+
text << " (PID #{process.pid})" if process
|
40
|
+
text << ": " << message if message
|
41
|
+
logger.info text
|
42
|
+
@handler.call process || job
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class JobTrigger < self; end
|
47
|
+
class ProcessTrigger < self; end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
Dir[File.expand_path '../triggers/concerns/*.rb', __FILE__].each { |f| require f }
|
53
|
+
Dir[File.expand_path '../triggers/*.rb', __FILE__].each { |f| require f }
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Epi
|
2
|
+
module Triggers
|
3
|
+
module Concerns
|
4
|
+
module Comparison
|
5
|
+
|
6
|
+
def compare(subject)
|
7
|
+
tester.call subject, object
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def tester
|
13
|
+
@tester ||= choose_tester
|
14
|
+
end
|
15
|
+
|
16
|
+
def op
|
17
|
+
@op ||= args[0]
|
18
|
+
end
|
19
|
+
|
20
|
+
def object
|
21
|
+
@object ||= args[1]
|
22
|
+
end
|
23
|
+
|
24
|
+
def choose_tester
|
25
|
+
case op
|
26
|
+
when :gt then -> a, b { a > b }
|
27
|
+
when :lt then -> a, b { a < b }
|
28
|
+
when :gte then -> a, b { a >= b }
|
29
|
+
when :lte then -> a, b { a <= b }
|
30
|
+
when :eq then -> a, b { a == b }
|
31
|
+
when :not_eq then -> a, b { a != b}
|
32
|
+
when :match then -> a, b { a =~ b }
|
33
|
+
when :not_match then -> a, b { a !~ b }
|
34
|
+
when :like then -> a, b { a === b }
|
35
|
+
when :not_like then -> a, b { !(a === b) }
|
36
|
+
else raise Exceptions::Fatal, "Unknown operation #{op}"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Epi
|
2
|
+
module Triggers
|
3
|
+
class Memory < Trigger::ProcessTrigger
|
4
|
+
include Concerns::Comparison
|
5
|
+
|
6
|
+
def test(process)
|
7
|
+
compare process.physical_memory
|
8
|
+
end
|
9
|
+
|
10
|
+
def message
|
11
|
+
"Physical memory exceeded #{object} bytes"
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Epi
|
2
|
+
module Triggers
|
3
|
+
class Touch < Trigger::JobTrigger
|
4
|
+
|
5
|
+
def initialize(*args)
|
6
|
+
super *args
|
7
|
+
update
|
8
|
+
end
|
9
|
+
|
10
|
+
def test
|
11
|
+
ino = @ino; mtime = @mtime
|
12
|
+
update
|
13
|
+
ino != @ino || mtime != @mtime
|
14
|
+
end
|
15
|
+
|
16
|
+
def message
|
17
|
+
"Path '#{path}' was touched"
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def path
|
23
|
+
@path ||= Pathname args.first
|
24
|
+
end
|
25
|
+
|
26
|
+
def update
|
27
|
+
@ino, @mtime = begin
|
28
|
+
stat = path.stat
|
29
|
+
[stat.ino, stat.mtime]
|
30
|
+
rescue Errno::ENOENT
|
31
|
+
[nil, nil]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/epi/version.rb
CHANGED
data/lib/epi.rb
CHANGED
@@ -3,10 +3,12 @@ require 'logger'
|
|
3
3
|
require 'shellwords'
|
4
4
|
|
5
5
|
require 'epi/core_ext'
|
6
|
+
require 'epi/logging'
|
6
7
|
require 'epi/exceptions'
|
7
8
|
require 'epi/version'
|
8
9
|
require 'epi/cli'
|
9
|
-
require 'epi/
|
10
|
+
require 'epi/connection'
|
11
|
+
require 'epi/daemon'
|
10
12
|
require 'epi/data'
|
11
13
|
require 'epi/process_status'
|
12
14
|
require 'epi/running_process'
|
@@ -15,38 +17,18 @@ require 'epi/jobs'
|
|
15
17
|
require 'epi/configuration_file'
|
16
18
|
require 'epi/job_description'
|
17
19
|
require 'epi/launch'
|
20
|
+
require 'epi/trigger'
|
18
21
|
|
19
22
|
module Epi
|
20
23
|
ROOT = Pathname File.expand_path('../..', __FILE__)
|
21
24
|
|
22
25
|
class << self
|
23
26
|
|
24
|
-
def logger
|
25
|
-
@logger ||= make_logger
|
26
|
-
end
|
27
|
-
|
28
|
-
def logger=(value)
|
29
|
-
@logger = Logger === value ? value : make_logger(value)
|
30
|
-
end
|
31
|
-
|
32
27
|
def root?
|
33
28
|
@is_root = `whoami`.chomp == 'root' if @is_root.nil?
|
34
29
|
@is_root
|
35
30
|
end
|
36
31
|
|
37
|
-
private
|
38
|
-
|
39
|
-
def make_logger(target = nil)
|
40
|
-
Logger.new(target || ENV['EPI_LOG'] || STDOUT).tap do |logger|
|
41
|
-
logger.level = Logger::Severity::WARN
|
42
|
-
level = ENV['EPI_LOG_LEVEL']
|
43
|
-
if level
|
44
|
-
level = level.upcase
|
45
|
-
logger.level = Logger::Severity.const_get(level) if Logger::Severity.const_defined? level
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
32
|
end
|
51
33
|
|
52
34
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: epi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Neil E. Pearson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-10-
|
11
|
+
date: 2014-10-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: eventmachine
|
@@ -24,20 +24,6 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.0'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: bson
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - "~>"
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '2.3'
|
34
|
-
type: :runtime
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - "~>"
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '2.3'
|
41
27
|
description: Manage your background processes
|
42
28
|
email:
|
43
29
|
- neil@helium.net.au
|
@@ -50,13 +36,29 @@ files:
|
|
50
36
|
- lib/epi.rb
|
51
37
|
- lib/epi/cli.rb
|
52
38
|
- lib/epi/cli/command.rb
|
39
|
+
- lib/epi/cli/commands/concerns/daemon.rb
|
53
40
|
- lib/epi/cli/commands/config.rb
|
41
|
+
- lib/epi/cli/commands/daemon.rb
|
42
|
+
- lib/epi/cli/commands/help.rb
|
54
43
|
- lib/epi/cli/commands/job.rb
|
55
|
-
- lib/epi/cli/commands/
|
44
|
+
- lib/epi/cli/commands/restart.rb
|
45
|
+
- lib/epi/cli/commands/start.rb
|
56
46
|
- lib/epi/cli/commands/status.rb
|
47
|
+
- lib/epi/cli/commands/stop.rb
|
57
48
|
- lib/epi/configuration_file.rb
|
49
|
+
- lib/epi/connection.rb
|
58
50
|
- lib/epi/core_ext.rb
|
59
51
|
- lib/epi/core_ext/inflector.rb
|
52
|
+
- lib/epi/daemon.rb
|
53
|
+
- lib/epi/daemon/receiver.rb
|
54
|
+
- lib/epi/daemon/responder.rb
|
55
|
+
- lib/epi/daemon/responders/config.rb
|
56
|
+
- lib/epi/daemon/responders/job.rb
|
57
|
+
- lib/epi/daemon/responders/shutdown.rb
|
58
|
+
- lib/epi/daemon/responders/start.rb
|
59
|
+
- lib/epi/daemon/responders/status.rb
|
60
|
+
- lib/epi/daemon/responders/stop_all.rb
|
61
|
+
- lib/epi/daemon/sender.rb
|
60
62
|
- lib/epi/data.rb
|
61
63
|
- lib/epi/exceptions.rb
|
62
64
|
- lib/epi/exceptions/base.rb
|
@@ -67,17 +69,14 @@ files:
|
|
67
69
|
- lib/epi/job_description.rb
|
68
70
|
- lib/epi/jobs.rb
|
69
71
|
- lib/epi/launch.rb
|
72
|
+
- lib/epi/logging.rb
|
70
73
|
- lib/epi/process_status.rb
|
71
74
|
- lib/epi/running_process.rb
|
72
|
-
- lib/epi/
|
73
|
-
- lib/epi/
|
74
|
-
- lib/epi/
|
75
|
-
- lib/epi/
|
76
|
-
- lib/epi/
|
77
|
-
- lib/epi/server/responders/job.rb
|
78
|
-
- lib/epi/server/responders/shutdown.rb
|
79
|
-
- lib/epi/server/responders/status.rb
|
80
|
-
- lib/epi/server/sender.rb
|
75
|
+
- lib/epi/trigger.rb
|
76
|
+
- lib/epi/triggers/concerns/comparison.rb
|
77
|
+
- lib/epi/triggers/memory.rb
|
78
|
+
- lib/epi/triggers/touch.rb
|
79
|
+
- lib/epi/triggers/uptime.rb
|
81
80
|
- lib/epi/version.rb
|
82
81
|
homepage: https://github.com/hx/epi
|
83
82
|
licenses:
|
@@ -104,3 +103,4 @@ signing_key:
|
|
104
103
|
specification_version: 4
|
105
104
|
summary: Epinephrine
|
106
105
|
test_files: []
|
106
|
+
has_rdoc:
|
@@ -1,38 +0,0 @@
|
|
1
|
-
module Epi
|
2
|
-
module Cli
|
3
|
-
module Commands
|
4
|
-
class Server < Command
|
5
|
-
|
6
|
-
def run
|
7
|
-
process = Epi::Server.process
|
8
|
-
raise Exceptions::Fatal, 'You need root privileges to manage this server' if
|
9
|
-
process && process.was_alive? && process.root? && !Epi.root?
|
10
|
-
case args.first
|
11
|
-
when nil, 'start' then startup
|
12
|
-
when 'run' then run_server
|
13
|
-
when 'stop' then shutdown
|
14
|
-
else raise Exceptions::Fatal, 'Unknown server command, use [ start | stop | restart ]'
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
private
|
19
|
-
|
20
|
-
def startup
|
21
|
-
Epi::Server.ensure_running
|
22
|
-
puts 'Server is running'
|
23
|
-
end
|
24
|
-
|
25
|
-
def shutdown
|
26
|
-
Epi::Server.shutdown
|
27
|
-
puts 'Server has shut down'
|
28
|
-
end
|
29
|
-
|
30
|
-
def run_server
|
31
|
-
Epi::Server.run
|
32
|
-
puts 'Server is running'
|
33
|
-
end
|
34
|
-
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|