ruby-supervisor 0.0.2
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 +4 -0
- data/.travis.yml +3 -0
- data/Gemfile +4 -0
- data/Guardfile +21 -0
- data/README.md +47 -0
- data/Rakefile +14 -0
- data/lib/ruby-supervisor.rb +7 -0
- data/lib/ruby-supervisor/api.rb +52 -0
- data/lib/ruby-supervisor/api/global.rb +146 -0
- data/lib/ruby-supervisor/api/process.rb +114 -0
- data/lib/ruby-supervisor/api/process_group.rb +53 -0
- data/lib/ruby-supervisor/api/process_logs.rb +67 -0
- data/lib/ruby-supervisor/proxy.rb +23 -0
- data/lib/ruby-supervisor/version.rb +3 -0
- data/ruby-supervisor.gemspec +31 -0
- data/spec/api/global_spec.rb +82 -0
- data/spec/api/process_group_spec.rb +29 -0
- data/spec/api/process_logs_spec.rb +54 -0
- data/spec/api/process_spec.rb +48 -0
- data/spec/api_spec.rb +22 -0
- data/spec/spec_helper.rb +18 -0
- metadata +166 -0
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
guard 'rspec', :version => 2 do
|
5
|
+
watch(%r{^spec/.+_spec\.rb$})
|
6
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
7
|
+
watch('spec/spec_helper.rb') { "spec" }
|
8
|
+
|
9
|
+
# Rails example
|
10
|
+
watch(%r{^spec/.+_spec\.rb$})
|
11
|
+
watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
12
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
13
|
+
watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
|
14
|
+
watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
|
15
|
+
watch('spec/spec_helper.rb') { "spec" }
|
16
|
+
watch('config/routes.rb') { "spec/routing" }
|
17
|
+
watch('app/controllers/application_controller.rb') { "spec/controllers" }
|
18
|
+
# Capybara request specs
|
19
|
+
watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/requests/#{m[1]}_spec.rb" }
|
20
|
+
end
|
21
|
+
|
data/README.md
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
|
2
|
+
[](https://secure.travis-ci.org/schmurfy/ruby-supervisor.png)
|
3
|
+
|
4
|
+
# What is this ?
|
5
|
+
|
6
|
+
I needed an interface to Supervisor, a python alternative to daemontools amongst others and
|
7
|
+
since I did not found any in ruby I made mine !
|
8
|
+
|
9
|
+
Instead of blindly mapping the XML-RPC methods I decided to built an API which feels more
|
10
|
+
like a native ruby API than an ugly java like thing.
|
11
|
+
|
12
|
+
# Examples
|
13
|
+
|
14
|
+
```ruby
|
15
|
+
require 'ruby-supervisor'
|
16
|
+
client = RubySupervisor::Client.new('192.168.0.32', 9001,
|
17
|
+
:user => 'user',
|
18
|
+
:password => 'secret'
|
19
|
+
)
|
20
|
+
|
21
|
+
process = client.process('collectd')
|
22
|
+
|
23
|
+
puts "You are running supervisor version #{client.version}"
|
24
|
+
|
25
|
+
p process.state
|
26
|
+
# => :running
|
27
|
+
|
28
|
+
p process.logs.read(0, 21)
|
29
|
+
# => "some line of 21 bytes"
|
30
|
+
|
31
|
+
process.logs.clear()
|
32
|
+
process.restart()
|
33
|
+
```
|
34
|
+
|
35
|
+
|
36
|
+
|
37
|
+
# Development
|
38
|
+
|
39
|
+
- clone the repository
|
40
|
+
- run "bundle"
|
41
|
+
- run "bundle exec guard" to automatically run tests on changes
|
42
|
+
- run "bundle exec rake rspec" to run all specs
|
43
|
+
|
44
|
+
# Supported versions
|
45
|
+
|
46
|
+
- ruby 1.9.2
|
47
|
+
- ruby 1.8.7
|
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler/setup'
|
3
|
+
require "bundler/gem_tasks"
|
4
|
+
require "rspec/core/rake_task"
|
5
|
+
|
6
|
+
task :default => :spec
|
7
|
+
task :rspec => :spec
|
8
|
+
|
9
|
+
desc "Run all specs"
|
10
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
11
|
+
t.rspec_opts = %w[--color]
|
12
|
+
t.verbose = false
|
13
|
+
end
|
14
|
+
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'xmlrpc/client'
|
2
|
+
require File.expand_path('../api/global', __FILE__)
|
3
|
+
require File.expand_path('../api/process', __FILE__)
|
4
|
+
require File.expand_path('../api/process_logs', __FILE__)
|
5
|
+
require File.expand_path('../api/process_group', __FILE__)
|
6
|
+
|
7
|
+
|
8
|
+
module RubySupervisor
|
9
|
+
|
10
|
+
##
|
11
|
+
# Main class, one client is connected to one supervisor
|
12
|
+
# instance.
|
13
|
+
#
|
14
|
+
# @param [String] address network server address
|
15
|
+
# @param [Integer] port server port
|
16
|
+
#
|
17
|
+
class Client
|
18
|
+
|
19
|
+
include ProcessAPI
|
20
|
+
include ProcessGroupAPI
|
21
|
+
include GlobalAPI
|
22
|
+
|
23
|
+
|
24
|
+
def initialize(address = '127.0.0.1', port = 9001, params = {})
|
25
|
+
params = params.merge(
|
26
|
+
:host => address,
|
27
|
+
:port => port
|
28
|
+
)
|
29
|
+
|
30
|
+
@xmlrpc_client = XMLRPC::Client.new3(params)
|
31
|
+
check_api_version()
|
32
|
+
end
|
33
|
+
|
34
|
+
##
|
35
|
+
# Check that the API version is supported.
|
36
|
+
#
|
37
|
+
def check_api_version
|
38
|
+
v = api_version()
|
39
|
+
if v != "3.0"
|
40
|
+
raise "unsupported API: #{v}"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def request(command, *args)
|
48
|
+
@xmlrpc_client.call("supervisor.#{command}", *args)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
require File.expand_path('../../proxy', __FILE__)
|
2
|
+
|
3
|
+
module RubySupervisor
|
4
|
+
|
5
|
+
module GlobalAPI
|
6
|
+
|
7
|
+
#
|
8
|
+
# returned by get_state
|
9
|
+
#
|
10
|
+
STATE_TO_STR = {
|
11
|
+
2 => :fatal,
|
12
|
+
1 => :running,
|
13
|
+
0 => :restarting,
|
14
|
+
-1 => :shutdown
|
15
|
+
}.freeze
|
16
|
+
|
17
|
+
|
18
|
+
##
|
19
|
+
# Return the API Version.
|
20
|
+
#
|
21
|
+
# @return [String] API Version
|
22
|
+
#
|
23
|
+
def api_version
|
24
|
+
request('getAPIVersion')
|
25
|
+
end
|
26
|
+
|
27
|
+
##
|
28
|
+
# Return supervisor version.
|
29
|
+
#
|
30
|
+
# @return [String] Supervisor version
|
31
|
+
#
|
32
|
+
def version
|
33
|
+
request('getSupervisorVersion')
|
34
|
+
end
|
35
|
+
|
36
|
+
##
|
37
|
+
# Return supervisor identifying string.
|
38
|
+
# Aliased as identifier.
|
39
|
+
#
|
40
|
+
# @return [String] identifier
|
41
|
+
#
|
42
|
+
def identification
|
43
|
+
request('getIdentification')
|
44
|
+
end
|
45
|
+
alias :identifier :identification
|
46
|
+
|
47
|
+
##
|
48
|
+
# Return supervisor pid.
|
49
|
+
#
|
50
|
+
# @return [Integer] PID
|
51
|
+
#
|
52
|
+
def pid
|
53
|
+
request('getPID')
|
54
|
+
end
|
55
|
+
|
56
|
+
##
|
57
|
+
# Return supervisor current state.
|
58
|
+
#
|
59
|
+
# @return [Symbol] Supervisor state
|
60
|
+
#
|
61
|
+
def state
|
62
|
+
ret = request('getState')
|
63
|
+
STATE_TO_STR[ ret['statecode'] ]
|
64
|
+
end
|
65
|
+
|
66
|
+
##
|
67
|
+
# Return informations for all defined
|
68
|
+
# processes.
|
69
|
+
#
|
70
|
+
# @return [Array] An array of hash
|
71
|
+
#
|
72
|
+
def processes
|
73
|
+
request('getAllProcessInfo')
|
74
|
+
end
|
75
|
+
|
76
|
+
##
|
77
|
+
# Start all processes.
|
78
|
+
#
|
79
|
+
# @param [Boolean] wait if true the call will
|
80
|
+
# block until all processes are started.
|
81
|
+
#
|
82
|
+
def start_processes(wait = true)
|
83
|
+
request('startAllProcesses', wait)
|
84
|
+
end
|
85
|
+
|
86
|
+
##
|
87
|
+
# Stop all processes.
|
88
|
+
#
|
89
|
+
# @param [Boolean] wait if true the call will
|
90
|
+
# block until all processes are stopped.
|
91
|
+
#
|
92
|
+
def stop_processes(wait = true)
|
93
|
+
request('stopAllProcesses', wait)
|
94
|
+
end
|
95
|
+
|
96
|
+
##
|
97
|
+
# Clear logs for all processes.
|
98
|
+
#
|
99
|
+
def clear_processes_logs
|
100
|
+
request('clearAllProcessesLogs')
|
101
|
+
end
|
102
|
+
|
103
|
+
##
|
104
|
+
# Read a chunk of the supervisor logs.
|
105
|
+
#
|
106
|
+
# @param [Integer] offset where to start
|
107
|
+
# @param [Integer] length How many bytes to read
|
108
|
+
#
|
109
|
+
# @return [String] logs data
|
110
|
+
#
|
111
|
+
def read_log(offset, length)
|
112
|
+
request('readLog', offset, length)
|
113
|
+
end
|
114
|
+
|
115
|
+
##
|
116
|
+
# Clear the supervisor logs.
|
117
|
+
#
|
118
|
+
def clear_log
|
119
|
+
request('clearLog')
|
120
|
+
end
|
121
|
+
|
122
|
+
##
|
123
|
+
# Restart the supervisor process.
|
124
|
+
#
|
125
|
+
def restart
|
126
|
+
request('restart')
|
127
|
+
end
|
128
|
+
|
129
|
+
##
|
130
|
+
# Shutdown the supervisor process.
|
131
|
+
#
|
132
|
+
def shutdown
|
133
|
+
request('shutdown')
|
134
|
+
end
|
135
|
+
|
136
|
+
##
|
137
|
+
# Send an event that will be received by event listener
|
138
|
+
# subprocesses subscribing to the RemoteCommunicationEvent
|
139
|
+
#
|
140
|
+
def send_remote_comm_event(type, data)
|
141
|
+
request('sendRemoteCommEvent', type, data)
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
require File.expand_path('../../proxy', __FILE__)
|
2
|
+
require File.expand_path('../process_logs', __FILE__)
|
3
|
+
|
4
|
+
module RubySupervisor
|
5
|
+
|
6
|
+
module ProcessAPI
|
7
|
+
def process(name)
|
8
|
+
ProcessProxy.new(self, name)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
##
|
13
|
+
# Process Proxy.
|
14
|
+
#
|
15
|
+
# Note: you can address programs in a group via this name:
|
16
|
+
# <group>:<process>
|
17
|
+
#
|
18
|
+
class ProcessProxy < NamedProxy
|
19
|
+
|
20
|
+
include ProcessLogsAPI
|
21
|
+
|
22
|
+
STATE_TO_STR = {
|
23
|
+
0 => :stopped,
|
24
|
+
10 => :starting,
|
25
|
+
20 => :running,
|
26
|
+
30 => :backoff,
|
27
|
+
40 => :stopping,
|
28
|
+
100 => :exited,
|
29
|
+
200 => :fatal,
|
30
|
+
1000 => :unknown
|
31
|
+
}.freeze
|
32
|
+
|
33
|
+
STR_TO_STATE = STATE_TO_STR.invert.freeze
|
34
|
+
|
35
|
+
##
|
36
|
+
# Return process state as symbol.
|
37
|
+
#
|
38
|
+
# @return [Symbol] The process state
|
39
|
+
#
|
40
|
+
def state
|
41
|
+
state = infos['state']
|
42
|
+
STATE_TO_STR[ state ]
|
43
|
+
end
|
44
|
+
|
45
|
+
##
|
46
|
+
# Return informations about process.
|
47
|
+
#
|
48
|
+
# @return [Hash] Informations about the process
|
49
|
+
#
|
50
|
+
def infos
|
51
|
+
request('getProcessInfo', @name)
|
52
|
+
end
|
53
|
+
|
54
|
+
##
|
55
|
+
# Start the process.
|
56
|
+
#
|
57
|
+
# @param [Boolean] wait if true the call will
|
58
|
+
# block until the process is started.
|
59
|
+
#
|
60
|
+
def start(wait = true)
|
61
|
+
request('startProcess', @name, wait)
|
62
|
+
end
|
63
|
+
|
64
|
+
##
|
65
|
+
# Stop the process.
|
66
|
+
#
|
67
|
+
# @param [Boolean] wait if true the call will
|
68
|
+
# block until the process is stopped.
|
69
|
+
#
|
70
|
+
def stop(wait = true)
|
71
|
+
request('stopProcess', @name, wait)
|
72
|
+
end
|
73
|
+
|
74
|
+
##
|
75
|
+
# Restart the process.
|
76
|
+
# If you pass a block to this method it will get called
|
77
|
+
# after the actual restart.
|
78
|
+
# Be aware that wehn using a block with wait = false your block
|
79
|
+
# will be scheduled in a separate thread !
|
80
|
+
#
|
81
|
+
# @param [Boolean] wait if true the call will
|
82
|
+
# block until the process is restarted.
|
83
|
+
#
|
84
|
+
def restart(wait = true, &block)
|
85
|
+
if wait
|
86
|
+
begin
|
87
|
+
stop(true)
|
88
|
+
ensure
|
89
|
+
start(true)
|
90
|
+
end
|
91
|
+
|
92
|
+
block.call if block
|
93
|
+
else
|
94
|
+
Thread.new do
|
95
|
+
stop(true)
|
96
|
+
start(true)
|
97
|
+
block.call if block
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
##
|
103
|
+
# Write data to the process standard input.
|
104
|
+
#
|
105
|
+
# @param [String] data data to send to the
|
106
|
+
# process.
|
107
|
+
#
|
108
|
+
def send_stdin(data)
|
109
|
+
request('sendProcessStdin', @name, data)
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require File.expand_path('../../proxy', __FILE__)
|
2
|
+
|
3
|
+
# TODO: find what the hell this call is supposed to do:
|
4
|
+
# addProcessGroup
|
5
|
+
#
|
6
|
+
|
7
|
+
module RubySupervisor
|
8
|
+
|
9
|
+
module ProcessGroupAPI
|
10
|
+
def group(name)
|
11
|
+
ProcessGroupProxy.new(self, name)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
##
|
16
|
+
# Process Group Proxy.
|
17
|
+
#
|
18
|
+
class ProcessGroupProxy < NamedProxy
|
19
|
+
|
20
|
+
##
|
21
|
+
# Start the process group.
|
22
|
+
#
|
23
|
+
# @param [Boolean] wait if true the call will
|
24
|
+
# block until the process group is started.
|
25
|
+
#
|
26
|
+
def start(wait = true)
|
27
|
+
request('startProcessGroup', @name, wait)
|
28
|
+
end
|
29
|
+
|
30
|
+
##
|
31
|
+
# Stop the process group.
|
32
|
+
#
|
33
|
+
# @param [Boolean] wait if true the call will
|
34
|
+
# block until the process group is stopped.
|
35
|
+
#
|
36
|
+
def stop(wait = true)
|
37
|
+
request('stopProcessGroup', @name, wait)
|
38
|
+
end
|
39
|
+
|
40
|
+
##
|
41
|
+
# Restart the process group.
|
42
|
+
#
|
43
|
+
# @param [Boolean] wait if true the call will
|
44
|
+
# block until the process group is restarted.
|
45
|
+
#
|
46
|
+
def restart(wait = true)
|
47
|
+
stop(wait)
|
48
|
+
start(wait)
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require File.expand_path('../../proxy', __FILE__)
|
2
|
+
|
3
|
+
module RubySupervisor
|
4
|
+
|
5
|
+
module ProcessLogsAPI
|
6
|
+
def logs
|
7
|
+
ProcessLogsProxy.new(@xmlrpc_client, @name)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class ProcessLogsProxy < NamedProxy
|
12
|
+
|
13
|
+
##
|
14
|
+
# Clear the logs and reopen them,
|
15
|
+
# both stderr and stdout logs will be cleared.
|
16
|
+
#
|
17
|
+
def clear
|
18
|
+
request('clearProcessLogs', @name)
|
19
|
+
end
|
20
|
+
|
21
|
+
##
|
22
|
+
# Read chunk of logs for this process.
|
23
|
+
#
|
24
|
+
# @param [Integer] offset where to start from
|
25
|
+
# @param [Integer] length How many bytes to read
|
26
|
+
# @param [Symbol] what :stdout or :stderr
|
27
|
+
#
|
28
|
+
# @return [String] Log data
|
29
|
+
#
|
30
|
+
def read(offset, length, what = :stdout)
|
31
|
+
case what
|
32
|
+
when :stdout then call = 'readProcessStdoutLog'
|
33
|
+
when :stderr then call = 'readProcessStderrLog'
|
34
|
+
else
|
35
|
+
raise "invalid value for what parameter: #{what}"
|
36
|
+
end
|
37
|
+
|
38
|
+
request(call, @name, offset, length)
|
39
|
+
end
|
40
|
+
|
41
|
+
##
|
42
|
+
# Tail chunk of logs for this process.
|
43
|
+
#
|
44
|
+
# What is the real difference between read and tail ?
|
45
|
+
# I have currently no idea ! documentation is rather...
|
46
|
+
# vague.
|
47
|
+
#
|
48
|
+
# @param [Integer] offset where to start from
|
49
|
+
# @param [Integer] length How many bytes to read
|
50
|
+
# @param [Symbol] what :stdout or :stderr
|
51
|
+
#
|
52
|
+
# @return [Array] [bytes read, offset, overflow]
|
53
|
+
#
|
54
|
+
def tail(offset, length, what = :stdout)
|
55
|
+
case what
|
56
|
+
when :stdout then call = 'tailProcessStdoutLog'
|
57
|
+
when :stderr then call = 'tailProcessStderrLog'
|
58
|
+
else
|
59
|
+
raise "invalid value for what parameter: #{what}"
|
60
|
+
end
|
61
|
+
|
62
|
+
request(call, @name, offset, length)
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module RubySupervisor
|
2
|
+
|
3
|
+
class Proxy
|
4
|
+
def initialize(xmlrpc_client)
|
5
|
+
@xmlrpc_client = xmlrpc_client
|
6
|
+
end
|
7
|
+
|
8
|
+
private
|
9
|
+
def request(cmd, *args)
|
10
|
+
@xmlrpc_client.send(:request, cmd, *args)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class NamedProxy < Proxy
|
15
|
+
attr_reader :name
|
16
|
+
|
17
|
+
def initialize(xmlrpc_client, name)
|
18
|
+
super(xmlrpc_client)
|
19
|
+
@name = name
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "ruby-supervisor/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "ruby-supervisor"
|
7
|
+
s.version = RubySupervisor::VERSION
|
8
|
+
s.authors = ["Julien Ammous"]
|
9
|
+
s.email = ["schmurfy@gmail.com"]
|
10
|
+
s.homepage = ""
|
11
|
+
s.summary = %q{Ruby Interface to supervisord}
|
12
|
+
s.description = %q{uses XMLRPC supervisord API to communciate with supervisord}
|
13
|
+
|
14
|
+
s.rubyforge_project = "ruby-supervisor"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
# s.add_runtime_dependency "rest-client"
|
22
|
+
|
23
|
+
s.add_development_dependency "rspec", '~> 2.6'
|
24
|
+
s.add_development_dependency "guard", '~> 0.7.0'
|
25
|
+
s.add_development_dependency "guard-rspec", '~> 0.4.5'
|
26
|
+
s.add_development_dependency "growl", '~> 1.0.3'
|
27
|
+
s.add_development_dependency "rb-fsevent", '~> 0.4.3'
|
28
|
+
s.add_development_dependency "mocha", '~> 0.10.0'
|
29
|
+
s.add_development_dependency "simplecov", '~> 0.5.3'
|
30
|
+
s.add_development_dependency "rake", '~> 0.9.2'
|
31
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require File.expand_path('../../spec_helper', __FILE__)
|
2
|
+
require File.expand_path('../../../lib/ruby-supervisor/api', __FILE__)
|
3
|
+
|
4
|
+
describe 'Global API' do
|
5
|
+
before do
|
6
|
+
@server = stub('XMLRPC::Client', :call => nil)
|
7
|
+
XMLRPC::Client.stubs(:new2).returns(@server)
|
8
|
+
RubySupervisor::Client.any_instance.stubs(:check_api_version)
|
9
|
+
@client = RubySupervisor::Client.new
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'should return api version' do
|
13
|
+
@client.expects(:request).with('getAPIVersion').returns('3.0')
|
14
|
+
@client.api_version.should == "3.0"
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should return supervisor version' do
|
18
|
+
@client.expects(:request).with('getSupervisorVersion').returns('1.0')
|
19
|
+
@client.version.should == '1.0'
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should return its identification' do
|
23
|
+
@client.expects(:request).with('getIdentification').returns('supervisor')
|
24
|
+
@client.identifier.should == 'supervisor'
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should return its PID' do
|
28
|
+
@client.expects(:request).with('getPID').returns(340)
|
29
|
+
@client.pid.should == 340
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should return its state' do
|
33
|
+
@client.expects(:request).with('getState').returns('statecode' => 1)
|
34
|
+
@client.state.should == :running
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should returns process state' do
|
38
|
+
@client.expects(:request).with('getAllProcessInfo').returns([])
|
39
|
+
@client.processes.should == []
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'can start all processes' do
|
43
|
+
@client.expects(:request).with('startAllProcesses', false)
|
44
|
+
@client.start_processes(false)
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'can stop all processes' do
|
48
|
+
@client.expects(:request).with('stopAllProcesses', false)
|
49
|
+
@client.stop_processes(false)
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'can clear all processes logs' do
|
53
|
+
@client.expects(:request).with('clearAllProcessesLogs')
|
54
|
+
@client.clear_processes_logs()
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'can read supervisor logs' do
|
58
|
+
@client.expects(:request).with('readLog', 1, 45)
|
59
|
+
@client.read_log(1, 45)
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'can clear supervisor logs' do
|
63
|
+
@client.expects(:request).with('clearLog')
|
64
|
+
@client.clear_log()
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'can restart supervisor process' do
|
68
|
+
@client.expects(:request).with('restart')
|
69
|
+
@client.restart()
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'can shutdown supervisor process' do
|
73
|
+
@client.expects(:request).with('shutdown')
|
74
|
+
@client.shutdown()
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'can send remote comm event' do
|
78
|
+
@client.expects(:request).with('sendRemoteCommEvent', 1, 23)
|
79
|
+
@client.send_remote_comm_event(1, 23)
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require File.expand_path('../../spec_helper', __FILE__)
|
2
|
+
require File.expand_path('../../../lib/ruby-supervisor/api', __FILE__)
|
3
|
+
|
4
|
+
describe 'Process group API' do
|
5
|
+
before do
|
6
|
+
@server = stub('XMLRPC::Client', :call => nil)
|
7
|
+
XMLRPC::Client.stubs(:new2).returns(@server)
|
8
|
+
RubySupervisor::Client.any_instance.stubs(:check_api_version)
|
9
|
+
@client = RubySupervisor::Client.new
|
10
|
+
@proxy = @client.group('test')
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'can start a group' do
|
14
|
+
@proxy.expects(:request).with('startProcessGroup', @proxy.name, false)
|
15
|
+
@proxy.start(false)
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'can stop a group' do
|
19
|
+
@proxy.expects(:request).with('stopProcessGroup', @proxy.name, false)
|
20
|
+
@proxy.stop(false)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'can restart a group' do
|
24
|
+
@proxy.expects(:request).with('startProcessGroup', @proxy.name, false)
|
25
|
+
@proxy.expects(:request).with('stopProcessGroup', @proxy.name, false)
|
26
|
+
@proxy.restart(false)
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require File.expand_path('../../spec_helper', __FILE__)
|
2
|
+
require File.expand_path('../../../lib/ruby-supervisor/api', __FILE__)
|
3
|
+
|
4
|
+
describe 'Process logs API' do
|
5
|
+
before do
|
6
|
+
@server = stub('XMLRPC::Client', :call => nil)
|
7
|
+
XMLRPC::Client.stubs(:new2).returns(@server)
|
8
|
+
RubySupervisor::Client.any_instance.stubs(:check_api_version)
|
9
|
+
@client = RubySupervisor::Client.new
|
10
|
+
@proxy = @client.process('test').logs
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'can clear logs' do
|
14
|
+
@proxy.expects(:request).with('clearProcessLogs', @proxy.name)
|
15
|
+
@proxy.clear()
|
16
|
+
end
|
17
|
+
|
18
|
+
describe 'tail' do
|
19
|
+
it 'can tail data from stdout logs' do
|
20
|
+
@proxy.expects(:request).with('tailProcessStdoutLog', @proxy.name, 2, 34)
|
21
|
+
@proxy.tail(2, 34, :stdout)
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'can tail data from stderr logs' do
|
25
|
+
@proxy.expects(:request).with('tailProcessStderrLog', @proxy.name, 2, 34)
|
26
|
+
@proxy.tail(2, 34, :stderr)
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should raise an error with invalid parameters' do
|
30
|
+
proc{
|
31
|
+
@proxy.tail(2, 34, :invalid)
|
32
|
+
}.should raise_error
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe 'read' do
|
37
|
+
it 'can read data from stdout logs' do
|
38
|
+
@proxy.expects(:request).with('readProcessStdoutLog', @proxy.name, 2, 34)
|
39
|
+
@proxy.read(2, 34, :stdout)
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'can read data from stderr logs' do
|
43
|
+
@proxy.expects(:request).with('readProcessStderrLog', @proxy.name, 2, 34)
|
44
|
+
@proxy.read(2, 34, :stderr)
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'should raise an error with invalid parameters' do
|
48
|
+
proc{
|
49
|
+
@proxy.read(2, 34, :invalid)
|
50
|
+
}.should raise_error
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require File.expand_path('../../spec_helper', __FILE__)
|
2
|
+
require File.expand_path('../../../lib/ruby-supervisor/api', __FILE__)
|
3
|
+
|
4
|
+
describe 'Process API' do
|
5
|
+
before do
|
6
|
+
@server = stub('XMLRPC::Client', :call => nil)
|
7
|
+
XMLRPC::Client.stubs(:new2).returns(@server)
|
8
|
+
RubySupervisor::Client.any_instance.stubs(:check_api_version)
|
9
|
+
@client = RubySupervisor::Client.new
|
10
|
+
@proxy = @client.process('test')
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should return the process state' do
|
14
|
+
@proxy.expects(:request).with('getProcessInfo', @proxy.name).returns('state' => 30)
|
15
|
+
@proxy.state.should == :backoff
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should return a ProcessProxy' do
|
19
|
+
@proxy.should be_a(RubySupervisor::ProcessProxy)
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'can retrieve process infos' do
|
23
|
+
@client.expects(:request).with('getProcessInfo', @proxy.name)
|
24
|
+
@proxy.infos()
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'can start process' do
|
28
|
+
@client.expects(:request).with('startProcess', @proxy.name, true)
|
29
|
+
@proxy.start()
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'can stop process' do
|
33
|
+
@client.expects(:request).with('stopProcess', @proxy.name, true)
|
34
|
+
@proxy.stop()
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'can restart process' do
|
38
|
+
@client.expects(:request).with('stopProcess', @proxy.name, true)
|
39
|
+
@client.expects(:request).with('startProcess', @proxy.name, true)
|
40
|
+
@proxy.restart()
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'can write data to process standard input' do
|
44
|
+
@client.expects(:request).with('sendProcessStdin', @proxy.name, 'something')
|
45
|
+
@proxy.send_stdin('something')
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
data/spec/api_spec.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require File.expand_path('../spec_helper', __FILE__)
|
2
|
+
require File.expand_path('../../lib/ruby-supervisor/api', __FILE__)
|
3
|
+
|
4
|
+
describe 'API client' do
|
5
|
+
before do
|
6
|
+
@server = stub('XMLRPC::Client', :call => nil)
|
7
|
+
XMLRPC::Client.stubs(:new3).returns(@server)
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'should check api version on connect' do
|
11
|
+
@server.expects(:call).with('supervisor.getAPIVersion').returns('3.0')
|
12
|
+
@client = RubySupervisor::Client.new
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should raise an error on invalid api version' do
|
16
|
+
@server.expects(:call).with('supervisor.getAPIVersion').returns('2.0')
|
17
|
+
proc{
|
18
|
+
@client = RubySupervisor::Client.new
|
19
|
+
}.should raise_error
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
|
2
|
+
require 'rubygems'
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'rspec'
|
5
|
+
|
6
|
+
if (RUBY_VERSION >= "1.9") && ENV['COVERAGE']
|
7
|
+
require 'simplecov'
|
8
|
+
|
9
|
+
ROOT = File.expand_path('../../', __FILE__)
|
10
|
+
|
11
|
+
SimpleCov.start do
|
12
|
+
root(ROOT)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
RSpec.configure do |config|
|
17
|
+
config.mock_with :mocha
|
18
|
+
end
|
metadata
ADDED
@@ -0,0 +1,166 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ruby-supervisor
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Julien Ammous
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-03-01 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rspec
|
16
|
+
requirement: &70324485674020 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '2.6'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70324485674020
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: guard
|
27
|
+
requirement: &70324485673520 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ~>
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 0.7.0
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70324485673520
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: guard-rspec
|
38
|
+
requirement: &70324485673060 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 0.4.5
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70324485673060
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: growl
|
49
|
+
requirement: &70324485672600 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 1.0.3
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70324485672600
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: rb-fsevent
|
60
|
+
requirement: &70324485688480 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ~>
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: 0.4.3
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *70324485688480
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: mocha
|
71
|
+
requirement: &70324485687980 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ~>
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: 0.10.0
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: *70324485687980
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: simplecov
|
82
|
+
requirement: &70324485687340 !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ~>
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: 0.5.3
|
88
|
+
type: :development
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: *70324485687340
|
91
|
+
- !ruby/object:Gem::Dependency
|
92
|
+
name: rake
|
93
|
+
requirement: &70324485686740 !ruby/object:Gem::Requirement
|
94
|
+
none: false
|
95
|
+
requirements:
|
96
|
+
- - ~>
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: 0.9.2
|
99
|
+
type: :development
|
100
|
+
prerelease: false
|
101
|
+
version_requirements: *70324485686740
|
102
|
+
description: uses XMLRPC supervisord API to communciate with supervisord
|
103
|
+
email:
|
104
|
+
- schmurfy@gmail.com
|
105
|
+
executables: []
|
106
|
+
extensions: []
|
107
|
+
extra_rdoc_files: []
|
108
|
+
files:
|
109
|
+
- .gitignore
|
110
|
+
- .travis.yml
|
111
|
+
- Gemfile
|
112
|
+
- Guardfile
|
113
|
+
- README.md
|
114
|
+
- Rakefile
|
115
|
+
- lib/ruby-supervisor.rb
|
116
|
+
- lib/ruby-supervisor/api.rb
|
117
|
+
- lib/ruby-supervisor/api/global.rb
|
118
|
+
- lib/ruby-supervisor/api/process.rb
|
119
|
+
- lib/ruby-supervisor/api/process_group.rb
|
120
|
+
- lib/ruby-supervisor/api/process_logs.rb
|
121
|
+
- lib/ruby-supervisor/proxy.rb
|
122
|
+
- lib/ruby-supervisor/version.rb
|
123
|
+
- ruby-supervisor.gemspec
|
124
|
+
- spec/api/global_spec.rb
|
125
|
+
- spec/api/process_group_spec.rb
|
126
|
+
- spec/api/process_logs_spec.rb
|
127
|
+
- spec/api/process_spec.rb
|
128
|
+
- spec/api_spec.rb
|
129
|
+
- spec/spec_helper.rb
|
130
|
+
homepage: ''
|
131
|
+
licenses: []
|
132
|
+
post_install_message:
|
133
|
+
rdoc_options: []
|
134
|
+
require_paths:
|
135
|
+
- lib
|
136
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
138
|
+
requirements:
|
139
|
+
- - ! '>='
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
142
|
+
segments:
|
143
|
+
- 0
|
144
|
+
hash: -1444959157378247391
|
145
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
146
|
+
none: false
|
147
|
+
requirements:
|
148
|
+
- - ! '>='
|
149
|
+
- !ruby/object:Gem::Version
|
150
|
+
version: '0'
|
151
|
+
segments:
|
152
|
+
- 0
|
153
|
+
hash: -1444959157378247391
|
154
|
+
requirements: []
|
155
|
+
rubyforge_project: ruby-supervisor
|
156
|
+
rubygems_version: 1.8.15
|
157
|
+
signing_key:
|
158
|
+
specification_version: 3
|
159
|
+
summary: Ruby Interface to supervisord
|
160
|
+
test_files:
|
161
|
+
- spec/api/global_spec.rb
|
162
|
+
- spec/api/process_group_spec.rb
|
163
|
+
- spec/api/process_logs_spec.rb
|
164
|
+
- spec/api/process_spec.rb
|
165
|
+
- spec/api_spec.rb
|
166
|
+
- spec/spec_helper.rb
|