tyrantmanager 1.0.9
Sign up to get free protection for your applications and to get access to all the features.
- data/HISTORY +28 -0
- data/LICENSE +13 -0
- data/README +273 -0
- data/bin/tyrantmanager +10 -0
- data/data/config.rb +94 -0
- data/data/default_instance_config.rb +244 -0
- data/gemspec.rb +51 -0
- data/lib/tyrant_manager/cli.rb +145 -0
- data/lib/tyrant_manager/command.rb +118 -0
- data/lib/tyrant_manager/commands/create_instance.rb +27 -0
- data/lib/tyrant_manager/commands/list.rb +28 -0
- data/lib/tyrant_manager/commands/start.rb +32 -0
- data/lib/tyrant_manager/commands/stats.rb +25 -0
- data/lib/tyrant_manager/commands/status.rb +22 -0
- data/lib/tyrant_manager/commands/stop.rb +23 -0
- data/lib/tyrant_manager/log.rb +91 -0
- data/lib/tyrant_manager/paths.rb +77 -0
- data/lib/tyrant_manager/runner.rb +33 -0
- data/lib/tyrant_manager/tyrant_instance.rb +340 -0
- data/lib/tyrant_manager/version.rb +27 -0
- data/lib/tyrant_manager.rb +237 -0
- data/lib/tyrantmanager.rb +2 -0
- data/spec/command_spec.rb +37 -0
- data/spec/paths_spec.rb +57 -0
- data/spec/spec_helper.rb +58 -0
- data/spec/tyrant_instance_spec.rb +83 -0
- data/spec/tyrant_manager_spec.rb +69 -0
- data/spec/version_spec.rb +16 -0
- data/tasks/announce.rake +43 -0
- data/tasks/config.rb +99 -0
- data/tasks/distribution.rake +38 -0
- data/tasks/documentation.rake +32 -0
- data/tasks/rspec.rake +29 -0
- data/tasks/rubyforge.rake +51 -0
- data/tasks/utils.rb +80 -0
- metadata +144 -0
data/gemspec.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'tyrant_manager/version'
|
3
|
+
require 'tasks/config'
|
4
|
+
|
5
|
+
TyrantManager::GEM_SPEC = Gem::Specification.new do |spec|
|
6
|
+
proj = Configuration.for('project')
|
7
|
+
spec.name = proj.name
|
8
|
+
spec.version = TyrantManager::VERSION
|
9
|
+
|
10
|
+
spec.author = proj.author
|
11
|
+
spec.email = proj.email
|
12
|
+
spec.homepage = proj.homepage
|
13
|
+
spec.summary = proj.summary
|
14
|
+
spec.description = proj.description
|
15
|
+
spec.platform = Gem::Platform::RUBY
|
16
|
+
|
17
|
+
|
18
|
+
pkg = Configuration.for('packaging')
|
19
|
+
spec.files = pkg.files.all
|
20
|
+
spec.executables = pkg.files.bin.collect { |b| File.basename(b) }
|
21
|
+
|
22
|
+
# add dependencies here
|
23
|
+
# spec.add_dependency("rake", ">= 0.8.1")
|
24
|
+
spec.add_dependency( "loquacious", "~> 1.3.0")
|
25
|
+
spec.add_dependency( "rufus-tokyo", "~> 1.0.0")
|
26
|
+
|
27
|
+
spec.add_development_dependency("configuration", ">= 0.0.5")
|
28
|
+
spec.add_development_dependency( "rake", "~> 0.8.3")
|
29
|
+
|
30
|
+
if ext_conf = Configuration.for_if_exist?("extension") then
|
31
|
+
spec.extensions << ext_conf.configs
|
32
|
+
spec.extensions.flatten!
|
33
|
+
end
|
34
|
+
|
35
|
+
if rdoc = Configuration.for_if_exist?('rdoc') then
|
36
|
+
spec.has_rdoc = true
|
37
|
+
spec.extra_rdoc_files = pkg.files.rdoc
|
38
|
+
spec.rdoc_options = rdoc.options + [ "--main" , rdoc.main_page ]
|
39
|
+
else
|
40
|
+
spec.has_rdoc = false
|
41
|
+
end
|
42
|
+
|
43
|
+
if test = Configuration.for_if_exist?('testing') then
|
44
|
+
spec.test_files = test.files
|
45
|
+
end
|
46
|
+
|
47
|
+
if rf = Configuration.for_if_exist?('rubyforge') then
|
48
|
+
spec.rubyforge_project = rf.project
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
@@ -0,0 +1,145 @@
|
|
1
|
+
require 'main'
|
2
|
+
require 'tyrant_manager'
|
3
|
+
|
4
|
+
class TyrantManager
|
5
|
+
Cli = Main.create {
|
6
|
+
author "Copyright 2009 (c) Jeremy Hinegardner"
|
7
|
+
version ::TyrantManager::VERSION
|
8
|
+
|
9
|
+
description <<-txt
|
10
|
+
The command line tool for managing tyrant instances.
|
11
|
+
|
12
|
+
Run 'tyrantmanager help modename' for more information
|
13
|
+
txt
|
14
|
+
|
15
|
+
run { help! }
|
16
|
+
|
17
|
+
mode( :setup ) {
|
18
|
+
description "Setup an tyrant manager location"
|
19
|
+
argument( :home ) {
|
20
|
+
description "The home directory of the tyrant manager"
|
21
|
+
required
|
22
|
+
default TyrantManager.default_or_home_directory
|
23
|
+
}
|
24
|
+
|
25
|
+
run {
|
26
|
+
TyrantManager::Log.init
|
27
|
+
TyrantManager.setup( params['home'].value )
|
28
|
+
}
|
29
|
+
}
|
30
|
+
|
31
|
+
mode( 'create-instance' ) {
|
32
|
+
description <<-txt
|
33
|
+
Create a new tyrant instance in the specified directory
|
34
|
+
txt
|
35
|
+
|
36
|
+
argument( 'instance-home' ) do
|
37
|
+
description <<-txt
|
38
|
+
The home directory of the tyrant instance. If this is a full path it
|
39
|
+
will be used. If it is a relative path, it will be relative to the
|
40
|
+
manager's 'instances' configuration parameter
|
41
|
+
txt
|
42
|
+
end
|
43
|
+
|
44
|
+
mixin :option_home
|
45
|
+
mixin :option_log_level
|
46
|
+
|
47
|
+
run { Cli.run_command_with_params( "create-instance", params ) }
|
48
|
+
}
|
49
|
+
|
50
|
+
mode( 'start' ) {
|
51
|
+
description "Start all the tyrants listed"
|
52
|
+
mixin :option_home
|
53
|
+
mixin :option_log_level
|
54
|
+
mixin :argument_instances
|
55
|
+
option( 'dry-run' ) {
|
56
|
+
description "Do not start, just show the commands"
|
57
|
+
default false
|
58
|
+
}
|
59
|
+
|
60
|
+
run { Cli.run_command_with_params( 'start', params ) }
|
61
|
+
}
|
62
|
+
|
63
|
+
|
64
|
+
mode( 'stop' ) {
|
65
|
+
description "Stop all the tyrants listed"
|
66
|
+
mixin :option_home
|
67
|
+
mixin :option_log_level
|
68
|
+
mixin :argument_instances
|
69
|
+
|
70
|
+
run { Cli.run_command_with_params( 'stop', params ) }
|
71
|
+
}
|
72
|
+
|
73
|
+
|
74
|
+
mode('status') {
|
75
|
+
description "Check the running status of all the tyrants listed"
|
76
|
+
mixin :option_home
|
77
|
+
mixin :option_log_level
|
78
|
+
|
79
|
+
mixin :argument_instances
|
80
|
+
|
81
|
+
run { Cli.run_command_with_params( 'status', params ) }
|
82
|
+
}
|
83
|
+
|
84
|
+
mode( 'stats' ) {
|
85
|
+
description "Dump the database statistics of each of the tyrants listed"
|
86
|
+
mixin :option_home
|
87
|
+
mixin :option_log_level
|
88
|
+
|
89
|
+
mixin :argument_instances
|
90
|
+
|
91
|
+
run { Cli.run_command_with_params( 'stats', params ) }
|
92
|
+
}
|
93
|
+
|
94
|
+
|
95
|
+
mode('list') {
|
96
|
+
description "list the instances and their home directories"
|
97
|
+
mixin :option_home
|
98
|
+
mixin :option_log_level
|
99
|
+
mixin :argument_instances
|
100
|
+
run { Cli.run_command_with_params( 'list', params ) }
|
101
|
+
}
|
102
|
+
|
103
|
+
#--- Mixins ---
|
104
|
+
mixin :option_home do
|
105
|
+
option( :home ) do
|
106
|
+
description "The home directory of the tyrant manager"
|
107
|
+
argument :required
|
108
|
+
validate { |v| ::File.directory?( v ) }
|
109
|
+
default TyrantManager.default_or_home_directory
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
mixin :option_log_level do
|
114
|
+
option('log-level') do
|
115
|
+
description "The verbosity of logging, one of [ #{::Logging::LNAMES.map {|l| l.downcase}.join(", ")} ]"
|
116
|
+
argument :required
|
117
|
+
validate { |l| %w[ debug info warn error fatal off ].include?( l.downcase ) }
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
mixin :argument_instances do
|
122
|
+
argument('instances') do
|
123
|
+
description "A comman separated list of instance names the tyrant manager knows about"
|
124
|
+
argument :required
|
125
|
+
cast :list
|
126
|
+
default 'all'
|
127
|
+
end
|
128
|
+
end
|
129
|
+
}
|
130
|
+
|
131
|
+
#
|
132
|
+
# Convert the Parameters::List that exists as the parameters from Main
|
133
|
+
#
|
134
|
+
def Cli.params_to_hash( params )
|
135
|
+
(hash = params.to_hash ).keys.each { |key| hash[key] = hash[key].value }
|
136
|
+
return hash
|
137
|
+
end
|
138
|
+
|
139
|
+
def Cli.run_command_with_params( command, params )
|
140
|
+
phash = Cli.params_to_hash( params )
|
141
|
+
TyrantManager::Log.init( phash )
|
142
|
+
tm = TyrantManager.new( phash.delete('home') )
|
143
|
+
tm.runner_for( phash ).run( command )
|
144
|
+
end
|
145
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
require 'tyrant_manager'
|
2
|
+
class TyrantManager
|
3
|
+
#
|
4
|
+
# The Command is the base class for any class to be used as a command
|
5
|
+
#
|
6
|
+
# All commands run within the context of an existing TyrantManager location.
|
7
|
+
# Before the command starts the current working directory will be inside the
|
8
|
+
# tyrant manager's home directory.
|
9
|
+
#
|
10
|
+
# A command has a lifecyle of:
|
11
|
+
#
|
12
|
+
# * instantiation with a TyrantManager instance and an options hash
|
13
|
+
# * one call to before
|
14
|
+
# * one call to run
|
15
|
+
# * one call to after
|
16
|
+
#
|
17
|
+
# In case of an exception raised during the lifecycle, the +error+ method will
|
18
|
+
# be called. The +after+ method is called no matter what at the end of the
|
19
|
+
# lifecycle, even if an error has occurred.
|
20
|
+
#
|
21
|
+
class Command
|
22
|
+
def self.command_name
|
23
|
+
name.split("::").last.downcase
|
24
|
+
end
|
25
|
+
|
26
|
+
attr_reader :options
|
27
|
+
attr_reader :manager
|
28
|
+
|
29
|
+
#
|
30
|
+
# Instantiated and given the tyrant manager instance it is to operate
|
31
|
+
# through and a hash of options
|
32
|
+
#
|
33
|
+
def initialize( manager, opts = {} )
|
34
|
+
@manager = manager
|
35
|
+
@options = opts
|
36
|
+
end
|
37
|
+
|
38
|
+
def command_name
|
39
|
+
self.class.command_name
|
40
|
+
end
|
41
|
+
|
42
|
+
def logger
|
43
|
+
Logging::Logger[self]
|
44
|
+
end
|
45
|
+
|
46
|
+
#------------------------------------------------------------------
|
47
|
+
# lifecycle calls
|
48
|
+
#------------------------------------------------------------------
|
49
|
+
|
50
|
+
#
|
51
|
+
# call-seq:
|
52
|
+
# cmd.before
|
53
|
+
#
|
54
|
+
# called to allow the command to setup anything post initialization it
|
55
|
+
# needs to be able to +run+.
|
56
|
+
#
|
57
|
+
def before() nil ; end
|
58
|
+
|
59
|
+
#
|
60
|
+
# call-seq:
|
61
|
+
# cmd.run
|
62
|
+
#
|
63
|
+
# Yeah, this is where the work should be done.
|
64
|
+
#
|
65
|
+
def run()
|
66
|
+
raise NotImplementedError, "The #run method must be implemented"
|
67
|
+
end
|
68
|
+
|
69
|
+
#
|
70
|
+
# call-seq:
|
71
|
+
# cmd.after
|
72
|
+
#
|
73
|
+
# called no matter what, after the execution of run() or error() if there was
|
74
|
+
# an exception. It is here to allow the cmd to do cleanup work.
|
75
|
+
#
|
76
|
+
def after() nil ; end
|
77
|
+
|
78
|
+
#
|
79
|
+
# call-seq:
|
80
|
+
# cmd.error( exception )
|
81
|
+
#
|
82
|
+
# called if there is an exception during the before() or after() calls. It
|
83
|
+
# is passed in the exception that was raised.
|
84
|
+
#
|
85
|
+
def error(exception) nil ; end
|
86
|
+
|
87
|
+
#------------------------------------------------------------------
|
88
|
+
# registration
|
89
|
+
#------------------------------------------------------------------
|
90
|
+
class CommandNotFoundError < ::TyrantManager::Error ; end
|
91
|
+
class << Command
|
92
|
+
def inherited( klass )
|
93
|
+
return unless klass.instance_of? Class
|
94
|
+
self.list << klass
|
95
|
+
end
|
96
|
+
|
97
|
+
def list
|
98
|
+
unless defined? @list
|
99
|
+
@list = Set.new
|
100
|
+
end
|
101
|
+
return @list
|
102
|
+
end
|
103
|
+
|
104
|
+
def find( command )
|
105
|
+
klass = list.find { |klass| klass.command_name == command }
|
106
|
+
return klass if klass
|
107
|
+
names = list.collect { |c| c.command_name }
|
108
|
+
raise CommandNotFoundError, "No command for '#{command}' was found. Known commands : #{names.join(",")}"
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
require 'tyrant_manager/commands/create_instance'
|
114
|
+
require 'tyrant_manager/commands/start'
|
115
|
+
require 'tyrant_manager/commands/stop'
|
116
|
+
require 'tyrant_manager/commands/status'
|
117
|
+
require 'tyrant_manager/commands/stats'
|
118
|
+
require 'tyrant_manager/commands/list'
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require 'tyrant_manager/command'
|
3
|
+
class TyrantManager
|
4
|
+
module Commands
|
5
|
+
#
|
6
|
+
# Create a new Tyrant instance
|
7
|
+
#
|
8
|
+
class CreateInstance < Command
|
9
|
+
def self.command_name
|
10
|
+
'create-instance'
|
11
|
+
end
|
12
|
+
|
13
|
+
def run
|
14
|
+
path = Pathname.new( options['instance-home'] )
|
15
|
+
unless path.absolute? then
|
16
|
+
path = Pathname.new( manager.instances_path ) + path
|
17
|
+
end
|
18
|
+
|
19
|
+
unless path.exist? then
|
20
|
+
logger.info "Creating instance directory #{path}"
|
21
|
+
TyrantManager::TyrantInstance.setup( path.to_s )
|
22
|
+
end
|
23
|
+
tt = TyrantManager::TyrantInstance.new( path.to_s )
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require 'tyrant_manager/command'
|
3
|
+
class TyrantManager
|
4
|
+
module Commands
|
5
|
+
#
|
6
|
+
# List all known instances that the manager knows about
|
7
|
+
#
|
8
|
+
class List < Command
|
9
|
+
def run
|
10
|
+
manager.each_instance do |instance|
|
11
|
+
ilist = options['instances']
|
12
|
+
if ilist == %w[ all ] or ilist.include?( instance.name ) then
|
13
|
+
parts = []
|
14
|
+
parts << ("%20s" % instance.name)
|
15
|
+
parts << "port #{instance.configuration.port}"
|
16
|
+
parts << instance.home_dir
|
17
|
+
|
18
|
+
if instance.configuration.master_server then
|
19
|
+
parts << "server id #{"%2d" % instance.configuration.server_id}"
|
20
|
+
parts << "replicating from #{instance.configuration.master_server}:#{instance.configuration.master_port}"
|
21
|
+
end
|
22
|
+
puts parts.join(" : ")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'tyrant_manager/command'
|
2
|
+
class TyrantManager
|
3
|
+
module Commands
|
4
|
+
#
|
5
|
+
# Start one ore more instances
|
6
|
+
#
|
7
|
+
class Start < Command
|
8
|
+
def run
|
9
|
+
manager.each_instance do |instance|
|
10
|
+
ilist = options['instances']
|
11
|
+
if ilist == %w[ all ] or ilist.include?( instance.name ) then
|
12
|
+
parts = [ "Starting #{instance.name}" ]
|
13
|
+
parts << instance.start_command
|
14
|
+
|
15
|
+
if options['dry-run'] then
|
16
|
+
parts << "(dry-run)"
|
17
|
+
logger.info parts.join(" : ")
|
18
|
+
|
19
|
+
elsif not instance.running? then
|
20
|
+
logger.info parts.join(" : ")
|
21
|
+
Dir.chdir( instance.home_dir ) do
|
22
|
+
instance.start
|
23
|
+
end
|
24
|
+
else
|
25
|
+
logger.info "Instance #{instance.name} already running"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'tyrant_manager/command'
|
2
|
+
class TyrantManager
|
3
|
+
module Commands
|
4
|
+
#
|
5
|
+
# List the stats about one or more instances
|
6
|
+
#
|
7
|
+
class Stats < Command
|
8
|
+
def run
|
9
|
+
manager.each_instance do |instance|
|
10
|
+
ilist = options['instances']
|
11
|
+
if ilist == %w[ all ] or ilist.include?( instance.name ) then
|
12
|
+
puts "Instance #{instance.name} at #{instance.home_dir}"
|
13
|
+
conn = instance.connection
|
14
|
+
stats = conn.stat
|
15
|
+
stats.keys.sort.each do |k|
|
16
|
+
lhs = k.ljust(10, ".")
|
17
|
+
puts " #{lhs} #{stats[k]}"
|
18
|
+
end
|
19
|
+
puts
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'tyrant_manager/command'
|
2
|
+
class TyrantManager
|
3
|
+
module Commands
|
4
|
+
#
|
5
|
+
# Report the status of one ore more tyrant intances
|
6
|
+
#
|
7
|
+
class Status < Command
|
8
|
+
def run
|
9
|
+
manager.each_instance do |instance|
|
10
|
+
ilist = options['instances']
|
11
|
+
if ilist == %w[ all ] or ilist.include?( instance.name ) then
|
12
|
+
if instance.running? then
|
13
|
+
logger.info "#{instance.name} is running as pid #{instance.pid}"
|
14
|
+
else
|
15
|
+
logger.info "#{instance.name} is not running, or its pid file is gone"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'tyrant_manager/command'
|
2
|
+
class TyrantManager
|
3
|
+
module Commands
|
4
|
+
#
|
5
|
+
# Stop one or more tyrant instances
|
6
|
+
#
|
7
|
+
class Stop < Command
|
8
|
+
def run
|
9
|
+
manager.each_instance do |instance|
|
10
|
+
ilist = options['instances']
|
11
|
+
if ilist == %w[ all ] or ilist.include?( instance.name ) then
|
12
|
+
if File.exist?( instance.pid_file ) then
|
13
|
+
logger.info "Stopping #{instance.name} : pid #{instance.pid}"
|
14
|
+
instance.stop
|
15
|
+
else
|
16
|
+
logger.info "Stopping #{instance.name} : no pid file, nothing to do"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'logging'
|
2
|
+
require 'tyrant_manager'
|
3
|
+
|
4
|
+
class TyrantManager
|
5
|
+
::Logging::Logger[self].level = :info
|
6
|
+
|
7
|
+
def self.logger
|
8
|
+
::Logging::Logger[self]
|
9
|
+
end
|
10
|
+
|
11
|
+
module Log
|
12
|
+
def self.init( options = {} )
|
13
|
+
appender = Logging.appenders.stderr
|
14
|
+
appender.layout = self.console_layout
|
15
|
+
if options['log-file'] then
|
16
|
+
appender = ::Logging::Appenders::File.new(
|
17
|
+
'tyrant_manager',
|
18
|
+
:filename => options['log-file'],
|
19
|
+
:layout => self.layout
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
TyrantManager.logger.add_appenders( appender )
|
24
|
+
self.level = options['log-level'] || :info
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.logger
|
28
|
+
TyrantManager.logger
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.default_level
|
32
|
+
:info
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.console
|
36
|
+
Logging.appenders.stderr.level
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.console=( level )
|
40
|
+
Logging.appenders.stderr.level = level
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.level
|
44
|
+
::Logging::Logger[TyrantManager].level
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.level=( l )
|
48
|
+
::Logging::Logger[TyrantManager].level = l
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.layout
|
52
|
+
@layout ||= Logging::Layouts::Pattern.new(
|
53
|
+
:pattern => "[%d] %5l %6p %c : %m\n",
|
54
|
+
:date_pattern => "%Y-%m-%d %H:%M:%S"
|
55
|
+
)
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.console_layout
|
59
|
+
@layout ||= Logging::Layouts::Pattern.new(
|
60
|
+
:pattern => "%d %5l : %m\n",
|
61
|
+
:date_pattern => "%H:%M:%S"
|
62
|
+
)
|
63
|
+
end
|
64
|
+
|
65
|
+
#
|
66
|
+
# Turn off the console logging
|
67
|
+
#
|
68
|
+
def self.silent!
|
69
|
+
logger.level = :off
|
70
|
+
end
|
71
|
+
|
72
|
+
#
|
73
|
+
# Resume logging
|
74
|
+
#
|
75
|
+
def self.resume
|
76
|
+
logger.level = self.default_level
|
77
|
+
end
|
78
|
+
|
79
|
+
#
|
80
|
+
# Turn off logging for the execution of a block
|
81
|
+
#
|
82
|
+
def self.silent( &block )
|
83
|
+
begin
|
84
|
+
silent!
|
85
|
+
block.call
|
86
|
+
ensure
|
87
|
+
resume
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'rbconfig'
|
2
|
+
class TyrantManager
|
3
|
+
module Paths
|
4
|
+
# The installation directory of the project is considered to be the parent directory
|
5
|
+
# of the 'lib' directory.
|
6
|
+
#
|
7
|
+
def install_dir
|
8
|
+
@install_dir ||= (
|
9
|
+
path_parts = ::File.expand_path(__FILE__).split(::File::SEPARATOR)
|
10
|
+
lib_index = path_parts.rindex("lib")
|
11
|
+
path_parts[0...lib_index].join(::File::SEPARATOR) + ::File::SEPARATOR
|
12
|
+
)
|
13
|
+
end
|
14
|
+
|
15
|
+
def install_path( sub, *args )
|
16
|
+
sub_path( install_dir, sub, *args )
|
17
|
+
end
|
18
|
+
|
19
|
+
def bin_path( *args )
|
20
|
+
install_path( 'bin', *args )
|
21
|
+
end
|
22
|
+
|
23
|
+
def lib_path( *args )
|
24
|
+
install_path( "lib", *args )
|
25
|
+
end
|
26
|
+
|
27
|
+
def data_path( *args )
|
28
|
+
install_path( "data", *args )
|
29
|
+
end
|
30
|
+
|
31
|
+
def spec_path( *args )
|
32
|
+
install_path( "spec", *args )
|
33
|
+
end
|
34
|
+
|
35
|
+
# The home dir is the home directory of the project while it is running
|
36
|
+
# by default, this the same as the install_dir. But if this value is set
|
37
|
+
# then it affects other paths
|
38
|
+
def home_dir
|
39
|
+
@home_dir ||= install_dir
|
40
|
+
end
|
41
|
+
|
42
|
+
def home_dir=( other )
|
43
|
+
@home_dir = File.expand_path( other )
|
44
|
+
end
|
45
|
+
|
46
|
+
def home_path( sub, *args )
|
47
|
+
sub_path( home_dir, sub, *args )
|
48
|
+
end
|
49
|
+
|
50
|
+
def instances_path( *args )
|
51
|
+
home_path( "instances", *args )
|
52
|
+
end
|
53
|
+
|
54
|
+
def log_path( *args )
|
55
|
+
home_path( "log", *args )
|
56
|
+
end
|
57
|
+
|
58
|
+
def tmp_path( *args )
|
59
|
+
home_path( "tmp", *args )
|
60
|
+
end
|
61
|
+
|
62
|
+
def sub_path( parent, sub, *args )
|
63
|
+
sp = ::File.join( parent, sub ) + File::SEPARATOR
|
64
|
+
sp = ::File.join( sp, *args ) if args
|
65
|
+
end
|
66
|
+
|
67
|
+
extend self
|
68
|
+
end
|
69
|
+
extend Paths
|
70
|
+
|
71
|
+
# set the default home_dir for the manager to be the lib/tyrant in the local
|
72
|
+
# state dir directory. Instances are below them.
|
73
|
+
self.home_dir = File.join( Config::CONFIG['localstatedir'], 'lib', 'tyrant' )
|
74
|
+
def self.default_instances_dir
|
75
|
+
self.home_path( "instances" )
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'tyrant_manager/command'
|
2
|
+
|
3
|
+
class TyrantManager
|
4
|
+
class Runner
|
5
|
+
|
6
|
+
attr_reader :options
|
7
|
+
attr_reader :manager
|
8
|
+
|
9
|
+
def initialize( manager, opts = {} )
|
10
|
+
@manager = manager
|
11
|
+
@options = opts
|
12
|
+
end
|
13
|
+
|
14
|
+
def logger
|
15
|
+
::Logging::Logger[self]
|
16
|
+
end
|
17
|
+
|
18
|
+
def run( command_name )
|
19
|
+
cmd = Command.find( command_name ).new( self.manager, self.options )
|
20
|
+
begin
|
21
|
+
cmd.before
|
22
|
+
cmd.run
|
23
|
+
rescue => e
|
24
|
+
logger.error "while running #{command_name} : #{e.message}"
|
25
|
+
e.backtrace.each do |l|
|
26
|
+
logger.warn l.strip
|
27
|
+
end
|
28
|
+
ensure
|
29
|
+
cmd.after
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|