cognizant 0.0.1
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.
- 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:
|