Class: TyrantManager

Inherits:
Object
  • Object
show all
Extended by:
Paths
Includes:
Paths
Defined in:
lib/tyrant_manager/version.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/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/create_instance.rb,
lib/tyrant_manager/commands/replication_status.rb

Overview

– Copyright © 2009 Jeremy Hinegardner All rights reserved. See LICENSE and/or COPYING for details ++

Defined Under Namespace

Modules: Commands, Log, Paths, Version Classes: Command, Error, Runner, TyrantInstance

Constant Summary collapse

Cli =
Main.create {
  author "Copyright 2009 (c) Jeremy Hinegardner"
  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 { 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 { 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 { 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 { 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 { 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 { 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 { Cli.run_command_with_params( 'list', params ) }\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

Instance Method Summary collapse

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

Constructor Details

#initialize(directory = TyrantManager.default_directory) ⇒ TyrantManager

Initialize the manager, which is nothing more than creating the instance and setting the home directory.



144
145
146
147
148
149
150
151
# File 'lib/tyrant_manager.rb', line 144

def initialize( directory = TyrantManager.default_directory )
  self.home_dir = File.expand_path( directory ) 
  if File.exist?( self.config_file ) then
    configuration # force a load
  else
    raise Error, "#{home_dir} is not a valid archive. #{self.config_file} does not exist"
  end
end

Class Method Details

.basedirObject

The basename of the directory that holds the tyrant manager system



28
29
30
# File 'lib/tyrant_manager.rb', line 28

def basedir
  "tyrant"
end

.config_file_basenameObject

The basename of the default config file



21
22
23
# File 'lib/tyrant_manager.rb', line 21

def config_file_basename
  "config.rb"
end

.cwd_default_directoryObject

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



49
50
51
52
53
# File 'lib/tyrant_manager.rb', line 49

def cwd_default_directory
  default_dir = Dir.pwd
  return default_dir if is_tyrant_root?( default_dir )
  return nil
end

.default_directoryObject

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 )

Raises:



84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/tyrant_manager.rb', line 84

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_directory found" unless dd
  return dd
end

.default_instances_dirObject



74
75
76
# File 'lib/tyrant_manager/paths.rb', line 74

def self.default_instances_dir
  self.home_path( "instances" )
end

.default_or_home_directoryObject

Return the default directory if it exists, otherwise fallback to .home_dir



100
101
102
103
104
105
106
107
108
# File 'lib/tyrant_manager.rb', line 100

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_directoryObject

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



60
61
62
63
64
# File 'lib/tyrant_manager.rb', line 60

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

Returns:

  • (Boolean)


36
37
38
39
40
# File 'lib/tyrant_manager.rb', line 36

def is_tyrant_root?( dir )
  cfg = File.join( dir, config_file_basename )
  return true if File.directory?( dir ) and File.exist?( cfg )
  return false
end

.localstate_default_directoryObject

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



70
71
72
73
74
# File 'lib/tyrant_manager.rb', line 70

def localstate_default_directory
  default_dir = File.join( Config::CONFIG['localstatedir'], basedir )
  return default_dir if is_tyrant_root?( default_dir )
  return nil
end

.loggerObject



7
8
9
# File 'lib/tyrant_manager/log.rb', line 7

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.



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/tyrant_manager.rb', line 115

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_fileObject

The configuration file for the manager



160
161
162
# File 'lib/tyrant_manager.rb', line 160

def config_file
  @config_file ||= File.join( home_dir, TyrantManager.config_file_basename ) 
end

#configurationObject

load the configuration



167
168
169
170
171
172
173
# File 'lib/tyrant_manager.rb', line 167

def configuration
  unless @configuration 
    eval( IO.read( self.config_file ) )
    @configuration = Loquacious::Configuration.for("manager")
  end
  return @configuration
end

#each_instanceObject



214
215
216
217
218
# File 'lib/tyrant_manager.rb', line 214

def each_instance
  instances.keys.sort.each do |name|
    yield instances[name]
  end
end

#instancesObject

Return the list of instances that the manager knows about



185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
# File 'lib/tyrant_manager.rb', line 185

def instances
  unless @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

#loggerObject



153
154
155
# File 'lib/tyrant_manager.rb', line 153

def logger
  Logging::Logger[self]
end

#runner_for(options) ⇒ Object

Create a runner instance with the given options



178
179
180
# File 'lib/tyrant_manager.rb', line 178

def runner_for( options )
  Runner.new( self, options )
end