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 " The command line tool for managing tyrant instances.\n\n Run 'tyrantmanager help modename' for more information\n txt\n\n run { help! }\n\n mode( :setup ) {\n description \"Setup an tyrant manager location\"\n argument( :home ) {\n description \"The home directory of the tyrant manager\"\n required\n default ::TyrantManager.default_or_home_directory\n }\n\n run { \n TyrantManager::Log.init \n TyrantManager.setup( params['home'].value ) \n }\n }\n\n mode( 'create-instance' ) {\n description <<-txt\n Create a new tyrant instance in the specified directory\n txt\n\n argument( 'instance-home' ) do\n description <<-txt\n The home directory of the tyrant instance. If this is a full path it \n will be used. If it is a relative path, it will be relative to the \n manager's 'instances' configuration parameter\n txt\n end\n\n mixin :option_home\n mixin :option_log_level\n\n run { ::TyrantManager::Cli.run_command_with_params( \"create-instance\", params ) }\n }\n\n mode( 'start' ) {\n description \"Start all the tyrants listed\"\n mixin :option_home\n mixin :option_log_level\n mixin :argument_instances\n option( 'dry-run' ) {\n description \"Do not start, just show the commands\"\n default false\n }\n\n run { ::TyrantManager::Cli.run_command_with_params( 'start', params ) }\n }\n\n\n mode( 'stop' ) {\n description \"Stop all the tyrants listed\"\n mixin :option_home\n mixin :option_log_level\n mixin :argument_instances\n\n run { ::TyrantManager::Cli.run_command_with_params( 'stop', params ) }\n }\n\n mode('replication-status') {\n description \"Describe the replication status of those servers using replication\"\n mixin :option_home\n mixin :option_log_level\n mixin :argument_instances\n run { ::TyrantManager::Cli.run_command_with_params( 'replication-status', params ) }\n }\n\n mode('process-status') {\n description \"Check the running status of all the tyrants listed\"\n mixin :option_home\n mixin :option_log_level\n\n mixin :argument_instances\n\n run { ::TyrantManager::Cli.run_command_with_params( 'process-status', params ) }\n }\n\n mode( 'stats' ) {\n description \"Dump the database statistics of each of the tyrants listed\"\n mixin :option_home\n mixin :option_log_level\n\n mixin :argument_instances\n\n run { ::TyrantManager::Cli.run_command_with_params( 'stats', params ) }\n }\n\n\n mode('list') {\n description \"list the instances and their home directories\"\n mixin :option_home\n mixin :option_log_level\n mixin :argument_instances\n run { ::TyrantManager::Cli.run_command_with_params( 'list', params ) }\n }\n\n mode( 'archive-ulogs' ) {\n description \"Archive the ulog files that are no longer necessary for replication\"\n mixin :option_home\n mixin :option_log_level\n mixin :argument_instances\n\n option( 'archive-method' ) {\n description \"The method of archiving, compress, or delete. Choosing 'delete' will also delete previously 'compressed' ulog files.\"\n argument :required\n validate { |m| %w[ compress delete ].include?( m.downcase ) }\n default \"compress\"\n }\n\n option( 'dry-run' ) {\n description \"Do not archive, just show the commands\"\n default false\n }\n\n option( 'force' ) {\n description \"Force a record through the master to the slave so the replication timestamps are updated.\"\n default false\n cast :boolean\n }\n\n option('force-key') {\n description \"When used with --force, this is the key that is forced from the master to the slaves.\n The value iinserted at the key is the current timestamp in the form \n \#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}\"\n argument :required\n default \"__tyrant_manager.force_replication_at\"\n cast :string\n }\n\n\n option( 'slaves' ) {\n description \"Comma separated list of slave instances connection strings host:port,host:port,...\"\n argument :required\n cast :list_of_string\n }\n\n run { ::TyrantManager::Cli.run_command_with_params( 'archive-ulogs', params ) }\n\n }\n\n\n #--- Mixins ---\n mixin :option_home do\n option( :home ) do\n description \"The home directory of the tyrant manager\"\n argument :required\n validate { |v| ::File.directory?( v ) }\n default ::TyrantManager.default_or_home_directory\n end\n end\n\n mixin :option_log_level do\n option('log-level') do\n description \"The verbosity of logging, one of [ \#{::Logging::LNAMES.map {|l| l.downcase}.join(\", \")} ]\"\n argument :required\n validate { |l| %w[ debug info warn error fatal off ].include?( l.downcase ) }\n end\n end\n\n mixin :argument_instances do\n argument('instances') do\n description \"A comman separated list of instance names the tyrant manager knows about\"\n argument :required\n cast :list\n default 'all'\n end\n end\n}\n"
- 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_basenamefile 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 |
#runner_for(options) ⇒ Object
Create a runner instance with the given options
196 197 198 |
# File 'lib/tyrant_manager.rb', line 196 def runner_for( ) Runner.new( self, ) end |