rctl 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/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: []