Module: RightScale::AgentConfig

Defined in:
lib/right_agent/agent_config.rb

Overview

Helper methods for accessing RightAgent files, directories, and processes. Values returned are driven by root_dir, cfg_dir, and pid_dir, which may be set but have defaults, and secondarily by the contents of the associated agent configuration file generated by the ‘rad’ tool.

The root_dir may be specified to be a list of root directories to be searched when looking for agent files. It defaults to the current working directory. A root directory is assumed to contain some or all of the following directories:

init    - initialization code
actors  - actor code
certs   - security certificates and keys
lib     - additional agent code
scripts - tools code

The init directory contains the following initialization code:

config.yml - static configuration settings for the agent
init.rb    - code that registers the agent's actors and performs any other
             agent specific initialization such as initializing its
             secure serializer and its command protocol server

The certs directory contains the x.509 public certificate and keys needed to sign and encrypt all outgoing messages as well as to check the signature and decrypt any incoming messages. If AMQP is being used as the RightNet protocol, this directory should contain at least:

<agent name>.key  - agent's' private key
<agent name>.cert - agent's' public certificate
router.cert       - router's' public certificate

The scripts directory at a minimum contains the following:

install.sh - script for installing standard and agent specific tools in /usr/bin

The cfg_dir is the path to the directory containing a directory for each agent configured on the local machine (e.g., core, core_2, core_3). Each agent directory in turn contains a config.yml file generated to contain that agent’s current configuration. The cfg_dir defaults to the platform specific cfg_dir.

The pid_dir is the path to the directory where agent process id files are stored. These files are typically named <agent identity>.pid. The pid_dir defaults to the current to the platform specific pid_dir.

Constant Summary collapse

PROTOCOL_VERSION =

Current agent protocol version

24
DEFAULT_THREAD_NAME =

Default thread name when no thread is specified for an executable bundle.

'default'
VALID_THREAD_NAME =

Regular expression to define what a valid thread name looks like: an alpha character followed by 0 or more alphanumerics or underscores. Only lower-case characters are allowed.

/^[a-z][a-z0-9_]*$/
DEFAULT_POLICY_NAME =

Default policy name when no policy is specified for an executable bundle.

nil
DEFAULT_POLICY_PERIOD =

Default period for policies

60 * 60 * 24
DEFAULT_SERVER_SECRET =

Default server secret in case it is not provided by core.

"1a7c8f89bb78fcf1b225324af0abc474d308a5e7f654080664231af3b268db1e"

Class Method Summary collapse

Class Method Details

.actors_dirsObject

Ordered list of directory path names for searching for actors:

- actors directory in each configured root directory
- other directories produced by other_actors_dirs method, e.g., in other associated gems
- actors directory in RightAgent gem

Return

actors_dirs(Array)

List of directory path names



202
203
204
205
206
207
# File 'lib/right_agent/agent_config.rb', line 202

def self.actors_dirs
  actors_dirs = all_dirs(:actors_dir)
  actors_dirs += other_actors_dirs if self.respond_to?(:other_actors_dirs)
  actors_dirs << File.normalize_path(File.join(File.dirname(__FILE__), 'actors'))
  actors_dirs
end

.agent_name(agent_id) ⇒ Object

Agent name associated with given agent identity

Parameters

agent_id(String)

Serialized agent identity

Return

(String|nil)

Agent name, or nil if agent not found



320
321
322
323
324
325
326
327
# File 'lib/right_agent/agent_config.rb', line 320

def self.agent_name(agent_id)
  cfg_agents.each do |a|
    if (options = agent_options(a)) && options[:identity] == agent_id
      return a
    end
  end
  nil
end

.agent_options(agent_name) ⇒ Object

Agent options from generated agent configuration file and agent process id file if they exist Reset root_dir and pid_dir to one found in agent configuration file

Parameters

agent_name(String)

Agent name

Return

options(Hash)

Agent options including

:identity(String)

Serialized agent identity

:log_path(String)

Path to directory for agent log file

:pid(Integer)

Agent process pid if available

:listen_port(Integer)

Agent command listen port if available

:cookie(String)

Agent command cookie if available



397
398
399
400
401
402
403
404
405
406
# File 'lib/right_agent/agent_config.rb', line 397

def self.agent_options(agent_name)
  if options = load_cfg(agent_name)
    @root_dirs = array(options[:root_dir])
    @pid_dir = options[:pid_dir]
    options[:log_path] = options[:log_dir] || Platform.filesystem.log_dir
    pid_file = PidFile.new(options[:identity])
    options.merge!(pid_file.read_pid) if pid_file.exists?
  end
  options || {}
end

.certs_dir(root_dir = nil) ⇒ Object

Path to directory containing certificates

Parameters

root_dir(String|nil)

Specific root dir to use (must be in root_dirs),

if nil use first dir in root_dirs

Return

(String|nil)

Path to certs directory, or nil if cannot determine root_dir



217
218
219
220
221
222
223
224
# File 'lib/right_agent/agent_config.rb', line 217

def self.certs_dir(root_dir = nil)
  if root_dir
    root_dir = nil unless @root_dirs && @root_dirs.include?(root_dir)
  else
    root_dir = @root_dirs.first if @root_dirs
  end
  File.normalize_path(File.join(root_dir, "certs")) if root_dir
end

.certs_file(name) ⇒ Object

Path to security file containing X.509 data

Parameters

name(String)

Security file name

Return

file(String|nil)

File path name, or nil if file does not exist



233
234
235
# File 'lib/right_agent/agent_config.rb', line 233

def self.certs_file(name)
  first_file(:certs_dir, name)
end

.certs_files(pattern) ⇒ Object

All security files matching pattern

Parameters

pattern(String)

Pattern for security files of interest, e.g., ‘*.cert’ or

'*.{cert,key}'

Return

files(Array)

Path name of files found



245
246
247
248
249
250
251
252
253
254
255
256
257
# File 'lib/right_agent/agent_config.rb', line 245

def self.certs_files(pattern)
  files = []
  names = []
  all_dirs(:certs_dir).each do |d|
    certs = Dir.glob(File.join(d, pattern)).each do |f|
      unless names.include?(b = File.basename(f))
        files << f
        names << b
      end
    end
  end
  files
end

.cfg_agentsObject

Configured agents i.e. agents that have a configuration file

Return

(Array)

Name of configured agents



309
310
311
# File 'lib/right_agent/agent_config.rb', line 309

def self.cfg_agents
  cfg_files.map { |c| File.basename(File.dirname(c)) }
end

.cfg_dirObject

Path to directory containing a directory for each agent configured on the local machine

Return

(String)

Directory path name



279
280
281
# File 'lib/right_agent/agent_config.rb', line 279

def self.cfg_dir
  @cfg_dir ||= Platform.filesystem.right_agent_cfg_dir
end

.cfg_dir=(dir) ⇒ Object

Initialize path to directory containing generated agent configuration files

Parameters

dir(String)

Directory path

Return

(String)

Directory path



154
155
156
# File 'lib/right_agent/agent_config.rb', line 154

def self.cfg_dir=(dir)
  @cfg_dir = dir
end

.cfg_file(agent_name, exists = false) ⇒ Object

Path to generated agent configuration file

Parameters

agent_name(String)

Agent name

exists(Boolean)

Whether to return nil if does not exist

Return

(String)

Configuration file path name, or nil if file does not exist



291
292
293
294
295
# File 'lib/right_agent/agent_config.rb', line 291

def self.cfg_file(agent_name, exists = false)
  file = File.normalize_path(File.join(cfg_dir, agent_name, "config.yml"))
  file = nil unless !exists || File.exist?(file)
  file
end

.cfg_filesObject

Configuration file path names for all agents configured locally

Return

(Array)

Agent configuration file path names



301
302
303
# File 'lib/right_agent/agent_config.rb', line 301

def self.cfg_files
  Dir.glob(File.join(cfg_dir, "**", "*.yml"))
end

.default_audit_periodObject

Default audit period when a runlist policy does not specify a period.

Return

(String)

default policy name…



121
122
123
# File 'lib/right_agent/agent_config.rb', line 121

def self.default_audit_period
  DEFAULT_POLICY_PERIOD
end

.default_policy_nameObject

Default policy name when no policy is specified for an executable bundle.

Return

(String)

default policy name…



110
111
112
# File 'lib/right_agent/agent_config.rb', line 110

def self.default_policy_name
  DEFAULT_POLICY_NAME
end

.default_server_secretObject

Default server secret in case it is not provided by core.

Return

(String)

default server secret…



132
133
134
# File 'lib/right_agent/agent_config.rb', line 132

def self.default_server_secret
  DEFAULT_SERVER_SECRET
end

.default_thread_nameObject

Default thread name when no thread is specified for an executable bundle.

Return

(String)

default thread name…



84
85
86
# File 'lib/right_agent/agent_config.rb', line 84

def self.default_thread_name
  DEFAULT_THREAD_NAME
end

.init_cfg_fileObject

Path to agent config.yml file containing static configuration settings

Return

(String|nil)

File path name, or nil if file does not exist



191
192
193
# File 'lib/right_agent/agent_config.rb', line 191

def self.init_cfg_file
  first_file(:init_dir, "config.yml")
end

.init_fileObject

Path to agent init.rb file containing code that registers the agent’s actors and performs any other agent specific initialization such as initializing its secure serializer and its command protocol server

Return

(String|nil)

File path name, or nil if file does not exist



183
184
185
# File 'lib/right_agent/agent_config.rb', line 183

def self.init_file
  first_file(:init_dir, "init.rb")
end

.lib_dirObject

Path to first agent lib directory

Return

dir(String)

Directory path name



263
264
265
# File 'lib/right_agent/agent_config.rb', line 263

def self.lib_dir
  all_dirs(:lib_dir2).first
end

.load_cfg(agent_name) ⇒ Object

Get options from agent’s configuration file

Parameters

agent_name(String)

Agent name

Return

(Hash|nil)

Agent options with key names symbolized,

or nil if file not accessible or empty


337
338
339
340
341
# File 'lib/right_agent/agent_config.rb', line 337

def self.load_cfg(agent_name)
  if (file = cfg_file(agent_name, exists = true)) && File.readable?(file) && (cfg = YAML.load(IO.read(file)))
    SerializationHelper.symbolize_keys(cfg)
  end
end

.pid_dirObject

Path to directory containing agent process id files

Return

(String)

Directory path name



366
367
368
# File 'lib/right_agent/agent_config.rb', line 366

def self.pid_dir
  @pid_dir ||= Platform.filesystem.pid_dir
end

.pid_dir=(dir) ⇒ Object

Initialize path to directory containing agent process id files

Parameters

dir(String)

Directory path

Return

(String)

Directory path



165
166
167
# File 'lib/right_agent/agent_config.rb', line 165

def self.pid_dir=(dir)
  @pid_dir = dir
end

.pid_file(agent_name) ⇒ Object

Retrieve agent process id file

Parameters

agent_name(String)

Agent name

Return

(PidFile|nil)

Process id file, or nil if there is no configuration file for agent



377
378
379
380
381
# File 'lib/right_agent/agent_config.rb', line 377

def self.pid_file(agent_name)
  if options = load_cfg(agent_name)
    PidFile.new(options[:identity], options[:pid_dir])
  end
end

.protocol_versionObject

Current agent protocol version

Return

(Integer)

Protocol version



73
74
75
# File 'lib/right_agent/agent_config.rb', line 73

def self.protocol_version
  PROTOCOL_VERSION
end

.root_dirObject

Root directory path(s)

Return

(String|Array)

Individual directory path if only one, otherwise array of paths



173
174
175
# File 'lib/right_agent/agent_config.rb', line 173

def self.root_dir
  (d = root_dirs).size > 1 ? d : d.first
end

.root_dir=(dir) ⇒ Object

Initialize path to root directory of agent

Parameters

dir(String|Array)

Directory path or ordered list of directory paths to be searched

Return

(Array)

Ordered list of directory paths to be searched



143
144
145
# File 'lib/right_agent/agent_config.rb', line 143

def self.root_dir=(dir)
  @root_dirs = array(dir)
end

.running_agents(pattern = //) ⇒ Object

Agents that are currently running

Parameters

(Regexp)

Pattern that agent name must match to be included

Return

(Array)

Name of running agents



415
416
417
418
419
420
421
422
# File 'lib/right_agent/agent_config.rb', line 415

def self.running_agents(pattern = //)
  AgentConfig.cfg_agents.select do |agent_name|
    agent_name =~ pattern &&
    (pid_file = AgentConfig.pid_file(agent_name)) &&
    (pid = pid_file.read_pid[:pid]) &&
    (Process.getpgid(pid) rescue -1) != -1
  end.sort
end

.scripts_dirObject

Path to first agent scripts directory

Return

dir(String)

Directory path name



271
272
273
# File 'lib/right_agent/agent_config.rb', line 271

def self.scripts_dir
  all_dirs(:scripts_dir2).first
end

.store_cfg(agent_name, cfg) ⇒ Object

Write agent’s configuration to file

Parameters

agent_name(String)

Agent name

cfg(Hash)

Configuration options

Return

file(String)

Configuration file path name



351
352
353
354
355
356
357
358
359
360
# File 'lib/right_agent/agent_config.rb', line 351

def self.store_cfg(agent_name, cfg)
  file = cfg_file(agent_name)
  FileUtils.mkdir_p(File.dirname(file))
  File.delete(file) if File.exists?(file)
  File.open(file, 'w') do |fd|
    fd.puts "# Created at #{Time.now}"
    fd.write(YAML.dump(cfg))
  end
  file
end

.valid_thread_nameObject

Regular expression to define what a valid thread name looks like: an alpha character followed by 0 or more alphanumerics or underscores. Only lower-case characters are allowed.

Return

(String)

default thread name…



99
100
101
# File 'lib/right_agent/agent_config.rb', line 99

def self.valid_thread_name
  VALID_THREAD_NAME
end