srv_manager 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.
- checksums.yaml +7 -0
- data/.gitignore +19 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +1 -0
- data/bin/srv +176 -0
- data/lib/srv_manager/command.rb +21 -0
- data/lib/srv_manager/context.rb +60 -0
- data/lib/srv_manager/monitor.rb +43 -0
- data/lib/srv_manager/process.rb +76 -0
- data/lib/srv_manager/service.rb +54 -0
- data/lib/srv_manager/version.rb +3 -0
- data/lib/srv_manager.rb +21 -0
- data/rvm/runner +14 -0
- data/srv_manager.gemspec +23 -0
- metadata +88 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6257e9538f38e3ce480fcb2a4a46475e01af1489
|
4
|
+
data.tar.gz: 15d9025f67277caacecc04b3d6a3677fe2b13923
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b3124811a5c420f7e2683ee271ef8dc274cbdc67397531f44d8bb5e9ed1722c6e142874c72c025e27d3a928e2785f502a4b923a3acdaa50cc808a36db13ea6de
|
7
|
+
data.tar.gz: 55932a2d5f6883bb8c8adfb6a797c10cfcfd151b4056a2fd42f6dd054411c5011a2364bd97b513ba58a2b1421d1c26a0d934470ea01ecb16810a87d3a2560b7f
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Gabriel Naiman
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# SrvManager
|
2
|
+
|
3
|
+
Service admin and monitor
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'srv_manager'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install srv_manager
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/srv
ADDED
@@ -0,0 +1,176 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'thor'
|
3
|
+
require 'hirb'
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
require File.expand_path('../lib/srv_manager', File.dirname(__FILE__))
|
7
|
+
|
8
|
+
|
9
|
+
module SrvManager
|
10
|
+
class CLI < Thor
|
11
|
+
|
12
|
+
desc 'version', 'Show SrvManager version number'
|
13
|
+
def version
|
14
|
+
puts SrvManager::VERSION
|
15
|
+
end
|
16
|
+
|
17
|
+
option :dir, aliases: :d
|
18
|
+
option :processes, aliases: :p, type: :numeric
|
19
|
+
option :auto, type: :boolean
|
20
|
+
option :rvm, type: :boolean
|
21
|
+
option :env, type: :hash
|
22
|
+
desc 'add <NAME> <COMMAND>', 'Add new service'
|
23
|
+
def add(name, command)
|
24
|
+
Context.scoped do |ctx|
|
25
|
+
ctx.services << Service.new(name, command, options)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
desc 'rm <NAME>', 'Remove service'
|
30
|
+
def rm(name)
|
31
|
+
Context.scoped do |ctx|
|
32
|
+
service = find_service name, ctx
|
33
|
+
if service
|
34
|
+
service.stop
|
35
|
+
ctx.services.delete service
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
desc 'start <NAME>', 'Start service'
|
41
|
+
def start(name)
|
42
|
+
Context.scoped(safe: true) do |ctx|
|
43
|
+
service = find_service name, ctx
|
44
|
+
service.start
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
desc 'stop <NAME>', 'Stop service'
|
49
|
+
def stop(name)
|
50
|
+
Context.scoped(safe: true) do |ctx|
|
51
|
+
service = find_service name, ctx
|
52
|
+
service.stop
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
desc 'restart <NAME>', 'Restart service'
|
57
|
+
def restart(name)
|
58
|
+
Context.scoped(safe: true) do |ctx|
|
59
|
+
service = find_service name, ctx
|
60
|
+
service.restart
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
desc 'ps <NAME>', 'Show service processes'
|
65
|
+
def ps(name)
|
66
|
+
Context.scoped do |ctx|
|
67
|
+
service = find_service name, ctx
|
68
|
+
|
69
|
+
return if service.processes.empty?
|
70
|
+
|
71
|
+
processes = service.processes.map do |process|
|
72
|
+
{
|
73
|
+
PID: process.id,
|
74
|
+
Status: process.alive? ? 'Running' : 'Killed'
|
75
|
+
}
|
76
|
+
end
|
77
|
+
puts Hirb::Helpers::AutoTable.render(processes, unicode: true, fields: [:PID, :Status])
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
option :start, type: :boolean
|
82
|
+
option :stop, type: :boolean
|
83
|
+
desc 'monitor', 'Start service monitor'
|
84
|
+
def monitor
|
85
|
+
Context.scoped do |ctx|
|
86
|
+
if options[:stop]
|
87
|
+
if ctx.monitor.alive?
|
88
|
+
ctx.monitor.stop
|
89
|
+
puts 'Monitor stoped'
|
90
|
+
end
|
91
|
+
elsif options[:start]
|
92
|
+
if ctx.monitor.alive?
|
93
|
+
puts "Monitor already started (PID: #{ctx.monitor.pid})"
|
94
|
+
else
|
95
|
+
ctx.monitor.start
|
96
|
+
puts "Monitor started (PID: #{ctx.monitor.pid})"
|
97
|
+
end
|
98
|
+
else
|
99
|
+
if ctx.monitor.alive?
|
100
|
+
puts "Monitor running (PID: #{ctx.monitor.pid})"
|
101
|
+
else
|
102
|
+
puts 'Monitor not running'
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
desc 'logs', 'Show logs'
|
109
|
+
def logs
|
110
|
+
puts `tail #{LOG_FILE}`
|
111
|
+
end
|
112
|
+
|
113
|
+
option :dir, type: :boolean, aliases: :d
|
114
|
+
option :env, type: :boolean, aliases: :e
|
115
|
+
desc 'ls', 'List configured services'
|
116
|
+
def ls
|
117
|
+
Context.scoped do |ctx|
|
118
|
+
return if ctx.services.empty?
|
119
|
+
|
120
|
+
services = ctx.services.sort_by(&:name).map do |service|
|
121
|
+
{
|
122
|
+
Service: service.name,
|
123
|
+
Status: service.started? ? 'Started' : 'Stoped',
|
124
|
+
Alive: service.processes.select(&:alive?).count,
|
125
|
+
Dead: service.processes.reject(&:alive?).count,
|
126
|
+
Command: service.command.text,
|
127
|
+
Env: service.command.env.map{|k,v| "#{k}=#{v}"},
|
128
|
+
Dir: service.command.dir
|
129
|
+
}
|
130
|
+
end
|
131
|
+
|
132
|
+
fields = [:Service, :Status, :Alive, :Dead, :Command]
|
133
|
+
fields << :Env if options[:env]
|
134
|
+
fields << :Dir if options[:dir]
|
135
|
+
|
136
|
+
puts Hirb::Helpers::AutoTable.render(services, unicode: true, fields: fields)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
desc 'clean', 'Remove all services'
|
141
|
+
def clean
|
142
|
+
Context.scoped(safe: true) do |ctx|
|
143
|
+
ctx.clean
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
desc 'dump', 'Dump service configuration'
|
148
|
+
def dump
|
149
|
+
Context.scoped do |ctx|
|
150
|
+
puts JSON.pretty_generate(ctx.to_hash)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
desc 'load', 'Load service configuration'
|
155
|
+
def load(filename)
|
156
|
+
json = JSON.parse(File.read(filename))
|
157
|
+
Context.scoped do |ctx|
|
158
|
+
ctx.load json
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
private
|
163
|
+
|
164
|
+
def find_service(name, context)
|
165
|
+
service = context.services.detect { |s| s.name == name }
|
166
|
+
unless service
|
167
|
+
puts "Service not found: #{name}"
|
168
|
+
exit 1
|
169
|
+
end
|
170
|
+
service
|
171
|
+
end
|
172
|
+
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
SrvManager::CLI.start
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module SrvManager
|
2
|
+
class Command
|
3
|
+
|
4
|
+
attr_reader :text
|
5
|
+
attr_reader :dir
|
6
|
+
attr_reader :env
|
7
|
+
attr_reader :rvm
|
8
|
+
|
9
|
+
def initialize(text, options={})
|
10
|
+
@text = text
|
11
|
+
@dir = File.expand_path options[:dir].to_s
|
12
|
+
@env = options[:env] || {}
|
13
|
+
@rvm = options[:rvm] || false
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_hash
|
17
|
+
{text: text, dir: dir, env: env, rvm: rvm}
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module SrvManager
|
2
|
+
class Context
|
3
|
+
|
4
|
+
def monitor
|
5
|
+
@monitor ||= Monitor.new
|
6
|
+
end
|
7
|
+
|
8
|
+
def services
|
9
|
+
@services ||= []
|
10
|
+
end
|
11
|
+
|
12
|
+
def clean
|
13
|
+
services.each(&:stop)
|
14
|
+
services.clear
|
15
|
+
end
|
16
|
+
|
17
|
+
def load(json)
|
18
|
+
clean
|
19
|
+
@services = json['services'].map { |js| Service.parse js }
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.scoped(options={})
|
23
|
+
context = load
|
24
|
+
monitor_running = options[:safe] && context.monitor.alive?
|
25
|
+
context.monitor.stop if monitor_running
|
26
|
+
begin
|
27
|
+
yield context
|
28
|
+
ensure
|
29
|
+
save context
|
30
|
+
if monitor_running
|
31
|
+
context.monitor.start
|
32
|
+
save context
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def to_hash
|
38
|
+
{services: services.map(&:to_hash)}
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def self.load
|
44
|
+
LOGGER.info "Reading context from #{data_file}"
|
45
|
+
return new unless File.exists? data_file
|
46
|
+
Marshal.load(File.read(data_file))
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.save(context)
|
50
|
+
LOGGER.info "Saving context to #{data_file}"
|
51
|
+
FileUtils.mkpath File.dirname(data_file) unless Dir.exists? File.dirname(data_file)
|
52
|
+
File.write data_file, Marshal.dump(context)
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.data_file
|
56
|
+
File.expand_path('.srv_manager/context.bin', Dir.home)
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module SrvManager
|
2
|
+
class Monitor
|
3
|
+
|
4
|
+
attr_reader :pid
|
5
|
+
|
6
|
+
def start(sleep_time=60)
|
7
|
+
@pid = ::Process.fork do
|
8
|
+
loop do
|
9
|
+
Context.scoped do |ctx|
|
10
|
+
ctx.services.each do |service|
|
11
|
+
keep_alive service
|
12
|
+
end
|
13
|
+
end
|
14
|
+
sleep sleep_time
|
15
|
+
end
|
16
|
+
end
|
17
|
+
::Process.detach @pid
|
18
|
+
end
|
19
|
+
|
20
|
+
def stop
|
21
|
+
::Process.kill 'TERM', pid if pid
|
22
|
+
rescue Errno::ESRCH
|
23
|
+
end
|
24
|
+
|
25
|
+
def alive?
|
26
|
+
pid && ::Process.kill(0, pid) ? true : false
|
27
|
+
rescue Errno::ESRCH
|
28
|
+
false
|
29
|
+
end
|
30
|
+
|
31
|
+
def keep_alive(service)
|
32
|
+
service.processes.each do |process|
|
33
|
+
LOGGER.info "Monitoring service: #{service.name} (#{process.id || 'stoped'})"
|
34
|
+
if !process.started? && service.auto
|
35
|
+
process.start
|
36
|
+
elsif process.started? && !process.alive?
|
37
|
+
process.restart
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module SrvManager
|
2
|
+
class Process
|
3
|
+
|
4
|
+
attr_reader :command
|
5
|
+
attr_reader :id
|
6
|
+
|
7
|
+
def initialize(command)
|
8
|
+
@command = command
|
9
|
+
end
|
10
|
+
|
11
|
+
def start
|
12
|
+
return if alive?
|
13
|
+
command.rvm ? rvm_start : default_start
|
14
|
+
LOGGER.info "Started process #{@id}"
|
15
|
+
end
|
16
|
+
|
17
|
+
def stop
|
18
|
+
return unless started?
|
19
|
+
begin
|
20
|
+
::Process.kill 'TERM', @id
|
21
|
+
rescue Errno::ESRCH
|
22
|
+
end
|
23
|
+
LOGGER.info "Stoped process #{@id}"
|
24
|
+
@id = nil
|
25
|
+
end
|
26
|
+
|
27
|
+
def restart
|
28
|
+
stop if alive?
|
29
|
+
start
|
30
|
+
end
|
31
|
+
|
32
|
+
def started?
|
33
|
+
!id.nil?
|
34
|
+
end
|
35
|
+
|
36
|
+
def alive?
|
37
|
+
started? && ::Process.kill(0, id) ? true : false
|
38
|
+
rescue Errno::ESRCH
|
39
|
+
false
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def detault_start
|
45
|
+
@id = ::Process.spawn command.env, command.text, chdir: command.dir, out: '/dev/null', err: '/dev/null'
|
46
|
+
::Process.detach @id
|
47
|
+
end
|
48
|
+
|
49
|
+
def rvm_start
|
50
|
+
pid_file = File.expand_path "#{self.object_id}_#{Time.now.to_i}.pid", TMP_PATH
|
51
|
+
rvm_pid = ::Process.spawn command.env.merge('SRV_COMMAND' => command.text, 'SRV_PIDFILE' => pid_file),
|
52
|
+
RVM_RUNNER,
|
53
|
+
chdir: command.dir,
|
54
|
+
out: '/dev/null',
|
55
|
+
err: '/dev/null'
|
56
|
+
::Process.detach rvm_pid
|
57
|
+
@id = wait_for_pid pid_file
|
58
|
+
end
|
59
|
+
|
60
|
+
def wait_for_pid(filename)
|
61
|
+
Timeout.timeout(60) do
|
62
|
+
loop do
|
63
|
+
if File.exists? filename
|
64
|
+
pid = File.read(filename).to_i
|
65
|
+
File.delete filename
|
66
|
+
return pid
|
67
|
+
end
|
68
|
+
sleep 0.1
|
69
|
+
end
|
70
|
+
end
|
71
|
+
rescue Timeout::Error
|
72
|
+
nil
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module SrvManager
|
2
|
+
class Service
|
3
|
+
|
4
|
+
attr_reader :name
|
5
|
+
attr_reader :command
|
6
|
+
attr_reader :processes
|
7
|
+
attr_reader :auto
|
8
|
+
|
9
|
+
def initialize(name, command, options={})
|
10
|
+
@name = name
|
11
|
+
|
12
|
+
@command = Command.new command, options
|
13
|
+
|
14
|
+
@processes = (options[:processes] || 1).times.map do
|
15
|
+
Process.new @command
|
16
|
+
end
|
17
|
+
|
18
|
+
@auto = options[:auto] || false
|
19
|
+
end
|
20
|
+
|
21
|
+
def start
|
22
|
+
processes.each(&:start)
|
23
|
+
LOGGER.info "Started service #{name}"
|
24
|
+
end
|
25
|
+
|
26
|
+
def stop
|
27
|
+
processes.each(&:stop)
|
28
|
+
LOGGER.info "Stoped service #{name}"
|
29
|
+
end
|
30
|
+
|
31
|
+
def restart
|
32
|
+
processes.each(&:restart)
|
33
|
+
end
|
34
|
+
|
35
|
+
def started?
|
36
|
+
processes.map(&:started?).reduce(:|)
|
37
|
+
end
|
38
|
+
|
39
|
+
def to_hash
|
40
|
+
{name: name, command: command.to_hash, processes: processes.count, auto: auto}
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.parse(json)
|
44
|
+
new json['name'],
|
45
|
+
json['command']['text'],
|
46
|
+
dir: json['command']['dir'],
|
47
|
+
env: json['command']['env'],
|
48
|
+
rvm: json['command']['rvm'],
|
49
|
+
processes: json['processes'],
|
50
|
+
auto: json['auto']
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
data/lib/srv_manager.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'logger'
|
3
|
+
require 'timeout'
|
4
|
+
|
5
|
+
Dir.glob(File.expand_path('srv_manager/*.rb', File.dirname(__FILE__))).each { |f| require f }
|
6
|
+
|
7
|
+
|
8
|
+
module SrvManager
|
9
|
+
|
10
|
+
PATH = File.expand_path '.srv_manager', Dir.home
|
11
|
+
FileUtils.mkpath PATH unless Dir.exists? PATH
|
12
|
+
|
13
|
+
TMP_PATH = File.expand_path 'tmp', PATH
|
14
|
+
FileUtils.mkpath TMP_PATH unless Dir.exists? TMP_PATH
|
15
|
+
|
16
|
+
LOG_FILE = File.expand_path 'events.log', PATH
|
17
|
+
LOGGER = Logger.new LOG_FILE
|
18
|
+
|
19
|
+
RVM_RUNNER = File.expand_path '../rvm/runner', File.dirname(__FILE__)
|
20
|
+
|
21
|
+
end
|
data/rvm/runner
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
# Load RVM into a shell session *as a function*
|
4
|
+
if [[ -s "$HOME/.rvm/scripts/rvm" ]] ; then
|
5
|
+
# First try to load from a user install
|
6
|
+
source "$HOME/.rvm/scripts/rvm"
|
7
|
+
elif [[ -s "/usr/local/rvm/scripts/rvm" ]] ; then
|
8
|
+
# Then try to load from a root install
|
9
|
+
source "/usr/local/rvm/scripts/rvm"
|
10
|
+
else
|
11
|
+
printf "ERROR: An RVM installation was not found.\n"
|
12
|
+
fi
|
13
|
+
|
14
|
+
$SRV_COMMAND & echo $! > $SRV_PIDFILE
|
data/srv_manager.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'srv_manager/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "srv_manager"
|
8
|
+
spec.version = SrvManager::VERSION
|
9
|
+
spec.authors = ["Gabriel Naiman"]
|
10
|
+
spec.email = ["gabynaiman@gmail.com"]
|
11
|
+
spec.description = 'Service admin and monitor'
|
12
|
+
spec.summary = 'Service admin and monitor'
|
13
|
+
spec.homepage = 'http://github.com/gabynaiman/srv_manager'
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
end
|
metadata
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: srv_manager
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Gabriel Naiman
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-11-04 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description: Service admin and monitor
|
42
|
+
email:
|
43
|
+
- gabynaiman@gmail.com
|
44
|
+
executables:
|
45
|
+
- srv
|
46
|
+
extensions: []
|
47
|
+
extra_rdoc_files: []
|
48
|
+
files:
|
49
|
+
- .gitignore
|
50
|
+
- Gemfile
|
51
|
+
- LICENSE.txt
|
52
|
+
- README.md
|
53
|
+
- Rakefile
|
54
|
+
- bin/srv
|
55
|
+
- lib/srv_manager.rb
|
56
|
+
- lib/srv_manager/command.rb
|
57
|
+
- lib/srv_manager/context.rb
|
58
|
+
- lib/srv_manager/monitor.rb
|
59
|
+
- lib/srv_manager/process.rb
|
60
|
+
- lib/srv_manager/service.rb
|
61
|
+
- lib/srv_manager/version.rb
|
62
|
+
- rvm/runner
|
63
|
+
- srv_manager.gemspec
|
64
|
+
homepage: http://github.com/gabynaiman/srv_manager
|
65
|
+
licenses:
|
66
|
+
- MIT
|
67
|
+
metadata: {}
|
68
|
+
post_install_message:
|
69
|
+
rdoc_options: []
|
70
|
+
require_paths:
|
71
|
+
- lib
|
72
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - '>='
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
requirements: []
|
83
|
+
rubyforge_project:
|
84
|
+
rubygems_version: 2.1.10
|
85
|
+
signing_key:
|
86
|
+
specification_version: 4
|
87
|
+
summary: Service admin and monitor
|
88
|
+
test_files: []
|