tyrantmanager 1.0.9
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/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
|