rctl 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/bin/rctl ADDED
@@ -0,0 +1,76 @@
1
+ #!/usr/bin/ruby
2
+ #charset: utf-8
3
+
4
+ #
5
+ # Copyright (c) 2012 Olivier Amblet<olivier@amblet.net>
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person
8
+ # obtaining a copy of this software and associated documentation
9
+ # files (the "Software"), to deal in the Software without
10
+ # restriction, including without limitation the rights to use,
11
+ # copy, modify, merge, publish, distribute, sublicense, and/or sell
12
+ # copies of the Software, and to permit persons to whom the
13
+ # Software is furnished to do so, subject to the following
14
+ # conditions:
15
+ #
16
+ # The above copyright notice and this permission notice shall be
17
+ # included in all copies or substantial portions of the Software.
18
+ #
19
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
21
+ # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
23
+ # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24
+ # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
26
+ # OTHER DEALINGS IN THE SOFTWARE.
27
+ #
28
+
29
+ require 'rctl'
30
+ require 'rctl/version'
31
+ require 'optparse'
32
+
33
+ ctl = Rctl::Ctl.new
34
+ server_switch = []
35
+ usage = false
36
+ options = {}
37
+
38
+
39
+ parser = OptionParser.new do |opt|
40
+ opt.banner = "Usage: rctl COMMAND [OPTIONS]"
41
+ opt.separator ""
42
+ opt.separator "Commands"
43
+ opt.separator " start start server(s)"
44
+ opt.separator " stop stop server(s)"
45
+ opt.separator ""
46
+ opt.separator "Options"
47
+
48
+ opt.on("-a", "--all", "do COMMAND on all servers (by default)") { server_switch = ctl.commands.keys }
49
+
50
+ ctl.commands.each do |name, args|
51
+ opt.on("-#{args['short']}", "--#{name.to_s}", "do COMMAND on #{name.to_s} server") do
52
+ server_switch.push name
53
+ end
54
+ end
55
+
56
+ opt.on "-c CONFIG_FILE", "--config", "Read an alternate YAML configuration file (default is created in ~/.rctl.rc.yaml)." do |f|
57
+ options[:config] = File.expand_path(f)
58
+ end
59
+
60
+ opt.on("-v", "--version", "display version information") do
61
+ puts "Rctl CTL version #{Rctl::CtlVersion::VERSION}"
62
+ exit
63
+ end
64
+
65
+ opt.on("-h", "--help", "display this help message") do
66
+ usage = true
67
+ end
68
+ end
69
+ parser.parse!
70
+
71
+ if usage || !ARGV[0] || ARGV[0] == 'help'
72
+ puts parser
73
+ else
74
+ server_switch = ctl.commands.keys if server_switch.empty?
75
+ exec ctl.generate(ARGV[0], server_switch)
76
+ end
data/lib/rctl.rb ADDED
@@ -0,0 +1,93 @@
1
+ require 'yaml'
2
+ require 'pathname'
3
+
4
+ module Rctl
5
+ class Ctl
6
+ attr_reader :commands
7
+
8
+ def initialize(options = {})
9
+ if(options[:config])
10
+ @commands = YAML.load_file(options[:config])
11
+ else
12
+ if(!File.exists? "~/.rctl.rc.yml")
13
+ @commands = YAML.load_file(Pathname(__FILE__) + '../rctl/default_config.yml')
14
+ File.open(File.expand_path("~/.rctl.rc.yml"), 'w') do |file|
15
+ YAML.dump(@commands, file)
16
+ end
17
+ else
18
+ @commands = YAML.load_file("~/.rctl.rc.yml")
19
+ end
20
+ end
21
+ @start_order = define_start_order
22
+ end
23
+
24
+ # launch command on selected services.
25
+ # return 0 if everything went ok.
26
+ def generate(command = :start, services = {})
27
+ generate_command(command, services)
28
+ end
29
+
30
+ private
31
+ def define_start_order(remaining_server = nil)
32
+ if(remaining_server.nil?)
33
+ remaining_server = @commands.keys
34
+ end
35
+ ordered = []
36
+ to_order = []
37
+ remaining_server.each do |name|
38
+ if (@commands[name]['dependencies'].nil? || @commands[name]['dependencies'].empty?) ||
39
+ (@commands[name]['dependencies'].is_a?(Array) && (@commands[name]['dependencies'].select {|d| remaining_server.include?(d)}).count == 0) ||
40
+ (! remaining_server.include?(@commands[name]['dependencies'].to_s))
41
+ ordered.push name
42
+ else
43
+ to_order.push name
44
+ end
45
+ end
46
+
47
+ if remaining_server.count == 0
48
+ return ordered
49
+ elsif remaining_server.count == to_order.count
50
+ throw Exception.new("Circular dependencies in remaining server #{to_order}")
51
+ else
52
+ ordered.concat define_start_order(to_order)
53
+ end
54
+ end
55
+
56
+ def help
57
+ return "echo '#{@parser.to_s}'"
58
+ end
59
+
60
+ def generate_command(command, services)
61
+ sw = @start_order.select {|s| services.include?(s)}
62
+ sw.reverse! if command == 'stop'
63
+ return(sw.map do |name|
64
+ "echo '---> #{command} #{name.to_s}' && #{@commands[name][command]}"
65
+ end.join(" && "))
66
+ end
67
+
68
+ # Build the parser given @@server_desc data
69
+ def build_parser
70
+ @parser = OptionParser.new do |opt|
71
+ opt.banner = "Usage: rctl COMMAND [OPTIONS]"
72
+ opt.separator ""
73
+ opt.separator "Commands"
74
+ opt.separator " start start server(s)"
75
+ opt.separator " stop stop server(s)"
76
+ opt.separator ""
77
+ opt.separator "Options"
78
+
79
+ opt.on("-a", "--all", "do COMMAND on all servers (by default)") { all }
80
+
81
+ @commands.each do |name, args|
82
+ opt.on("-#{args[:short]}", "--#{name.to_s}", "do COMMAND on #{name.to_s} server") do
83
+ @server_switch.push name
84
+ end
85
+ end
86
+
87
+ opt.on("-h", "--help", "help") do
88
+ @usage = true
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,28 @@
1
+ mysql:
2
+ short: m
3
+ start: 'mysql.server start'
4
+ stop: 'mysql.server stop'
5
+ mongodb:
6
+ short: o
7
+ start: 'mongod run --config /usr/local/etc/mongod.conf --fork --logpath /usr/local/var/log/mongodb/mongod.log'
8
+ stop: 'killall -2 mongod'
9
+ solr:
10
+ dependencies:
11
+ - mongodb
12
+ - mysql
13
+ short: s
14
+ start: 'bundle exec rake sunspot:solr:start'
15
+ stop: "ps aux | grep 'solr' | grep -v 'grep' | awk '{print $2}' | xargs kill -2"
16
+ unicorn:
17
+ dependencies:
18
+ - solr
19
+ - mongodb
20
+ - mysql
21
+ short: u
22
+ start: 'bundle exec unicorn -c ./config/unicorn.conf.rb -D'
23
+ stop: "ps aux | grep 'unicorn master' | grep -v 'grep' | awk '{print $2}' | xargs kill -QUIT"
24
+ nginx:
25
+ dependencies: unicorn
26
+ short: n
27
+ start: 'sudo /usr/local/sbin/nginx'
28
+ stop: "ps aux | grep 'nginx' | grep -v 'grep' | awk '{print $2}' | sudo xargs kill -QUIT"
@@ -0,0 +1,5 @@
1
+ module Rctl
2
+ module CtlVersion
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
metadata ADDED
@@ -0,0 +1,113 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rctl
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Olivier Amblet
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-06-01 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: guard
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: guard-minitest
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: growl
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: rake
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
+ description:
79
+ email: olivier@amblet.net
80
+ executables:
81
+ - rctl
82
+ extensions: []
83
+ extra_rdoc_files: []
84
+ files:
85
+ - bin/rctl
86
+ - lib/rctl/default_config.yml
87
+ - lib/rctl/version.rb
88
+ - lib/rctl.rb
89
+ homepage: http://rctl.com
90
+ licenses: []
91
+ post_install_message:
92
+ rdoc_options: []
93
+ require_paths:
94
+ - lib
95
+ required_ruby_version: !ruby/object:Gem::Requirement
96
+ none: false
97
+ requirements:
98
+ - - ! '>='
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ required_rubygems_version: !ruby/object:Gem::Requirement
102
+ none: false
103
+ requirements:
104
+ - - ! '>='
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ requirements: []
108
+ rubyforge_project:
109
+ rubygems_version: 1.8.24
110
+ signing_key:
111
+ specification_version: 3
112
+ summary: rctl let you start and stop your service stack in one command.
113
+ test_files: []