cognizant 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +18 -0
- data/.yardopts +1 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +160 -0
- data/Rakefile +2 -0
- data/bin/cognizant +58 -0
- data/bin/cognizantd +124 -0
- data/cognizant.gemspec +24 -0
- data/examples/cognizantd.yml +23 -0
- data/examples/redis-server.rb +17 -0
- data/examples/resque.rb +10 -0
- data/images/logo-small.png +0 -0
- data/images/logo.png +0 -0
- data/images/logo.pxm +0 -0
- data/lib/cognizant/client/cli.rb +9 -0
- data/lib/cognizant/client/interface.rb +33 -0
- data/lib/cognizant/logging.rb +33 -0
- data/lib/cognizant/process/actions/restart.rb +60 -0
- data/lib/cognizant/process/actions/start.rb +70 -0
- data/lib/cognizant/process/actions/stop.rb +59 -0
- data/lib/cognizant/process/actions.rb +96 -0
- data/lib/cognizant/process/attributes.rb +81 -0
- data/lib/cognizant/process/execution.rb +176 -0
- data/lib/cognizant/process/pid.rb +28 -0
- data/lib/cognizant/process/status.rb +27 -0
- data/lib/cognizant/process.rb +149 -0
- data/lib/cognizant/server/commands.rb +53 -0
- data/lib/cognizant/server/daemon.rb +239 -0
- data/lib/cognizant/server/interface.rb +60 -0
- data/lib/cognizant/server.rb +14 -0
- data/lib/cognizant/validations.rb +142 -0
- data/lib/cognizant/version.rb +3 -0
- data/lib/cognizant.rb +7 -0
- metadata +169 -0
@@ -0,0 +1,53 @@
|
|
1
|
+
module Cognizant
|
2
|
+
module Server
|
3
|
+
module Commands
|
4
|
+
def self.load(config_file)
|
5
|
+
Cognizant::Server.daemon.load(config_file)
|
6
|
+
yield("OK")
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.status(*args)
|
10
|
+
if process_name = args.shift
|
11
|
+
Cognizant::Server.daemon.processes.each do |name, process|
|
12
|
+
if process.name.eql?(process_name)
|
13
|
+
yield("#{process.name}: #{process.state}")
|
14
|
+
return yield("OK")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
yield("ERR: No such process")
|
18
|
+
return yield("OK")
|
19
|
+
end
|
20
|
+
yield("OK")
|
21
|
+
end
|
22
|
+
|
23
|
+
%w(monitor start stop restart unmonitor).each do |action|
|
24
|
+
class_eval <<-END
|
25
|
+
def self.#{action}(*args)
|
26
|
+
unless process_name = args.shift
|
27
|
+
yield("ERR: Missing process name")
|
28
|
+
return yield("OK")
|
29
|
+
end
|
30
|
+
Cognizant::Server.daemon.processes.each do |name, process|
|
31
|
+
if process.name.eql?(process_name)
|
32
|
+
process.#{action}
|
33
|
+
return yield("OK")
|
34
|
+
end
|
35
|
+
end
|
36
|
+
yield("ERR: No such process")
|
37
|
+
yield("OK")
|
38
|
+
end
|
39
|
+
END
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.shutdown
|
43
|
+
Cognizant::Server.daemon.shutdown
|
44
|
+
yield("OK")
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.method_missing(command, *args)
|
48
|
+
yield("ERR: Unknown command '#{command}'")
|
49
|
+
yield("OK")
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,239 @@
|
|
1
|
+
require "eventmachine"
|
2
|
+
|
3
|
+
require "cognizant"
|
4
|
+
require "cognizant/logging"
|
5
|
+
require "cognizant/process"
|
6
|
+
require "cognizant/server/interface"
|
7
|
+
|
8
|
+
module Cognizant
|
9
|
+
module Server
|
10
|
+
class Daemon
|
11
|
+
include Cognizant::Logging
|
12
|
+
|
13
|
+
# Whether or not to the daemon in the background.
|
14
|
+
# @return [true, false] Defaults to true
|
15
|
+
attr_accessor :daemonize
|
16
|
+
|
17
|
+
# The pid lock file for the daemon.
|
18
|
+
# e.g. /Users/Gurpartap/.cognizant/cognizantd.pid
|
19
|
+
# @return [String] Defaults to /var/run/cognizant/cognizantd.pid
|
20
|
+
attr_accessor :pidfile
|
21
|
+
|
22
|
+
# The file to log the daemon's operations information into.
|
23
|
+
# e.g. /Users/Gurpartap/.cognizant/cognizantd.log
|
24
|
+
# @return [String] Defaults to /var/log/cognizant/cognizantd.log
|
25
|
+
attr_accessor :logfile
|
26
|
+
|
27
|
+
# The level of information to log. This does not affect the log
|
28
|
+
# level of managed processes.
|
29
|
+
# @note The possible values must be one of the following:
|
30
|
+
# Logger::DEBUG, Logger::INFO, Logger::WARN, Logger::ERROR and
|
31
|
+
# Logger::FATAL or 0, 1, 2, 3, 4 (respectively).
|
32
|
+
# @return [Logger::Severity] Defaults to Logger::INFO
|
33
|
+
attr_accessor :loglevel
|
34
|
+
|
35
|
+
# The socket lock file for the server. This file is ignored if valid
|
36
|
+
# bind address and port are given.
|
37
|
+
# e.g. /Users/Gurpartap/.cognizant/cognizant-server.sock
|
38
|
+
# @return [String] Defaults to /var/run/cognizant/cognizantd.sock
|
39
|
+
attr_accessor :socket
|
40
|
+
|
41
|
+
# The TCP address and port to start the server with. e.g. 8081,
|
42
|
+
# "127.0.0.1:8081", "0.0.0.0:8081".
|
43
|
+
# @return [String] Defaults to nil
|
44
|
+
attr_accessor :port
|
45
|
+
|
46
|
+
# Username for securing server access. e.g. "cognizant-user"
|
47
|
+
# @return [String] Defaults to nil
|
48
|
+
attr_accessor :username
|
49
|
+
|
50
|
+
# Password to accompany the username.
|
51
|
+
# e.g. "areallyverylongpasswordbecauseitmatters"
|
52
|
+
# @return [String] Defaults to nil
|
53
|
+
attr_accessor :password
|
54
|
+
|
55
|
+
# Directory to store the pid files of managed processes, when required.
|
56
|
+
# e.g. /Users/Gurpartap/.cognizant/pids/
|
57
|
+
# @return [String] Defaults to /var/run/cognizant/pids/
|
58
|
+
attr_accessor :pids_dir
|
59
|
+
|
60
|
+
# Directory to store the log files of managed processes, when required.
|
61
|
+
# e.g. /Users/Gurpartap/.cognizant/logs/
|
62
|
+
# @return [String] Defaults to /var/log/cognizant/logs/
|
63
|
+
attr_accessor :logs_dir
|
64
|
+
|
65
|
+
# Environment variables for managed processes to inherit.
|
66
|
+
# @return [Hash] Defaults to {}
|
67
|
+
attr_accessor :env
|
68
|
+
|
69
|
+
# The current working directory for the managed processes to start with.
|
70
|
+
# @return [String] Defaults to nil
|
71
|
+
attr_accessor :chdir
|
72
|
+
|
73
|
+
# Limit the permission modes for files and directories created by the
|
74
|
+
# daemon and the managed processes.
|
75
|
+
# @return [Integer] Defaults to nil
|
76
|
+
attr_accessor :umask
|
77
|
+
|
78
|
+
# Run the daemon and managed processes as the given user.
|
79
|
+
# e.g. "deploy", 1000
|
80
|
+
# @return [String] Defaults to nil
|
81
|
+
attr_accessor :user
|
82
|
+
|
83
|
+
# Run the daemon and managed processes as the given user group.
|
84
|
+
# e.g. "deploy"
|
85
|
+
# @return [String] Defaults to nil
|
86
|
+
attr_accessor :group
|
87
|
+
|
88
|
+
# Array of processes being managed.
|
89
|
+
# @private
|
90
|
+
# @return [Array]
|
91
|
+
attr_accessor :processes
|
92
|
+
|
93
|
+
# Initializes and starts the cognizant daemon with the given options
|
94
|
+
# as instance attributes.
|
95
|
+
# @param [Hash] options A hash of instance attributes and their values.
|
96
|
+
def initialize(options = {})
|
97
|
+
# Daemon config.
|
98
|
+
@daemonize = options.has_key?(:daemonize) ? options[:daemonize] : true
|
99
|
+
@pidfile = options[:pidfile] || "/var/run/cognizant/cognizantd.pid"
|
100
|
+
@logfile = options[:logfile] || "/var/log/cognizant/cognizantd.log"
|
101
|
+
@loglevel = options[:loglevel].to_i || Logger::INFO
|
102
|
+
@socket = options[:socket] || "/var/run/cognizant/cognizantd.sock"
|
103
|
+
@port = options[:port] || nil
|
104
|
+
@username = options[:username] || nil
|
105
|
+
@password = options[:password] || nil
|
106
|
+
@trace = options[:trace] || nil
|
107
|
+
|
108
|
+
# Processes config.
|
109
|
+
@pids_dir = options[:pids_dir] || "/var/run/cognizant/pids/"
|
110
|
+
@logs_dir = options[:logs_dir] || "/var/log/cognizant/logs/"
|
111
|
+
@env = options[:env] || {}
|
112
|
+
@chdir = options[:chdir] || nil
|
113
|
+
@umask = options[:umask] || nil
|
114
|
+
@user = options[:user] || nil
|
115
|
+
@group = options[:group] || nil
|
116
|
+
|
117
|
+
# Expand paths.
|
118
|
+
@socket = File.expand_path(@socket)
|
119
|
+
@pidfile = File.expand_path(@pidfile)
|
120
|
+
@logfile = File.expand_path(@logfile)
|
121
|
+
@pids_dir = File.expand_path(@pids_dir)
|
122
|
+
@logs_dir = File.expand_path(@logs_dir)
|
123
|
+
|
124
|
+
self.processes = {}
|
125
|
+
|
126
|
+
# # Only available through a config file/stdin.
|
127
|
+
# load_processes(options[:monitor]) if options.has_key?(:monitor)
|
128
|
+
end
|
129
|
+
|
130
|
+
def bootup
|
131
|
+
setup_prerequisites
|
132
|
+
trap_signals
|
133
|
+
log.info "Booting up cognizantd..."
|
134
|
+
EventMachine.run do
|
135
|
+
start_interface_server
|
136
|
+
start_periodic_ticks
|
137
|
+
daemonize
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def load(config_file)
|
142
|
+
config_file = File.expand_path(config_file)
|
143
|
+
log.info "Loading config from #{config_file}..."
|
144
|
+
# config = YAML.load_file(config_file)
|
145
|
+
# config = config.inject({}) { |c,(k,v)| c[k.gsub("-", "_").to_sym] = v; c }
|
146
|
+
# load_processes(config[:monitor]) if config.has_key?(:monitor)
|
147
|
+
Kernel.load(config_file)
|
148
|
+
end
|
149
|
+
|
150
|
+
def monitor(process_name = nil, attributes = {}, &block)
|
151
|
+
process = Cognizant::Process.new(process_name, attributes, &block)
|
152
|
+
self.processes[process_name] = process
|
153
|
+
process.monitor
|
154
|
+
end
|
155
|
+
|
156
|
+
# Stops the TCP server and the tick loop, and performs cleanup.
|
157
|
+
def shutdown
|
158
|
+
log.info "Shutting down cognizantd..."
|
159
|
+
|
160
|
+
EventMachine.next_tick do
|
161
|
+
EventMachine.stop
|
162
|
+
logger.close
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
private
|
167
|
+
|
168
|
+
def load_processes(processes_to_load)
|
169
|
+
if processes_to_load
|
170
|
+
processes_to_load.each do |name, attributes|
|
171
|
+
monitor(name, attributes)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
# Starts the TCP server with the set socket lock file or port.
|
177
|
+
def start_interface_server
|
178
|
+
if port = @port
|
179
|
+
log.info "Starting the TCP server at #{@port}..."
|
180
|
+
host = "127.0.0.1"
|
181
|
+
splitted = port.to_s.split(":")
|
182
|
+
host, port = splitted if splitted.size > 1
|
183
|
+
EventMachine.start_server(host, port, Server::Interface)
|
184
|
+
else
|
185
|
+
log.info "Starting the UNIX domain server with socket #{@socket}..."
|
186
|
+
EventMachine.start_unix_domain_server(@socket, Server::Interface)
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
# Starts the loop that defines the time window for determining and acting upon process states.
|
191
|
+
def start_periodic_ticks
|
192
|
+
log.info "Starting the periodic tick..."
|
193
|
+
EventMachine.add_periodic_timer(1) do
|
194
|
+
self.processes.each do |group, process|
|
195
|
+
process.tick
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
def setup_prerequisites
|
201
|
+
# Create the require directories.
|
202
|
+
[File.dirname(@pidfile), File.dirname(@logfile), @pids_dir, @logs_dir, File.dirname(@socket)].each do |directory|
|
203
|
+
FileUtils.mkdir_p(directory)
|
204
|
+
end
|
205
|
+
|
206
|
+
# Setup logging.
|
207
|
+
add_log_adapter(File.open(@logfile, "a"))
|
208
|
+
add_log_adapter($stdout) unless @daemonize
|
209
|
+
log.level = if @trace then Logger::DEBUG else @loglevel end
|
210
|
+
end
|
211
|
+
|
212
|
+
def trap_signals
|
213
|
+
terminator = Proc.new do
|
214
|
+
log.info "Received signal to shutdown."
|
215
|
+
shutdown
|
216
|
+
end
|
217
|
+
|
218
|
+
Signal.trap('TERM', &terminator)
|
219
|
+
Signal.trap('INT', &terminator)
|
220
|
+
Signal.trap('QUIT', &terminator)
|
221
|
+
end
|
222
|
+
|
223
|
+
# Daemonize the current process and save it pid in a file.
|
224
|
+
def daemonize
|
225
|
+
if @daemonize
|
226
|
+
log.info "Daemonizing into the background..."
|
227
|
+
::Process.daemon
|
228
|
+
|
229
|
+
pid = ::Process.pid
|
230
|
+
|
231
|
+
if @pidfile
|
232
|
+
log.info "Writing the daemon pid (#{pid}) to the pidfile..."
|
233
|
+
File.open(@pidfile, "w") { |f| f.write(pid) }
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require "json"
|
2
|
+
require "eventmachine"
|
3
|
+
|
4
|
+
require "cognizant/server/commands"
|
5
|
+
|
6
|
+
module Cognizant
|
7
|
+
module Server
|
8
|
+
class Interface < EventMachine::Connection
|
9
|
+
def post_init
|
10
|
+
# puts "-- someone connected to the server!"
|
11
|
+
end
|
12
|
+
|
13
|
+
def receive_data(args)
|
14
|
+
args = [*args.split]
|
15
|
+
command = args.shift.to_s.strip.downcase
|
16
|
+
if command.size > 0
|
17
|
+
begin
|
18
|
+
Commands.send(command, *args) do |response|
|
19
|
+
send_data "#{response.to_json}\r\n\r\n"
|
20
|
+
end
|
21
|
+
rescue => e
|
22
|
+
send_data "#{e.inspect.to_json}\r\n\r\n"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
# close_connection_after_writing
|
26
|
+
end
|
27
|
+
|
28
|
+
def unbind
|
29
|
+
# puts "-- someone disconnected from the server!"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# module Cognizant
|
36
|
+
# module Server
|
37
|
+
# class Interface < EventMachine::Connection
|
38
|
+
# include EventMachine::Protocols::ObjectProtocol
|
39
|
+
# # include EventMachine::Protocols::SASLauth
|
40
|
+
#
|
41
|
+
# def post_init
|
42
|
+
# @obj = Hash.new
|
43
|
+
# puts "-- someone connected to the echo server!"
|
44
|
+
# end
|
45
|
+
#
|
46
|
+
# def receive_object(method)
|
47
|
+
# send_object @obj.send(*method)
|
48
|
+
# end
|
49
|
+
#
|
50
|
+
# def unbind
|
51
|
+
# @obj = nil
|
52
|
+
# puts "-- someone disconnected from the echo server!"
|
53
|
+
# end
|
54
|
+
#
|
55
|
+
# # def validate(usr, psw, sys, realm)
|
56
|
+
# # usr == TestUser and psw == TestPsw
|
57
|
+
# # end
|
58
|
+
# end
|
59
|
+
# end
|
60
|
+
# end
|
@@ -0,0 +1,142 @@
|
|
1
|
+
module Cognizant
|
2
|
+
module Validations
|
3
|
+
class ValidationError < StandardError; end
|
4
|
+
|
5
|
+
# Validations the user/group ownership to the given file. Attempts to
|
6
|
+
# create the directory+file if it doesn't already exist.
|
7
|
+
# @param [String] file Path to a file
|
8
|
+
def self.validate_file_writable(file, type = "file")
|
9
|
+
file = File.expand_path(file)
|
10
|
+
|
11
|
+
begin
|
12
|
+
filetype = File.ftype(file)
|
13
|
+
|
14
|
+
unless filetype.eql?(type)
|
15
|
+
raise ValidationError, "\"#{file}\" is a #{filetype}. File required."
|
16
|
+
end
|
17
|
+
rescue Errno::ENOENT
|
18
|
+
self.validate_directory_writable(File.dirname(file))
|
19
|
+
|
20
|
+
begin
|
21
|
+
unless File.open(file, "w")
|
22
|
+
raise ValidationError, "The file \"#{file}\" is not writable."
|
23
|
+
end
|
24
|
+
rescue Errno::EACCES
|
25
|
+
raise ValidationError, "The file \"#{file}\" could not be created due to the lack of privileges."
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
unless File.owned?(file) or File.grpowned?(file)
|
30
|
+
raise ValidationError, "The file \"#{file}\" is not owned by the process user."
|
31
|
+
end
|
32
|
+
|
33
|
+
begin
|
34
|
+
unless File.open(file, "w")
|
35
|
+
raise ValidationError, "The file \"#{file}\" is not writable."
|
36
|
+
end
|
37
|
+
rescue Errno::EACCES
|
38
|
+
raise ValidationError, "The file \"#{file}\" is not accessible due to the lack of privileges."
|
39
|
+
rescue
|
40
|
+
raise ValidationError, "The file \"#{file}\" is not writable."
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# Validations the user/group ownership to the given directory. Attempts to
|
45
|
+
# create the directory if it doesn't already exist.
|
46
|
+
# @param [String] directory Path to a directory
|
47
|
+
def self.validate_directory_writable(directory)
|
48
|
+
directory = File.expand_path(directory)
|
49
|
+
|
50
|
+
begin
|
51
|
+
filetype = File.ftype(directory)
|
52
|
+
|
53
|
+
unless filetype.eql?("directory")
|
54
|
+
raise ValidationError, "\"#{directory}\" is a #{filetype}. Directory required."
|
55
|
+
end
|
56
|
+
rescue Errno::ENOENT
|
57
|
+
begin
|
58
|
+
FileUtils.mkdir_p(directory)
|
59
|
+
rescue Errno::EACCES
|
60
|
+
raise ValidationError, "The directory \"#{directory}\" could not be created due to the lack of privileges."
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
unless File.owned?(directory) or File.grpowned?(directory)
|
65
|
+
raise ValidationError, "The directory \"#{directory}\" is not owned by the process user."
|
66
|
+
end
|
67
|
+
|
68
|
+
begin
|
69
|
+
unless File.open(File.join(directory, ".testfile"), "w")
|
70
|
+
raise ValidationError, "The directory \"#{directory}\" is not writable."
|
71
|
+
end
|
72
|
+
rescue Errno::EACCES
|
73
|
+
raise ValidationError, "The directory \"#{directory}\" is not accessible due to the lack of privileges."
|
74
|
+
rescue
|
75
|
+
raise ValidationError, "The directory \"#{directory}\" is not writable."
|
76
|
+
ensure
|
77
|
+
File.delete(directory, ".testfile") rescue nil
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# Validates the inclusion of a value in an array.
|
82
|
+
# @param [Object] value The value to validate.
|
83
|
+
# @param [Array] array The array of allowed values.
|
84
|
+
def self.validate_includes(value, array)
|
85
|
+
unless [*array].include?(value)
|
86
|
+
raise ValidationError, "#{value} is an invalid option type. It must be one of the following: #{[*array].join(', ')}."
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# Validates the env variable to be a hash.
|
91
|
+
# @param [Object] env The value to validate.
|
92
|
+
def self.validate_env(env)
|
93
|
+
return unless env
|
94
|
+
if not env.respond_to?(:is_a?) or not env.is_a?(Hash)
|
95
|
+
raise Validations::ValidationError, %{"env" needs to be a hash. e.g. { "PATH" => "/usr/local/bin" }}
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
# Validates the umask variable to be a number.
|
100
|
+
# @param [Object] umask The value to validate.
|
101
|
+
def self.validate_umask(umask)
|
102
|
+
return unless umask
|
103
|
+
Float(umask) rescue raise Validations::ValidationError, %{The umask "#{umask}" is invalid.}
|
104
|
+
end
|
105
|
+
|
106
|
+
# Validates the existence of the user in the system.
|
107
|
+
# @param [String, Integer] user The user ID or name to validate.
|
108
|
+
def self.validate_user(user)
|
109
|
+
return unless user
|
110
|
+
begin
|
111
|
+
if self.is_number?(user)
|
112
|
+
Etc.getpwuid(user)
|
113
|
+
else
|
114
|
+
Etc.getpwnam(user)
|
115
|
+
end
|
116
|
+
rescue ArgumentError
|
117
|
+
raise Validations::ValidationError, %{The user "#{user}" does not exist.}
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
# Validates the existence of the user group in the system.
|
122
|
+
# @param [String, Integer] group The user group ID or name to validate.
|
123
|
+
def self.validate_user_group(group)
|
124
|
+
return unless group
|
125
|
+
begin
|
126
|
+
if self.is_number?(group)
|
127
|
+
Etc.getgrgid(group)
|
128
|
+
else
|
129
|
+
Etc.getgrname(group)
|
130
|
+
end
|
131
|
+
rescue ArgumentError
|
132
|
+
raise Validations::ValidationError, %{The group "#{group}" does not exist.}
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
private
|
137
|
+
|
138
|
+
def self.is_number?(value)
|
139
|
+
true if Float(value) rescue false
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
data/lib/cognizant.rb
ADDED
metadata
ADDED
@@ -0,0 +1,169 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: cognizant
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Gurpartap Singh
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-11-01 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: redcarpet
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: yard
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: eventmachine
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: state_machine
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :runtime
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
description: Process monitoring and management framework
|
95
|
+
email:
|
96
|
+
- contact@gurpartap.com
|
97
|
+
executables:
|
98
|
+
- cognizant
|
99
|
+
- cognizantd
|
100
|
+
extensions: []
|
101
|
+
extra_rdoc_files: []
|
102
|
+
files:
|
103
|
+
- .gitignore
|
104
|
+
- .yardopts
|
105
|
+
- Gemfile
|
106
|
+
- LICENSE
|
107
|
+
- README.md
|
108
|
+
- Rakefile
|
109
|
+
- bin/cognizant
|
110
|
+
- bin/cognizantd
|
111
|
+
- cognizant.gemspec
|
112
|
+
- examples/cognizantd.yml
|
113
|
+
- examples/redis-server.rb
|
114
|
+
- examples/resque.rb
|
115
|
+
- images/logo-small.png
|
116
|
+
- images/logo.png
|
117
|
+
- images/logo.pxm
|
118
|
+
- lib/cognizant.rb
|
119
|
+
- lib/cognizant/client/cli.rb
|
120
|
+
- lib/cognizant/client/interface.rb
|
121
|
+
- lib/cognizant/logging.rb
|
122
|
+
- lib/cognizant/process.rb
|
123
|
+
- lib/cognizant/process/actions.rb
|
124
|
+
- lib/cognizant/process/actions/restart.rb
|
125
|
+
- lib/cognizant/process/actions/start.rb
|
126
|
+
- lib/cognizant/process/actions/stop.rb
|
127
|
+
- lib/cognizant/process/attributes.rb
|
128
|
+
- lib/cognizant/process/execution.rb
|
129
|
+
- lib/cognizant/process/pid.rb
|
130
|
+
- lib/cognizant/process/status.rb
|
131
|
+
- lib/cognizant/server.rb
|
132
|
+
- lib/cognizant/server/commands.rb
|
133
|
+
- lib/cognizant/server/daemon.rb
|
134
|
+
- lib/cognizant/server/interface.rb
|
135
|
+
- lib/cognizant/validations.rb
|
136
|
+
- lib/cognizant/version.rb
|
137
|
+
homepage: http://gurpartap.github.com/cognizant/
|
138
|
+
licenses: []
|
139
|
+
post_install_message:
|
140
|
+
rdoc_options: []
|
141
|
+
require_paths:
|
142
|
+
- lib
|
143
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
144
|
+
none: false
|
145
|
+
requirements:
|
146
|
+
- - ! '>='
|
147
|
+
- !ruby/object:Gem::Version
|
148
|
+
version: '0'
|
149
|
+
segments:
|
150
|
+
- 0
|
151
|
+
hash: 2933141880858945843
|
152
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
153
|
+
none: false
|
154
|
+
requirements:
|
155
|
+
- - ! '>='
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: '0'
|
158
|
+
segments:
|
159
|
+
- 0
|
160
|
+
hash: 2933141880858945843
|
161
|
+
requirements: []
|
162
|
+
rubyforge_project:
|
163
|
+
rubygems_version: 1.8.24
|
164
|
+
signing_key:
|
165
|
+
specification_version: 3
|
166
|
+
summary: Cognizant is an advanced and efficient process monitoring and management
|
167
|
+
framework.
|
168
|
+
test_files: []
|
169
|
+
has_rdoc:
|