right_agent 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. data/LICENSE +20 -0
  2. data/README.rdoc +78 -0
  3. data/Rakefile +86 -0
  4. data/lib/right_agent.rb +66 -0
  5. data/lib/right_agent/actor.rb +163 -0
  6. data/lib/right_agent/actor_registry.rb +76 -0
  7. data/lib/right_agent/actors/agent_manager.rb +189 -0
  8. data/lib/right_agent/agent.rb +735 -0
  9. data/lib/right_agent/agent_config.rb +403 -0
  10. data/lib/right_agent/agent_identity.rb +209 -0
  11. data/lib/right_agent/agent_tags_manager.rb +213 -0
  12. data/lib/right_agent/audit_formatter.rb +107 -0
  13. data/lib/right_agent/broker_client.rb +683 -0
  14. data/lib/right_agent/command.rb +30 -0
  15. data/lib/right_agent/command/agent_manager_commands.rb +134 -0
  16. data/lib/right_agent/command/command_client.rb +136 -0
  17. data/lib/right_agent/command/command_constants.rb +42 -0
  18. data/lib/right_agent/command/command_io.rb +128 -0
  19. data/lib/right_agent/command/command_parser.rb +87 -0
  20. data/lib/right_agent/command/command_runner.rb +105 -0
  21. data/lib/right_agent/command/command_serializer.rb +63 -0
  22. data/lib/right_agent/console.rb +65 -0
  23. data/lib/right_agent/core_payload_types.rb +42 -0
  24. data/lib/right_agent/core_payload_types/cookbook.rb +61 -0
  25. data/lib/right_agent/core_payload_types/cookbook_position.rb +46 -0
  26. data/lib/right_agent/core_payload_types/cookbook_repository.rb +116 -0
  27. data/lib/right_agent/core_payload_types/cookbook_sequence.rb +70 -0
  28. data/lib/right_agent/core_payload_types/dev_repositories.rb +90 -0
  29. data/lib/right_agent/core_payload_types/event_categories.rb +38 -0
  30. data/lib/right_agent/core_payload_types/executable_bundle.rb +138 -0
  31. data/lib/right_agent/core_payload_types/login_policy.rb +72 -0
  32. data/lib/right_agent/core_payload_types/login_user.rb +62 -0
  33. data/lib/right_agent/core_payload_types/planned_volume.rb +94 -0
  34. data/lib/right_agent/core_payload_types/recipe_instantiation.rb +60 -0
  35. data/lib/right_agent/core_payload_types/repositories_bundle.rb +50 -0
  36. data/lib/right_agent/core_payload_types/right_script_attachment.rb +95 -0
  37. data/lib/right_agent/core_payload_types/right_script_instantiation.rb +73 -0
  38. data/lib/right_agent/core_payload_types/secure_document.rb +66 -0
  39. data/lib/right_agent/core_payload_types/secure_document_location.rb +63 -0
  40. data/lib/right_agent/core_payload_types/software_repository_instantiation.rb +61 -0
  41. data/lib/right_agent/daemonize.rb +35 -0
  42. data/lib/right_agent/dispatcher.rb +348 -0
  43. data/lib/right_agent/enrollment_result.rb +217 -0
  44. data/lib/right_agent/exceptions.rb +30 -0
  45. data/lib/right_agent/ha_broker_client.rb +1278 -0
  46. data/lib/right_agent/idempotent_request.rb +140 -0
  47. data/lib/right_agent/log.rb +418 -0
  48. data/lib/right_agent/monkey_patches.rb +29 -0
  49. data/lib/right_agent/monkey_patches/amqp_patch.rb +274 -0
  50. data/lib/right_agent/monkey_patches/ruby_patch.rb +49 -0
  51. data/lib/right_agent/monkey_patches/ruby_patch/array_patch.rb +29 -0
  52. data/lib/right_agent/monkey_patches/ruby_patch/darwin_patch.rb +24 -0
  53. data/lib/right_agent/monkey_patches/ruby_patch/linux_patch.rb +24 -0
  54. data/lib/right_agent/monkey_patches/ruby_patch/linux_patch/file_patch.rb +30 -0
  55. data/lib/right_agent/monkey_patches/ruby_patch/object_patch.rb +49 -0
  56. data/lib/right_agent/monkey_patches/ruby_patch/singleton_patch.rb +46 -0
  57. data/lib/right_agent/monkey_patches/ruby_patch/string_patch.rb +107 -0
  58. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch.rb +32 -0
  59. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/file_patch.rb +90 -0
  60. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/process_patch.rb +63 -0
  61. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/stdio_patch.rb +27 -0
  62. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/time_patch.rb +55 -0
  63. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/win32ole_patch.rb +34 -0
  64. data/lib/right_agent/multiplexer.rb +91 -0
  65. data/lib/right_agent/operation_result.rb +270 -0
  66. data/lib/right_agent/packets.rb +637 -0
  67. data/lib/right_agent/payload_formatter.rb +104 -0
  68. data/lib/right_agent/pid_file.rb +159 -0
  69. data/lib/right_agent/platform.rb +319 -0
  70. data/lib/right_agent/platform/darwin.rb +227 -0
  71. data/lib/right_agent/platform/linux.rb +268 -0
  72. data/lib/right_agent/platform/windows.rb +1204 -0
  73. data/lib/right_agent/scripts/agent_controller.rb +522 -0
  74. data/lib/right_agent/scripts/agent_deployer.rb +379 -0
  75. data/lib/right_agent/scripts/common_parser.rb +153 -0
  76. data/lib/right_agent/scripts/log_level_manager.rb +193 -0
  77. data/lib/right_agent/scripts/stats_manager.rb +256 -0
  78. data/lib/right_agent/scripts/usage.rb +58 -0
  79. data/lib/right_agent/secure_identity.rb +92 -0
  80. data/lib/right_agent/security.rb +32 -0
  81. data/lib/right_agent/security/cached_certificate_store_proxy.rb +63 -0
  82. data/lib/right_agent/security/certificate.rb +102 -0
  83. data/lib/right_agent/security/certificate_cache.rb +89 -0
  84. data/lib/right_agent/security/distinguished_name.rb +56 -0
  85. data/lib/right_agent/security/encrypted_document.rb +84 -0
  86. data/lib/right_agent/security/rsa_key_pair.rb +76 -0
  87. data/lib/right_agent/security/signature.rb +86 -0
  88. data/lib/right_agent/security/static_certificate_store.rb +69 -0
  89. data/lib/right_agent/sender.rb +937 -0
  90. data/lib/right_agent/serialize.rb +29 -0
  91. data/lib/right_agent/serialize/message_pack.rb +102 -0
  92. data/lib/right_agent/serialize/secure_serializer.rb +131 -0
  93. data/lib/right_agent/serialize/secure_serializer_initializer.rb +47 -0
  94. data/lib/right_agent/serialize/serializable.rb +135 -0
  95. data/lib/right_agent/serialize/serializer.rb +149 -0
  96. data/lib/right_agent/stats_helper.rb +731 -0
  97. data/lib/right_agent/subprocess.rb +38 -0
  98. data/lib/right_agent/tracer.rb +124 -0
  99. data/right_agent.gemspec +60 -0
  100. data/spec/actor_registry_spec.rb +81 -0
  101. data/spec/actor_spec.rb +99 -0
  102. data/spec/agent_config_spec.rb +226 -0
  103. data/spec/agent_identity_spec.rb +75 -0
  104. data/spec/agent_spec.rb +571 -0
  105. data/spec/broker_client_spec.rb +961 -0
  106. data/spec/command/agent_manager_commands_spec.rb +51 -0
  107. data/spec/command/command_io_spec.rb +93 -0
  108. data/spec/command/command_parser_spec.rb +79 -0
  109. data/spec/command/command_runner_spec.rb +72 -0
  110. data/spec/command/command_serializer_spec.rb +51 -0
  111. data/spec/core_payload_types/dev_repositories_spec.rb +64 -0
  112. data/spec/core_payload_types/executable_bundle_spec.rb +59 -0
  113. data/spec/core_payload_types/login_user_spec.rb +98 -0
  114. data/spec/core_payload_types/right_script_attachment_spec.rb +65 -0
  115. data/spec/core_payload_types/spec_helper.rb +23 -0
  116. data/spec/dispatcher_spec.rb +372 -0
  117. data/spec/enrollment_result_spec.rb +53 -0
  118. data/spec/ha_broker_client_spec.rb +1673 -0
  119. data/spec/idempotent_request_spec.rb +136 -0
  120. data/spec/log_spec.rb +177 -0
  121. data/spec/monkey_patches/amqp_patch_spec.rb +100 -0
  122. data/spec/monkey_patches/eventmachine_spec.rb +62 -0
  123. data/spec/monkey_patches/string_patch_spec.rb +99 -0
  124. data/spec/multiplexer_spec.rb +48 -0
  125. data/spec/operation_result_spec.rb +171 -0
  126. data/spec/packets_spec.rb +418 -0
  127. data/spec/platform/platform_spec.rb +60 -0
  128. data/spec/results_mock.rb +45 -0
  129. data/spec/secure_identity_spec.rb +50 -0
  130. data/spec/security/cached_certificate_store_proxy_spec.rb +56 -0
  131. data/spec/security/certificate_cache_spec.rb +71 -0
  132. data/spec/security/certificate_spec.rb +49 -0
  133. data/spec/security/distinguished_name_spec.rb +46 -0
  134. data/spec/security/encrypted_document_spec.rb +55 -0
  135. data/spec/security/rsa_key_pair_spec.rb +55 -0
  136. data/spec/security/signature_spec.rb +66 -0
  137. data/spec/security/static_certificate_store_spec.rb +52 -0
  138. data/spec/sender_spec.rb +887 -0
  139. data/spec/serialize/message_pack_spec.rb +131 -0
  140. data/spec/serialize/secure_serializer_spec.rb +102 -0
  141. data/spec/serialize/serializable_spec.rb +90 -0
  142. data/spec/serialize/serializer_spec.rb +174 -0
  143. data/spec/spec.opts +2 -0
  144. data/spec/spec_helper.rb +77 -0
  145. data/spec/stats_helper_spec.rb +681 -0
  146. data/spec/tracer_spec.rb +114 -0
  147. metadata +320 -0
@@ -0,0 +1,522 @@
1
+ # === Synopsis:
2
+ # RightScale RightAgent Controller (rnac) - (c) 2009-2011 RightScale Inc
3
+ #
4
+ # rnac is a command line tool for managing a RightAgent
5
+ #
6
+ # === Examples:
7
+ # Start new agent named AGENT:
8
+ # rnac --start AGENT
9
+ # rnac -s AGENT
10
+ #
11
+ # Stop running agent named AGENT:
12
+ # rnac --stop AGENT
13
+ # rnac -p AGENT
14
+ #
15
+ # Stop agent with given serialized ID:
16
+ # rnac --stop-agent ID
17
+ #
18
+ # Terminate all agents on local machine:
19
+ # rnac --killall
20
+ # rnac -K
21
+ #
22
+ # List agents configured on local machine:
23
+ # rnac --list
24
+ # rnac -l
25
+ #
26
+ # List status of agents configured on local machine:
27
+ # rnac --status
28
+ # rnac -U
29
+ #
30
+ # Start new agent named AGENT in foreground:
31
+ # rnac --start AGENT --foreground
32
+ # rnac -s AGENT -f
33
+ #
34
+ # Start new agent named AGENT of type TYPE:
35
+ # rnac --start AGENT --type TYPE
36
+ # rnac -s AGENT -t TYPE
37
+ #
38
+ # Note: To start multiple agents of the same type generate one
39
+ # config.yml file with rad and then start each agent with rnac:
40
+ # rad my_agent
41
+ # rnac -s my_agent_1 -t my_agent
42
+ # rnac -s my_agent_2 -t my_agent
43
+ #
44
+ # === Usage:
45
+ # rnac [options]
46
+ #
47
+ # options:
48
+ # --start, -s AGENT Start agent named AGENT
49
+ # --stop, -p AGENT Stop agent named AGENT
50
+ # --stop-agent ID Stop agent with serialized identity ID
51
+ # --kill, -k PIDFILE Kill process with given process id file
52
+ # --killall, -K Stop all running agents
53
+ # --status, -U List running agents on local machine
54
+ # --identity, -i ID Use base id ID to build agent's identity
55
+ # --token, -t TOKEN Use token TOKEN to build agent's identity
56
+ # --prefix, -x PREFIX Use prefix PREFIX to build agent's identity
57
+ # --type TYPE Use agent type TYPE to build agent's' identity,98589
58
+ # defaults to AGENT with any trailing '_[0-9]+' removed
59
+ # --list, -l List all configured agents
60
+ # --user, -u USER Set AMQP user
61
+ # --pass, -p PASS Set AMQP password
62
+ # --vhost, -v VHOST Set AMQP vhost
63
+ # --host, -h HOST Set AMQP server hostname
64
+ # --port, -P PORT Set AMQP server port
65
+ # --cfg-dir, -c DIR Set directory containing configuration for all agents
66
+ # --pid-dir, -z DIR Set directory containing agent process id files
67
+ # --log-dir DIR Set log directory
68
+ # --log-level LVL Log level (debug, info, warning, error or fatal)
69
+ # --foreground, -f Run agent in foreground
70
+ # --interactive, -I Spawn an irb console after starting agent
71
+ # --test Use test settings
72
+ # --help Display help
73
+
74
+ require 'rubygems'
75
+ require 'optparse'
76
+ require 'fileutils'
77
+ require File.expand_path(File.join(File.dirname(__FILE__), 'usage'))
78
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'right_agent'))
79
+ require File.expand_path(File.join(File.dirname(__FILE__), 'common_parser'))
80
+
81
+ module RightScale
82
+
83
+ class AgentController
84
+
85
+ include CommonParser
86
+
87
+ FORCED_OPTIONS =
88
+ {
89
+ :threadpool_size => 1
90
+ }
91
+
92
+ DEFAULT_OPTIONS =
93
+ {
94
+ :single_threaded => true,
95
+ :log_dir => Platform.filesystem.log_dir,
96
+ :daemonize => true
97
+ }
98
+
99
+ @@agent = nil
100
+
101
+ # Create and run controller
102
+ #
103
+ # === Return
104
+ # true:: Always return true
105
+ def self.run
106
+ c = AgentController.new
107
+ c.control(c.parse_args)
108
+ end
109
+
110
+ # Parse arguments and execute request
111
+ #
112
+ # === Parameters
113
+ # options(Hash):: Command line options
114
+ #
115
+ # === Return
116
+ # true:: Always return true
117
+ def control(options)
118
+ # Initialize directory settings
119
+ AgentConfig.cfg_dir = options[:cfg_dir]
120
+ AgentConfig.pid_dir = options[:pid_dir]
121
+
122
+ # List agents if requested
123
+ list_configured_agents if options[:list]
124
+
125
+ # Validate arguments
126
+ action = options.delete(:action)
127
+ fail("No action specified on the command line.", print_usage = true) unless action
128
+ if action == 'kill' && (options[:pid_file].nil? || !File.file?(options[:pid_file]))
129
+ fail("Missing or invalid pid file #{options[:pid_file]}", print_usage = true)
130
+ end
131
+ if options[:agent_name]
132
+ if action == 'start'
133
+ cfg = configure_agent(action, options)
134
+ else
135
+ cfg = AgentConfig.load_cfg(options[:agent_name])
136
+ fail("Deployment is missing configuration file #{AgentConfig.cfg_file(options[:agent_name]).inspect}.") unless cfg
137
+ end
138
+ options.delete(:identity)
139
+ options = cfg.merge(options)
140
+ AgentConfig.root_dir = options[:root_dir]
141
+ AgentConfig.pid_dir = options[:pid_dir]
142
+ Log.program_name = syslog_program_name(options)
143
+ Log.log_to_file_only(options[:log_to_file_only])
144
+ configure_proxy(options[:http_proxy], options[:http_no_proxy]) if options[:http_proxy]
145
+ elsif options[:identity]
146
+ options[:agent_name] = AgentConfig.agent_name(options[:identity])
147
+ end
148
+ @options = DEFAULT_OPTIONS.clone.merge(options.merge(FORCED_OPTIONS))
149
+ FileUtils.mkdir_p(@options[:pid_dir]) unless @options[:pid_dir].nil? || File.directory?(@options[:pid_dir])
150
+
151
+ # Execute request
152
+ success = case action
153
+ when /show|killall/
154
+ action = 'stop' if action == 'killall'
155
+ s = true
156
+ AgentConfig.cfg_agents.each { |agent_name| s &&= dispatch(action, agent_name) }
157
+ s
158
+ when 'kill'
159
+ kill_process
160
+ else
161
+ dispatch(action, @options[:agent_name])
162
+ end
163
+
164
+ exit(1) unless success
165
+ end
166
+
167
+ # Create options hash from command line arguments
168
+ #
169
+ # === Return
170
+ # options(Hash):: Parsed options
171
+ def parse_args
172
+ options = {}
173
+
174
+ opts = OptionParser.new do |opts|
175
+ parse_common(opts, options)
176
+ parse_other_args(opts, options)
177
+
178
+ opts.on("-s", "--start AGENT") do |a|
179
+ options[:action] = 'start'
180
+ options[:agent_name] = a
181
+ end
182
+
183
+ opts.on("-p", "--stop AGENT") do |a|
184
+ options[:action] = 'stop'
185
+ options[:agent_name] = a
186
+ end
187
+
188
+ opts.on("--stop-agent ID") do |id|
189
+ options[:action] = 'stop'
190
+ options[:identity] = id
191
+ end
192
+
193
+ opts.on("-k", "--kill PIDFILE") do |file|
194
+ options[:pid_file] = file
195
+ options[:action] = 'kill'
196
+ end
197
+
198
+ opts.on("-K", "--killall") do
199
+ options[:action] = 'killall'
200
+ end
201
+
202
+ opts.on("-U", "--status") do
203
+ options[:action] = 'show'
204
+ end
205
+
206
+ opts.on("-l", "--list") do
207
+ options[:list] = true
208
+ end
209
+
210
+ opts.on("--log-level LVL") do |lvl|
211
+ options[:log_level] = lvl
212
+ end
213
+
214
+ opts.on("-c", "--cfg-dir DIR") do |d|
215
+ options[:cfg_dir] = d
216
+ end
217
+
218
+ opts.on("-z", "--pid-dir DIR") do |dir|
219
+ options[:pid_dir] = dir
220
+ end
221
+
222
+ opts.on("--log-dir DIR") do |dir|
223
+ options[:log_dir] = dir
224
+
225
+ # Ensure log directory exists (for windows, etc.)
226
+ FileUtils.mkdir_p(dir) unless File.directory?(dir)
227
+ end
228
+
229
+ opts.on("-f", "--foreground") do
230
+ options[:daemonize] = false
231
+ #Squelch Ruby VM warnings about various things
232
+ $VERBOSE = nil
233
+ end
234
+
235
+ opts.on("-I", "--interactive") do
236
+ options[:console] = true
237
+ end
238
+
239
+ opts.on_tail("--help") do
240
+ puts Usage.scan(__FILE__)
241
+ exit
242
+ end
243
+
244
+ end
245
+
246
+ begin
247
+ opts.parse(ARGV)
248
+ rescue Exception => e
249
+ exit 0 if e.is_a?(SystemExit)
250
+ fail(e.message, print_usage = true)
251
+ end
252
+ resolve_identity(options)
253
+ options
254
+ end
255
+
256
+ protected
257
+
258
+ # Parse any other arguments used by agent
259
+ #
260
+ # === Parameters
261
+ # opts(OptionParser):: Options parser with options to be parsed
262
+ # options(Hash):: Storage for options that are parsed
263
+ #
264
+ # === Return
265
+ # true:: Always return true
266
+ def parse_other_args(opts, options)
267
+ true
268
+ end
269
+
270
+ # Dispatch action
271
+ #
272
+ # === Parameters
273
+ # action(String):: Action to be performed
274
+ # agent_name(String):: Agent name
275
+ #
276
+ # === Return
277
+ # true:: Always return true
278
+ def dispatch(action, agent_name)
279
+ # Setup the environment from config if necessary
280
+ begin
281
+ eval("#{action}_agent(agent_name)")
282
+ rescue SystemExit
283
+ true
284
+ rescue SignalException
285
+ true
286
+ rescue Exception => e
287
+ puts Log.format("Failed to #{action} #{agent_name}", e, :trace)
288
+ end
289
+ true
290
+ end
291
+
292
+ # Kill process defined in pid file
293
+ #
294
+ # === Parameters
295
+ # sig(String):: Signal to be used for kill
296
+ #
297
+ # === Return
298
+ # true:: Always return true
299
+ def kill_process(sig = 'TERM')
300
+ content = IO.read(@options[:pid_file])
301
+ pid = content.to_i
302
+ fail("Invalid pid file content #{content.inspect}") if pid == 0
303
+ begin
304
+ Process.kill(sig, pid)
305
+ rescue Errno::ESRCH => e
306
+ fail("Could not find process with pid #{pid}")
307
+ rescue Errno::EPERM => e
308
+ fail("You don't have permissions to stop process #{pid}")
309
+ rescue Exception => e
310
+ fail(e.message)
311
+ end
312
+ true
313
+ end
314
+
315
+ # Start agent
316
+ #
317
+ # === Parameters
318
+ # agent_name(String):: Agent name
319
+ # agent_class(Agent):: Agent class
320
+ #
321
+ # === Return
322
+ # true:: Always return true
323
+ def start_agent(agent_name, agent_class = Agent)
324
+ puts "#{human_readable_name} being started"
325
+
326
+ EM.error_handler do |e|
327
+ Log.error("EM block execution failed with exception", e, :trace)
328
+ Log.error("\n\n===== Exiting due to EM block exception =====\n\n")
329
+ EM.stop
330
+ end
331
+
332
+ EM.run do
333
+ begin
334
+ @@agent = agent_class.start(@options)
335
+ rescue SystemExit
336
+ raise # Let parents of forked (daemonized) processes die
337
+ rescue PidFile::AlreadyRunning
338
+ puts "#{human_readable_name} already running"
339
+ EM.stop
340
+ rescue Exception => e
341
+ puts Log.format("#{human_readable_name} failed", e, :trace)
342
+ EM.stop
343
+ end
344
+ end
345
+ true
346
+ end
347
+
348
+ # Stop agent process
349
+ #
350
+ # === Parameters
351
+ # agent_name(String):: Agent name
352
+ #
353
+ # === Return
354
+ # (Boolean):: true if process was stopped, otherwise false
355
+ def stop_agent(agent_name)
356
+ res = false
357
+ if pid_file = AgentConfig.pid_file(agent_name)
358
+ name = human_readable_name(agent_name, pid_file.identity)
359
+ if pid = pid_file.read_pid[:pid]
360
+ begin
361
+ Process.kill('TERM', pid)
362
+ res = true
363
+ puts "#{name} stopped"
364
+ rescue Errno::ESRCH
365
+ puts "#{name} not running"
366
+ end
367
+ elsif File.file?(pid_file.to_s)
368
+ puts "Invalid pid file '#{pid_file.to_s}' content: #{IO.read(pid_file.to_s)}"
369
+ else
370
+ puts "#{name} not running"
371
+ end
372
+ else
373
+ puts "Non-existent pid file for #{agent_name}"
374
+ end
375
+ res
376
+ end
377
+
378
+ # Show status of agent
379
+ #
380
+ # === Parameters
381
+ # agent_name(String):: Agent name
382
+ #
383
+ # === Return
384
+ # (Boolean):: true if process is running, otherwise false
385
+ def show_agent(agent_name)
386
+ res = false
387
+ if (pid_file = AgentConfig.pid_file(agent_name)) && (pid = pid_file.read_pid[:pid])
388
+ pgid = Process.getpgid(pid) rescue -1
389
+ name = human_readable_name(agent_name, pid_file.identity)
390
+ if pgid != -1
391
+ psdata = `ps up #{pid}`.split("\n").last.split
392
+ memory = (psdata[5].to_i / 1024)
393
+ puts "#{name} is alive, using #{memory}MB of memory"
394
+ res = true
395
+ else
396
+ puts "#{name} is not running but has a stale pid file at #{pid_file}"
397
+ end
398
+ elsif identity = AgentConfig.agent_options(agent_name)[:identity]
399
+ puts "#{human_readable_name(agent_name, identity)} is not running"
400
+ end
401
+ res
402
+ end
403
+
404
+ # Generate human readable name for agent
405
+ #
406
+ # === Return
407
+ # (String):: Human readable name
408
+ def human_readable_name(agent_name = nil, identity = nil)
409
+ agent_name ||= @options[:agent_name]
410
+ "Agent #{agent_name + ' ' if agent_name}with ID #{identity || @options[:identity]}"
411
+ end
412
+
413
+ # List all configured agents
414
+ #
415
+ # === Return
416
+ # never
417
+ def list_configured_agents
418
+ agents = AgentConfig.cfg_agents
419
+ if agents.empty?
420
+ puts "Found no configured agents"
421
+ else
422
+ puts "Configured agents:"
423
+ agents.each { |a| puts " - #{a}" }
424
+ end
425
+ exit
426
+ end
427
+
428
+ # Determine syslog program name based on options
429
+ #
430
+ # === Parameters
431
+ # options(Hash):: Command line options
432
+ #
433
+ # === Return
434
+ # (String):: Program name
435
+ def syslog_program_name(options)
436
+ 'RightAgent'
437
+ end
438
+
439
+ # Determine configuration settings for this agent and persist them if needed
440
+ # Reuse existing agent identity when possible
441
+ #
442
+ # === Parameters
443
+ # action(String):: Requested action
444
+ # options(Hash):: Command line options
445
+ #
446
+ # === Return
447
+ # cfg(Hash):: Persisted configuration options
448
+ def configure_agent(action, options)
449
+ agent_type = options[:agent_type]
450
+ agent_name = options[:agent_name]
451
+ if agent_name != agent_type && cfg = AgentConfig.load_cfg(agent_type)
452
+ base_id = (options[:base_id] || AgentIdentity.parse(cfg[:identity]).base_id.to_s).to_i
453
+ unless (identity = AgentConfig.agent_options(agent_name)[:identity]) &&
454
+ AgentIdentity.parse(identity).base_id == base_id
455
+ identity = AgentIdentity.new(options[:prefix] || 'rs', options[:agent_type], base_id, options[:token]).to_s
456
+ end
457
+ cfg.merge!(:identity => identity)
458
+ cfg_file = AgentConfig.store_cfg(agent_name, cfg)
459
+ puts "Generated configuration file for #{agent_name} agent: #{cfg_file}"
460
+ elsif !(cfg = AgentConfig.load_cfg(agent_name))
461
+ fail("Deployment is missing configuration file #{AgentConfig.cfg_file(agent_name).inspect}")
462
+ end
463
+ cfg
464
+ end
465
+
466
+ # Enable the use of an HTTP proxy for this process and its subprocesses
467
+ #
468
+ # === Parameters
469
+ # proxy_setting(String):: Proxy to use
470
+ # exceptions(String):: Comma-separated list of proxy exceptions (e.g. metadata server)
471
+ #
472
+ # === Return
473
+ # true:: Always return true
474
+ def configure_proxy(proxy_setting, exceptions)
475
+ ENV['HTTP_PROXY'] = proxy_setting
476
+ ENV['http_proxy'] = proxy_setting
477
+ ENV['HTTPS_PROXY'] = proxy_setting
478
+ ENV['https_proxy'] = proxy_setting
479
+ ENV['NO_PROXY'] = exceptions
480
+ ENV['no_proxy'] = exceptions
481
+ true
482
+ end
483
+
484
+ # Print error on console and exit abnormally
485
+ #
486
+ # === Parameters
487
+ # message(String):: Error message to be displayed
488
+ # print_usage(Boolean):: Whether to display usage information
489
+ #
490
+ # === Return
491
+ # never
492
+ def fail(message, print_usage = false)
493
+ puts "** #{message}"
494
+ puts Usage.scan(__FILE__) if print_usage
495
+ exit(1)
496
+ end
497
+
498
+ end # AgentController
499
+
500
+ end # RightScale
501
+
502
+ #
503
+ # Copyright (c) 2009-2011 RightScale Inc
504
+ #
505
+ # Permission is hereby granted, free of charge, to any person obtaining
506
+ # a copy of this software and associated documentation files (the
507
+ # "Software"), to deal in the Software without restriction, including
508
+ # without limitation the rights to use, copy, modify, merge, publish,
509
+ # distribute, sublicense, and/or sell copies of the Software, and to
510
+ # permit persons to whom the Software is furnished to do so, subject to
511
+ # the following conditions:
512
+ #
513
+ # The above copyright notice and this permission notice shall be
514
+ # included in all copies or substantial portions of the Software.
515
+ #
516
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
517
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
518
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
519
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
520
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
521
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
522
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.