Class: TyrantManager
- Inherits:
-
Object
- Object
- TyrantManager
- Extended by:
- Paths
- Defined in:
- lib/tyrant_manager/util.rb,
lib/tyrant_manager.rb,
lib/tyrant_manager/cli.rb,
lib/tyrant_manager/log.rb,
lib/tyrant_manager/paths.rb,
lib/tyrant_manager/runner.rb,
lib/tyrant_manager/command.rb,
lib/tyrant_manager/version.rb,
lib/tyrant_manager/commands/list.rb,
lib/tyrant_manager/commands/stop.rb,
lib/tyrant_manager/commands/start.rb,
lib/tyrant_manager/commands/stats.rb,
lib/tyrant_manager/commands/status.rb,
lib/tyrant_manager/tyrant_instance.rb,
lib/tyrant_manager/commands/archive_ulogs.rb,
lib/tyrant_manager/commands/create_instance.rb,
lib/tyrant_manager/commands/replication_status.rb
Overview
– Copyright © 2009-2011 Jeremy Hinegardner All rights reserved. See LICENSE and/or COPYING for details ++
Defined Under Namespace
Modules: Commands, Log, Paths, Util, Version Classes: Command, Error, Runner, TyrantInstance
Constant Summary collapse
- MAGIC_LINE =
'Loquacious::Configuration.for( "manager" ) do'
- Cli =
Main.create { "Copyright (c) 2009-2011 Jeremy Hinegardner. All rights reserved" version ::TyrantManager::VERSION description <<-txt The command line tool for managing tyrant instances. Run 'tyrantmanager help modename' for more information txt run { help! } mode( :setup ) { description "Setup an tyrant manager location" argument( :home ) { description "The home directory of the tyrant manager" required default ::TyrantManager.default_or_home_directory } run { TyrantManager::Log.init TyrantManager.setup( params['home'].value ) } } mode( 'create-instance' ) { description <<-txt Create a new tyrant instance in the specified directory txt argument( 'instance-home' ) do description <<-txt The home directory of the tyrant instance. If this is a full path it will be used. If it is a relative path, it will be relative to the manager's 'instances' configuration parameter txt end mixin :option_home mixin :option_log_level run { ::TyrantManager::Cli.run_command_with_params( "create-instance", params ) } } mode( 'start' ) { description "Start all the tyrants listed" mixin :option_home mixin :option_log_level mixin :argument_instances option( 'dry-run' ) { description "Do not start, just show the commands" default false } run { ::TyrantManager::Cli.run_command_with_params( 'start', params ) } } mode( 'stop' ) { description "Stop all the tyrants listed" mixin :option_home mixin :option_log_level mixin :argument_instances run { ::TyrantManager::Cli.run_command_with_params( 'stop', params ) } } mode('replication-status') { description "Describe the replication status of those servers using replication" mixin :option_home mixin :option_log_level mixin :argument_instances run { ::TyrantManager::Cli.run_command_with_params( 'replication-status', params ) } } mode('process-status') { description "Check the running status of all the tyrants listed" mixin :option_home mixin :option_log_level mixin :argument_instances run { ::TyrantManager::Cli.run_command_with_params( 'process-status', params ) } } mode( 'stats' ) { description "Dump the database statistics of each of the tyrants listed" mixin :option_home mixin :option_log_level mixin :argument_instances run { ::TyrantManager::Cli.run_command_with_params( 'stats', params ) } } mode('list') { description "list the instances and their home directories" mixin :option_home mixin :option_log_level mixin :argument_instances run { ::TyrantManager::Cli.run_command_with_params( 'list', params ) } } mode( 'archive-ulogs' ) { description "Archive the ulog files that are no longer necessary for replication" mixin :option_home mixin :option_log_level mixin :argument_instances option( 'archive-method' ) { description "The method of archiving, compress, or delete. Choosing 'delete' will also delete previously 'compressed' ulog files." argument :required validate { |m| %w[ compress delete ].include?( m.downcase ) } default "compress" } option( 'dry-run' ) { description "Do not archive, just show the commands" default false } option( 'force' ) { description "Force a record through the master to the slave so the replication timestamps are updated." default false cast :boolean } option('force-key') { description "When used with --force, this is the key that is forced from the master to the slaves. The value iinserted at the key is the current timestamp in the form #{Time.now.strftime('%Y-%m-%d %H:%M:%S')}" argument :required default "__tyrant_manager.force_replication_at" cast :string } option( 'slaves' ) { description "Comma separated list of slave instances connection strings host:port,host:port,..." argument :required cast :list_of_string } run { ::TyrantManager::Cli.run_command_with_params( 'archive-ulogs', params ) } } #--- Mixins --- mixin :option_home do option( :home ) do description "The home directory of the tyrant manager" argument :required validate { |v| ::File.directory?( v ) } default ::TyrantManager.default_or_home_directory end end mixin :option_log_level do option('log-level') do description "The verbosity of logging, one of [ #{::Logging::LNAMES.map {|l| l.downcase}.join(", ")} ]" argument :required validate { |l| %w[ debug info warn error fatal off ].include?( l.downcase ) } end end mixin :argument_instances do argument('instances') do description "A comman separated list of instance names the tyrant manager knows about" argument :required cast :list default 'all' end end }
- VERSION =
Version.to_s
Class Method Summary collapse
-
.basedir ⇒ Object
The basename of the directory that holds the tyrant manager system.
-
.config_file_basename ⇒ Object
The basename of the default config file.
-
.cwd_default_directory ⇒ Object
Return the path of the tyrant dir if there is one relative to the current working directory.
-
.default_directory ⇒ Object
The default tyrant directory.
- .default_instances_dir ⇒ Object
-
.default_or_home_directory ⇒ Object
Return the default directory if it exists, otherwise fallback to .home_dir.
-
.env_default_directory ⇒ Object
Return the path of the tyrant dir as it pertains to the TYRANT_MANAGER_HOME environment variable.
-
.is_tyrant_root?(dir) ⇒ Boolean
is the given directory a tyrant root directory.
-
.localstate_default_directory ⇒ Object
Return the path of the tyrant dir as it pertains to the default global setting of ‘lcoalstatedir’ which is /opt/local/var, /var, or similar.
- .logger ⇒ Object
-
.setup(dir = default_directory) ⇒ Object
Setup the tyrant manager in the given directory.
Instance Method Summary collapse
-
#config_file ⇒ Object
The configuration file for the manager.
-
#configuration ⇒ Object
load the configuration.
-
#each_instance(limit = %w[ all ])) ⇒ Object
Yield each instance that exists in the limit list, if the limit exists.
-
#initialize(directory = TyrantManager.default_directory) ⇒ TyrantManager
constructor
Initialize the manager, which is nothing more than creating the instance and setting the home directory.
-
#instances ⇒ Object
Return the list of instances that the manager knows about.
- #logger ⇒ Object
-
#runner_for(options) ⇒ Object
Create a runner instance with the given options.
Methods included from Paths
bin_path, data_path, home_dir, home_dir=, home_path, install_dir, install_path, instances_path, lib_path, log_path, spec_path, sub_path, tmp_path
Methods included from Util
Constructor Details
#initialize(directory = TyrantManager.default_directory) ⇒ TyrantManager
Initialize the manager, which is nothing more than creating the instance and setting the home directory.
162 163 164 165 166 167 168 169 |
# File 'lib/tyrant_manager.rb', line 162 def initialize( directory = TyrantManager.default_directory ) self.home_dir = File.( directory ) if File.exist?( self.config_file ) then configuration # force a load else raise Error, "#{home_dir} is not a valid TyrantManager home. #{self.config_file} does not exist" end end |
Class Method Details
.basedir ⇒ Object
The basename of the directory that holds the tyrant manager system
30 31 32 |
# File 'lib/tyrant_manager.rb', line 30 def basedir "tyrant" end |
.config_file_basename ⇒ Object
The basename of the default config file
23 24 25 |
# File 'lib/tyrant_manager.rb', line 23 def config_file_basename "config.rb" end |
.cwd_default_directory ⇒ Object
Return the path of the tyrant dir if there is one relative to the current working directory. This means that there is a config_file_basename
in the current working directory.
returns Dir.pwd if this is the case, nil otherwise
65 66 67 68 69 |
# File 'lib/tyrant_manager.rb', line 65 def cwd_default_directory default_dir = Dir.pwd return default_dir if is_tyrant_root?( default_dir ) return nil end |
.default_directory ⇒ Object
The default tyrant directory. It is the first of these that matches:
-
current directory if there is a
config_file_basename
file in the current dirctory -
the value of the TYRANT_MANAGER_HOME environment variable
-
File.join( Config::CONFIG, basedir )
100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/tyrant_manager.rb', line 100 def default_directory defaults = [ self.cwd_default_directory, self.env_default_directory, self.localstate_default_directory ] dd = nil loop do dd = defaults.shift break if dd or defaults.empty? end raise Error, "No default Tyrant Manager home directory found" unless dd return dd end |
.default_instances_dir ⇒ Object
79 80 81 |
# File 'lib/tyrant_manager/paths.rb', line 79 def self.default_instances_dir self.home_path( "instances" ) end |
.default_or_home_directory ⇒ Object
Return the default directory if it exists, otherwise fallback to .home_dir
116 117 118 119 120 121 122 123 124 |
# File 'lib/tyrant_manager.rb', line 116 def default_or_home_directory hd = TyrantManager.home_dir begin hd = TyrantManager.default_directory rescue => e # yup, using home end return hd end |
.env_default_directory ⇒ Object
Return the path of the tyrant dir as it pertains to the TYRANT_MANAGER_HOME environment variable. If the directory is a tyrant root, then return that directory, otherwise return nil
76 77 78 79 80 |
# File 'lib/tyrant_manager.rb', line 76 def env_default_directory default_dir = ENV['TYRANT_MANAGER_HOME'] return default_dir if default_dir and is_tyrant_root?( default_dir ) return nil end |
.is_tyrant_root?(dir) ⇒ Boolean
is the given directory a tyrant root directory. A tyrant root has a config_file_basename
file in the top level. And that config_file_basename
file has the following line in it.
Loquacious::Configuration.for( "manager" ) do
Consider this a ‘magic line’ in the config file. If this line is in the config file then it is considered the top level tyrant root config file. This is done by line detection instead of evaluation since the configuration is not evaluated until later.
48 49 50 51 52 53 54 55 56 |
# File 'lib/tyrant_manager.rb', line 48 def is_tyrant_root?( dir ) cfg = File.join( dir, config_file_basename ) if File.directory?( dir ) and File.exist?( cfg ) then IO.readlines( cfg ).each do |line| return true if line.index( MAGIC_LINE ) end end return false end |
.localstate_default_directory ⇒ Object
Return the path of the tyrant dir as it pertains to the default global setting of ‘lcoalstatedir’ which is /opt/local/var, /var, or similar
86 87 88 89 90 |
# File 'lib/tyrant_manager.rb', line 86 def localstate_default_directory default_dir = File.join( Config::CONFIG['localstatedir'], basedir ) return default_dir if is_tyrant_root?( default_dir ) return nil end |
.logger ⇒ Object
12 13 14 |
# File 'lib/tyrant_manager/log.rb', line 12 def self.logger ::Logging::Logger[self] end |
.setup(dir = default_directory) ⇒ Object
Setup the tyrant manager in the given directory. This means creating it if it does not exist.
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
# File 'lib/tyrant_manager.rb', line 131 def setup( dir = default_directory ) unless File.directory?( dir ) logger.info "Creating directory #{dir}" FileUtils.mkdir_p( dir ) end cfg = File.join( dir, config_file_basename ) unless File.exist?( cfg ) template = TyrantManager::Paths.data_path( config_file_basename ) logger.info "Creating default config file #{cfg}" FileUtils.cp( template, dir ) end %w[ instances log tmp ].each do |subdir| subdir = File.join( dir, subdir ) unless File.directory?( subdir ) then logger.info "Creating directory #{subdir}" FileUtils.mkdir subdir end end return TyrantManager.new( dir ) end |
Instance Method Details
#config_file ⇒ Object
The configuration file for the manager
178 179 180 |
# File 'lib/tyrant_manager.rb', line 178 def config_file @config_file ||= File.join( home_dir, TyrantManager.config_file_basename ) end |
#configuration ⇒ Object
load the configuration
185 186 187 188 189 190 191 |
# File 'lib/tyrant_manager.rb', line 185 def configuration unless defined? @configuration eval( IO.read( self.config_file ) ) @configuration = Loquacious::Configuration.for("manager") end return @configuration end |
#each_instance(limit = %w[ all ])) ⇒ Object
Yield each instance that exists in the limit list, if the limit exists.
If the limit does not exist then yield each instance.
235 236 237 238 239 240 241 242 243 244 |
# File 'lib/tyrant_manager.rb', line 235 def each_instance( limit = %w[ all ]) limit = [ limit ].flatten every = (limit.first == "all") instances.keys.sort.each do |name| if every or limit.include?( name ) then yield instances[name] end end end |
#instances ⇒ Object
Return the list of instances that the manager knows about
203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 |
# File 'lib/tyrant_manager.rb', line 203 def instances unless defined? @instances then candidates = [ self.instances_path ] if configuration.instances then candidates = configuration.instances end @instances = {} while not candidates.empty? do candidate = candidates.pop cpath = append_to_home_if_not_absolute( candidate ) begin t = TyrantInstance.new( cpath ) t.manager = self @instances[t.name] = t rescue TyrantManager::Error => e if File.directory?( cpath ) then Dir.glob( "#{cpath}/*" ).each do |epath| if File.directory?( epath ) then candidates.push epath end end end end end #while end return @instances end |
#logger ⇒ Object
171 172 173 |
# File 'lib/tyrant_manager.rb', line 171 def logger Logging::Logger[self] end |