ruby-supervisor 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Build Status](https://secure.travis-ci.org/schmurfy/ruby-supervisor.png)](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
|