right_agent 2.0.7-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (176) hide show
  1. data/LICENSE +20 -0
  2. data/README.rdoc +82 -0
  3. data/Rakefile +113 -0
  4. data/lib/right_agent.rb +59 -0
  5. data/lib/right_agent/actor.rb +182 -0
  6. data/lib/right_agent/actor_registry.rb +76 -0
  7. data/lib/right_agent/actors/agent_manager.rb +232 -0
  8. data/lib/right_agent/agent.rb +1149 -0
  9. data/lib/right_agent/agent_config.rb +480 -0
  10. data/lib/right_agent/agent_identity.rb +210 -0
  11. data/lib/right_agent/agent_tag_manager.rb +237 -0
  12. data/lib/right_agent/audit_formatter.rb +107 -0
  13. data/lib/right_agent/clients.rb +31 -0
  14. data/lib/right_agent/clients/api_client.rb +383 -0
  15. data/lib/right_agent/clients/auth_client.rb +247 -0
  16. data/lib/right_agent/clients/balanced_http_client.rb +369 -0
  17. data/lib/right_agent/clients/base_retry_client.rb +495 -0
  18. data/lib/right_agent/clients/right_http_client.rb +279 -0
  19. data/lib/right_agent/clients/router_client.rb +493 -0
  20. data/lib/right_agent/command.rb +30 -0
  21. data/lib/right_agent/command/agent_manager_commands.rb +150 -0
  22. data/lib/right_agent/command/command_client.rb +136 -0
  23. data/lib/right_agent/command/command_constants.rb +33 -0
  24. data/lib/right_agent/command/command_io.rb +126 -0
  25. data/lib/right_agent/command/command_parser.rb +87 -0
  26. data/lib/right_agent/command/command_runner.rb +118 -0
  27. data/lib/right_agent/command/command_serializer.rb +63 -0
  28. data/lib/right_agent/connectivity_checker.rb +179 -0
  29. data/lib/right_agent/console.rb +65 -0
  30. data/lib/right_agent/core_payload_types.rb +44 -0
  31. data/lib/right_agent/core_payload_types/cookbook.rb +61 -0
  32. data/lib/right_agent/core_payload_types/cookbook_position.rb +46 -0
  33. data/lib/right_agent/core_payload_types/cookbook_repository.rb +116 -0
  34. data/lib/right_agent/core_payload_types/cookbook_sequence.rb +70 -0
  35. data/lib/right_agent/core_payload_types/dev_repositories.rb +100 -0
  36. data/lib/right_agent/core_payload_types/dev_repository.rb +76 -0
  37. data/lib/right_agent/core_payload_types/event_categories.rb +38 -0
  38. data/lib/right_agent/core_payload_types/executable_bundle.rb +130 -0
  39. data/lib/right_agent/core_payload_types/login_policy.rb +72 -0
  40. data/lib/right_agent/core_payload_types/login_user.rb +79 -0
  41. data/lib/right_agent/core_payload_types/planned_volume.rb +94 -0
  42. data/lib/right_agent/core_payload_types/recipe_instantiation.rb +73 -0
  43. data/lib/right_agent/core_payload_types/repositories_bundle.rb +50 -0
  44. data/lib/right_agent/core_payload_types/right_script_attachment.rb +95 -0
  45. data/lib/right_agent/core_payload_types/right_script_instantiation.rb +94 -0
  46. data/lib/right_agent/core_payload_types/runlist_policy.rb +44 -0
  47. data/lib/right_agent/core_payload_types/secure_document.rb +66 -0
  48. data/lib/right_agent/core_payload_types/secure_document_location.rb +63 -0
  49. data/lib/right_agent/core_payload_types/software_repository_instantiation.rb +61 -0
  50. data/lib/right_agent/daemonize.rb +35 -0
  51. data/lib/right_agent/dispatched_cache.rb +109 -0
  52. data/lib/right_agent/dispatcher.rb +272 -0
  53. data/lib/right_agent/enrollment_result.rb +221 -0
  54. data/lib/right_agent/exceptions.rb +87 -0
  55. data/lib/right_agent/history.rb +145 -0
  56. data/lib/right_agent/log.rb +460 -0
  57. data/lib/right_agent/minimal.rb +46 -0
  58. data/lib/right_agent/monkey_patches.rb +30 -0
  59. data/lib/right_agent/monkey_patches/ruby_patch.rb +55 -0
  60. data/lib/right_agent/monkey_patches/ruby_patch/array_patch.rb +29 -0
  61. data/lib/right_agent/monkey_patches/ruby_patch/darwin_patch.rb +24 -0
  62. data/lib/right_agent/monkey_patches/ruby_patch/linux_patch.rb +24 -0
  63. data/lib/right_agent/monkey_patches/ruby_patch/linux_patch/file_patch.rb +30 -0
  64. data/lib/right_agent/monkey_patches/ruby_patch/object_patch.rb +49 -0
  65. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch.rb +32 -0
  66. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/file_patch.rb +60 -0
  67. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/process_patch.rb +63 -0
  68. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/stdio_patch.rb +27 -0
  69. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/time_patch.rb +55 -0
  70. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/win32ole_patch.rb +34 -0
  71. data/lib/right_agent/multiplexer.rb +102 -0
  72. data/lib/right_agent/offline_handler.rb +270 -0
  73. data/lib/right_agent/operation_result.rb +300 -0
  74. data/lib/right_agent/packets.rb +673 -0
  75. data/lib/right_agent/payload_formatter.rb +104 -0
  76. data/lib/right_agent/pending_requests.rb +128 -0
  77. data/lib/right_agent/pid_file.rb +159 -0
  78. data/lib/right_agent/platform.rb +770 -0
  79. data/lib/right_agent/platform/unix/darwin/platform.rb +102 -0
  80. data/lib/right_agent/platform/unix/linux/platform.rb +305 -0
  81. data/lib/right_agent/platform/unix/platform.rb +226 -0
  82. data/lib/right_agent/platform/windows/mingw/platform.rb +447 -0
  83. data/lib/right_agent/platform/windows/mswin/platform.rb +236 -0
  84. data/lib/right_agent/platform/windows/platform.rb +1808 -0
  85. data/lib/right_agent/protocol_version_mixin.rb +69 -0
  86. data/lib/right_agent/retryable_request.rb +195 -0
  87. data/lib/right_agent/scripts/agent_controller.rb +543 -0
  88. data/lib/right_agent/scripts/agent_deployer.rb +400 -0
  89. data/lib/right_agent/scripts/common_parser.rb +160 -0
  90. data/lib/right_agent/scripts/log_level_manager.rb +192 -0
  91. data/lib/right_agent/scripts/stats_manager.rb +268 -0
  92. data/lib/right_agent/scripts/usage.rb +58 -0
  93. data/lib/right_agent/secure_identity.rb +92 -0
  94. data/lib/right_agent/security.rb +32 -0
  95. data/lib/right_agent/security/cached_certificate_store_proxy.rb +77 -0
  96. data/lib/right_agent/security/certificate.rb +102 -0
  97. data/lib/right_agent/security/certificate_cache.rb +89 -0
  98. data/lib/right_agent/security/distinguished_name.rb +56 -0
  99. data/lib/right_agent/security/encrypted_document.rb +83 -0
  100. data/lib/right_agent/security/rsa_key_pair.rb +76 -0
  101. data/lib/right_agent/security/signature.rb +86 -0
  102. data/lib/right_agent/security/static_certificate_store.rb +85 -0
  103. data/lib/right_agent/sender.rb +792 -0
  104. data/lib/right_agent/serialize.rb +29 -0
  105. data/lib/right_agent/serialize/message_pack.rb +107 -0
  106. data/lib/right_agent/serialize/secure_serializer.rb +151 -0
  107. data/lib/right_agent/serialize/secure_serializer_initializer.rb +47 -0
  108. data/lib/right_agent/serialize/serializable.rb +151 -0
  109. data/lib/right_agent/serialize/serializer.rb +159 -0
  110. data/lib/right_agent/subprocess.rb +38 -0
  111. data/lib/right_agent/tracer.rb +124 -0
  112. data/right_agent.gemspec +101 -0
  113. data/spec/actor_registry_spec.rb +80 -0
  114. data/spec/actor_spec.rb +162 -0
  115. data/spec/agent_config_spec.rb +235 -0
  116. data/spec/agent_identity_spec.rb +78 -0
  117. data/spec/agent_spec.rb +734 -0
  118. data/spec/agent_tag_manager_spec.rb +319 -0
  119. data/spec/clients/api_client_spec.rb +423 -0
  120. data/spec/clients/auth_client_spec.rb +272 -0
  121. data/spec/clients/balanced_http_client_spec.rb +576 -0
  122. data/spec/clients/base_retry_client_spec.rb +635 -0
  123. data/spec/clients/router_client_spec.rb +594 -0
  124. data/spec/clients/spec_helper.rb +111 -0
  125. data/spec/command/agent_manager_commands_spec.rb +51 -0
  126. data/spec/command/command_io_spec.rb +93 -0
  127. data/spec/command/command_parser_spec.rb +79 -0
  128. data/spec/command/command_runner_spec.rb +107 -0
  129. data/spec/command/command_serializer_spec.rb +51 -0
  130. data/spec/connectivity_checker_spec.rb +83 -0
  131. data/spec/core_payload_types/dev_repositories_spec.rb +64 -0
  132. data/spec/core_payload_types/dev_repository_spec.rb +33 -0
  133. data/spec/core_payload_types/executable_bundle_spec.rb +67 -0
  134. data/spec/core_payload_types/login_user_spec.rb +102 -0
  135. data/spec/core_payload_types/recipe_instantiation_spec.rb +81 -0
  136. data/spec/core_payload_types/right_script_attachment_spec.rb +65 -0
  137. data/spec/core_payload_types/right_script_instantiation_spec.rb +79 -0
  138. data/spec/core_payload_types/spec_helper.rb +23 -0
  139. data/spec/dispatched_cache_spec.rb +136 -0
  140. data/spec/dispatcher_spec.rb +324 -0
  141. data/spec/enrollment_result_spec.rb +53 -0
  142. data/spec/history_spec.rb +246 -0
  143. data/spec/log_spec.rb +192 -0
  144. data/spec/monkey_patches/eventmachine_spec.rb +62 -0
  145. data/spec/multiplexer_spec.rb +48 -0
  146. data/spec/offline_handler_spec.rb +340 -0
  147. data/spec/operation_result_spec.rb +208 -0
  148. data/spec/packets_spec.rb +461 -0
  149. data/spec/pending_requests_spec.rb +136 -0
  150. data/spec/platform/spec_helper.rb +216 -0
  151. data/spec/platform/unix/darwin/platform_spec.rb +181 -0
  152. data/spec/platform/unix/linux/platform_spec.rb +540 -0
  153. data/spec/platform/unix/spec_helper.rb +149 -0
  154. data/spec/platform/windows/mingw/platform_spec.rb +222 -0
  155. data/spec/platform/windows/mswin/platform_spec.rb +259 -0
  156. data/spec/platform/windows/spec_helper.rb +720 -0
  157. data/spec/retryable_request_spec.rb +306 -0
  158. data/spec/secure_identity_spec.rb +50 -0
  159. data/spec/security/cached_certificate_store_proxy_spec.rb +62 -0
  160. data/spec/security/certificate_cache_spec.rb +71 -0
  161. data/spec/security/certificate_spec.rb +49 -0
  162. data/spec/security/distinguished_name_spec.rb +46 -0
  163. data/spec/security/encrypted_document_spec.rb +55 -0
  164. data/spec/security/rsa_key_pair_spec.rb +55 -0
  165. data/spec/security/signature_spec.rb +66 -0
  166. data/spec/security/static_certificate_store_spec.rb +58 -0
  167. data/spec/sender_spec.rb +1045 -0
  168. data/spec/serialize/message_pack_spec.rb +131 -0
  169. data/spec/serialize/secure_serializer_spec.rb +132 -0
  170. data/spec/serialize/serializable_spec.rb +90 -0
  171. data/spec/serialize/serializer_spec.rb +197 -0
  172. data/spec/spec.opts +2 -0
  173. data/spec/spec.win32.opts +1 -0
  174. data/spec/spec_helper.rb +130 -0
  175. data/spec/tracer_spec.rb +114 -0
  176. metadata +447 -0
@@ -0,0 +1,480 @@
1
+ #
2
+ # Copyright (c) 2009-2011 RightScale Inc
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+
23
+ module RightScale
24
+
25
+ # Helper methods for accessing RightAgent files, directories, and processes.
26
+ # Values returned are driven by root_dir, cfg_dir, and pid_dir, which may be set
27
+ # but have defaults, and secondarily by the contents of the associated agent
28
+ # configuration file generated by the 'rad' tool.
29
+ #
30
+ # The root_dir may be specified to be a list of root directories to be searched
31
+ # when looking for agent files. It defaults to the current working directory.
32
+ # A root directory is assumed to contain some or all of the following directories:
33
+ # init - initialization code
34
+ # actors - actor code
35
+ # certs - security certificates and keys
36
+ # lib - additional agent code
37
+ # scripts - tools code
38
+ #
39
+ # The init directory contains the following initialization code:
40
+ # config.yml - static configuration settings for the agent
41
+ # init.rb - code that registers the agent's actors and performs any other
42
+ # agent specific initialization such as initializing its
43
+ # secure serializer and its command protocol server
44
+ #
45
+ # The certs directory contains the x.509 public certificate and keys needed
46
+ # to sign and encrypt all outgoing messages as well as to check the signature
47
+ # and decrypt any incoming messages. If AMQP is being used as the RightNet
48
+ # protocol, this directory should contain at least:
49
+ # <agent name>.key - agent's' private key
50
+ # <agent name>.cert - agent's' public certificate
51
+ # router.cert - router's' public certificate
52
+ #
53
+ # The scripts directory at a minimum contains the following:
54
+ # install.sh - script for installing standard and agent specific tools in /usr/bin
55
+ #
56
+ # The cfg_dir is the path to the directory containing a directory for each agent
57
+ # configured on the local machine (e.g., core, core_2, core_3). Each agent directory
58
+ # in turn contains a config.yml file generated to contain that agent's current
59
+ # configuration. The cfg_dir defaults to the platform specific cfg_dir.
60
+ #
61
+ # The pid_dir is the path to the directory where agent process id files are stored.
62
+ # These files are typically named <agent identity>.pid. The pid_dir defaults to the
63
+ # current to the platform specific pid_dir.
64
+ module AgentConfig
65
+
66
+ # Current agent protocol version
67
+ PROTOCOL_VERSION = 23
68
+
69
+ # Current agent protocol version
70
+ #
71
+ # === Return
72
+ # (Integer):: Protocol version
73
+ def self.protocol_version
74
+ PROTOCOL_VERSION
75
+ end
76
+
77
+ # Default thread name when no thread is specified for an executable bundle.
78
+ DEFAULT_THREAD_NAME = 'default'
79
+
80
+ # Default thread name when no thread is specified for an executable bundle.
81
+ #
82
+ # === Return
83
+ # (String):: default thread name...
84
+ def self.default_thread_name
85
+ DEFAULT_THREAD_NAME
86
+ end
87
+
88
+ # Regular expression to define what a valid thread name looks like: an alpha character
89
+ # followed by 0 or more alphanumerics or underscores. Only lower-case characters are
90
+ # allowed.
91
+ VALID_THREAD_NAME = /^[a-z][a-z0-9_]*$/
92
+
93
+ # Regular expression to define what a valid thread name looks like: an alpha character
94
+ # followed by 0 or more alphanumerics or underscores. Only lower-case characters are
95
+ # allowed.
96
+ #
97
+ # === Return
98
+ # (String):: default thread name...
99
+ def self.valid_thread_name
100
+ VALID_THREAD_NAME
101
+ end
102
+
103
+ # Default policy name when no policy is specified for an executable bundle.
104
+ DEFAULT_POLICY_NAME = nil
105
+
106
+ # Default policy name when no policy is specified for an executable bundle.
107
+ #
108
+ # === Return
109
+ # (String):: default policy name...
110
+ def self.default_policy_name
111
+ DEFAULT_POLICY_NAME
112
+ end
113
+
114
+ # Default period for policies
115
+ DEFAULT_POLICY_PERIOD = 60 * 60 * 24
116
+
117
+ # Default audit period when a runlist policy does not specify a period.
118
+ #
119
+ # === Return
120
+ # (String):: default policy name...
121
+ def self.default_audit_period
122
+ DEFAULT_POLICY_PERIOD
123
+ end
124
+
125
+ # Default server secret in case it is not provided by core.
126
+ DEFAULT_SERVER_SECRET = "1a7c8f89bb78fcf1b225324af0abc474d308a5e7f654080664231af3b268db1e"
127
+
128
+ # Default server secret in case it is not provided by core.
129
+ #
130
+ # === Return
131
+ # (String):: default server secret...
132
+ def self.default_server_secret
133
+ DEFAULT_SERVER_SECRET
134
+ end
135
+
136
+ # Initialize path to root directory of agent
137
+ #
138
+ # === Parameters
139
+ # dir(String|Array):: Directory path or ordered list of directory paths to be searched
140
+ #
141
+ # === Return
142
+ # (Array):: Ordered list of directory paths to be searched
143
+ def self.root_dir=(dir)
144
+ @root_dirs = array(dir)
145
+ end
146
+
147
+ # Initialize path to directory containing generated agent configuration files
148
+ #
149
+ # === Parameters
150
+ # dir(String):: Directory path
151
+ #
152
+ # === Return
153
+ # (String):: Directory path
154
+ def self.cfg_dir=(dir)
155
+ @cfg_dir = dir
156
+ end
157
+
158
+ # Initialize path to directory containing agent process id files
159
+ #
160
+ # === Parameters
161
+ # dir(String):: Directory path
162
+ #
163
+ # === Return
164
+ # (String):: Directory path
165
+ def self.pid_dir=(dir)
166
+ @pid_dir = dir
167
+ end
168
+
169
+ # Root directory path(s)
170
+ #
171
+ # === Return
172
+ # (String|Array):: Individual directory path if only one, otherwise array of paths
173
+ def self.root_dir
174
+ (d = root_dirs).size > 1 ? d : d.first
175
+ end
176
+
177
+ # Path to agent init.rb file containing code that registers the agent's actors
178
+ # and performs any other agent specific initialization such as initializing its
179
+ # secure serializer and its command protocol server
180
+ #
181
+ # === Return
182
+ # (String|nil):: File path name, or nil if file does not exist
183
+ def self.init_file
184
+ first_file(:init_dir, "init.rb")
185
+ end
186
+
187
+ # Path to agent config.yml file containing static configuration settings
188
+ #
189
+ # === Return
190
+ # (String|nil):: File path name, or nil if file does not exist
191
+ def self.init_cfg_file
192
+ first_file(:init_dir, "config.yml")
193
+ end
194
+
195
+ # Ordered list of directory path names for searching for actors:
196
+ # - actors directory in each configured root directory
197
+ # - other directories produced by other_actors_dirs method, e.g., in other associated gems
198
+ # - actors directory in RightAgent gem
199
+ #
200
+ # === Return
201
+ # actors_dirs(Array):: List of directory path names
202
+ def self.actors_dirs
203
+ actors_dirs = all_dirs(:actors_dir)
204
+ actors_dirs += other_actors_dirs if self.respond_to?(:other_actors_dirs)
205
+ actors_dirs << File.normalize_path(File.join(File.dirname(__FILE__), 'actors'))
206
+ actors_dirs
207
+ end
208
+
209
+ # Path to directory containing certificates
210
+ #
211
+ # === Parameters
212
+ # root_dir(String|nil):: Specific root dir to use (must be in root_dirs),
213
+ # if nil use first dir in root_dirs
214
+ #
215
+ # === Return
216
+ # (String|nil):: Path to certs directory, or nil if cannot determine root_dir
217
+ def self.certs_dir(root_dir = nil)
218
+ if root_dir
219
+ root_dir = nil unless @root_dirs && @root_dirs.include?(root_dir)
220
+ else
221
+ root_dir = @root_dirs.first if @root_dirs
222
+ end
223
+ File.normalize_path(File.join(root_dir, "certs")) if root_dir
224
+ end
225
+
226
+ # Path to security file containing X.509 data
227
+ #
228
+ # === Parameters
229
+ # name(String):: Security file name
230
+ #
231
+ # === Return
232
+ # file(String|nil):: File path name, or nil if file does not exist
233
+ def self.certs_file(name)
234
+ first_file(:certs_dir, name)
235
+ end
236
+
237
+ # All security files matching pattern
238
+ #
239
+ # === Parameters
240
+ # pattern(String):: Pattern for security files of interest, e.g., '*.cert' or
241
+ # '*.{cert,key}'
242
+ #
243
+ # === Return
244
+ # files(Array):: Path name of files found
245
+ def self.certs_files(pattern)
246
+ files = []
247
+ names = []
248
+ all_dirs(:certs_dir).each do |d|
249
+ certs = Dir.glob(File.join(d, pattern)).each do |f|
250
+ unless names.include?(b = File.basename(f))
251
+ files << f
252
+ names << b
253
+ end
254
+ end
255
+ end
256
+ files
257
+ end
258
+
259
+ # Path to first agent lib directory
260
+ #
261
+ # === Return
262
+ # dir(String):: Directory path name
263
+ def self.lib_dir
264
+ all_dirs(:lib_dir2).first
265
+ end
266
+
267
+ # Path to first agent scripts directory
268
+ #
269
+ # === Return
270
+ # dir(String):: Directory path name
271
+ def self.scripts_dir
272
+ all_dirs(:scripts_dir2).first
273
+ end
274
+
275
+ # Path to directory containing a directory for each agent configured on the local machine
276
+ #
277
+ # === Return
278
+ # (String):: Directory path name
279
+ def self.cfg_dir
280
+ @cfg_dir ||= Platform.filesystem.right_agent_cfg_dir
281
+ end
282
+
283
+ # Path to generated agent configuration file
284
+ #
285
+ # === Parameters
286
+ # agent_name(String):: Agent name
287
+ # exists(Boolean):: Whether to return nil if does not exist
288
+ #
289
+ # === Return
290
+ # (String):: Configuration file path name, or nil if file does not exist
291
+ def self.cfg_file(agent_name, exists = false)
292
+ file = File.normalize_path(File.join(cfg_dir, agent_name, "config.yml"))
293
+ file = nil unless !exists || File.exist?(file)
294
+ file
295
+ end
296
+
297
+ # Configuration file path names for all agents configured locally
298
+ #
299
+ # === Return
300
+ # (Array):: Agent configuration file path names
301
+ def self.cfg_files
302
+ Dir.glob(File.join(cfg_dir, "**", "*.yml"))
303
+ end
304
+
305
+ # Configured agents i.e. agents that have a configuration file
306
+ #
307
+ # === Return
308
+ # (Array):: Name of configured agents
309
+ def self.cfg_agents
310
+ cfg_files.map { |c| File.basename(File.dirname(c)) }
311
+ end
312
+
313
+ # Agent name associated with given agent identity
314
+ #
315
+ # === Parameters
316
+ # agent_id(String):: Serialized agent identity
317
+ #
318
+ # === Return
319
+ # (String|nil):: Agent name, or nil if agent not found
320
+ def self.agent_name(agent_id)
321
+ cfg_agents.each do |a|
322
+ if (options = agent_options(a)) && options[:identity] == agent_id
323
+ return a
324
+ end
325
+ end
326
+ nil
327
+ end
328
+
329
+ # Get options from agent's configuration file
330
+ #
331
+ # === Parameters
332
+ # agent_name(String):: Agent name
333
+ #
334
+ # === Return
335
+ # (Hash|nil):: Agent options with key names symbolized,
336
+ # or nil if file not accessible or empty
337
+ def self.load_cfg(agent_name)
338
+ if (file = cfg_file(agent_name, exists = true)) && File.readable?(file) && (cfg = YAML.load(IO.read(file)))
339
+ SerializationHelper.symbolize_keys(cfg)
340
+ end
341
+ end
342
+
343
+ # Write agent's configuration to file
344
+ #
345
+ # === Parameters
346
+ # agent_name(String):: Agent name
347
+ # cfg(Hash):: Configuration options
348
+ #
349
+ # === Return
350
+ # file(String):: Configuration file path name
351
+ def self.store_cfg(agent_name, cfg)
352
+ file = cfg_file(agent_name)
353
+ FileUtils.mkdir_p(File.dirname(file))
354
+ File.delete(file) if File.exists?(file)
355
+ File.open(file, 'w') do |fd|
356
+ fd.puts "# Created at #{Time.now}"
357
+ fd.write(YAML.dump(cfg))
358
+ end
359
+ file
360
+ end
361
+
362
+ # Path to directory containing agent process id files
363
+ #
364
+ # === Return
365
+ # (String):: Directory path name
366
+ def self.pid_dir
367
+ @pid_dir ||= Platform.filesystem.pid_dir
368
+ end
369
+
370
+ # Retrieve agent process id file
371
+ #
372
+ # === Parameters
373
+ # agent_name(String):: Agent name
374
+ #
375
+ # === Return
376
+ # (PidFile|nil):: Process id file, or nil if there is no configuration file for agent
377
+ def self.pid_file(agent_name)
378
+ if options = load_cfg(agent_name)
379
+ PidFile.new(options[:identity], options[:pid_dir])
380
+ end
381
+ end
382
+
383
+ # Agent options from generated agent configuration file
384
+ # and agent process id file if they exist
385
+ # Reset root_dir and pid_dir to one found in agent configuration file
386
+ #
387
+ # === Parameters
388
+ # agent_name(String):: Agent name
389
+ #
390
+ # === Return
391
+ # options(Hash):: Agent options including
392
+ # :identity(String):: Serialized agent identity
393
+ # :log_path(String):: Path to directory for agent log file
394
+ # :pid(Integer):: Agent process pid if available
395
+ # :listen_port(Integer):: Agent command listen port if available
396
+ # :cookie(String):: Agent command cookie if available
397
+ def self.agent_options(agent_name)
398
+ if options = load_cfg(agent_name)
399
+ @root_dirs = array(options[:root_dir])
400
+ @pid_dir = options[:pid_dir]
401
+ options[:log_path] = options[:log_dir] || Platform.filesystem.log_dir
402
+ pid_file = PidFile.new(options[:identity])
403
+ options.merge!(pid_file.read_pid) if pid_file.exists?
404
+ end
405
+ options || {}
406
+ end
407
+
408
+ # Agents that are currently running
409
+ #
410
+ # === Parameters
411
+ # (Regexp):: Pattern that agent name must match to be included
412
+ #
413
+ # === Return
414
+ # (Array):: Name of running agents
415
+ def self.running_agents(pattern = //)
416
+ AgentConfig.cfg_agents.select do |agent_name|
417
+ agent_name =~ pattern &&
418
+ (pid_file = AgentConfig.pid_file(agent_name)) &&
419
+ (pid = pid_file.read_pid[:pid]) &&
420
+ (Process.getpgid(pid) rescue -1) != -1
421
+ end.sort
422
+ end
423
+
424
+ protected
425
+
426
+ # Convert value to array if not an array, unless nil
427
+ def self.array(value)
428
+ (value.nil? || value.is_a?(Array)) ? value : [value]
429
+ end
430
+
431
+ # Ordered list of root directories
432
+ def self.root_dirs
433
+ @root_dirs || [Dir.pwd]
434
+ end
435
+
436
+ # Path to agent directory containing initialization files
437
+ def self.init_dir(root_dir)
438
+ File.normalize_path(File.join(root_dir, "init"))
439
+ end
440
+
441
+ # Path to directory containing actor source files
442
+ def self.actors_dir(root_dir)
443
+ File.normalize_path(File.join(root_dir, "actors"))
444
+ end
445
+
446
+ # Path to agent directory containing code
447
+ def self.lib_dir2(root_dir)
448
+ File.normalize_path(File.join(root_dir, "lib"))
449
+ end
450
+
451
+ # Path to agent directory containing scripts
452
+ def self.scripts_dir2(root_dir)
453
+ File.normalize_path(File.join(root_dir, "scripts"))
454
+ end
455
+
456
+ # All existing directories of given type
457
+ def self.all_dirs(type)
458
+ dirs = []
459
+ root_dirs.each do |d|
460
+ c = self.send(type, d)
461
+ dirs << c if File.directory?(c)
462
+ end
463
+ dirs
464
+ end
465
+
466
+ # Path name of first file found of given type and name, or nil if none found
467
+ def self.first_file(type, name)
468
+ file = nil
469
+ root_dirs.each do |d|
470
+ if File.exist?(f = File.join(self.send(type, d), name))
471
+ file = f
472
+ break
473
+ end
474
+ end
475
+ file
476
+ end
477
+
478
+ end # AgentConfig
479
+
480
+ end # RightScale