right_agent 2.0.7-x86-mingw32
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.
- data/LICENSE +20 -0
- data/README.rdoc +82 -0
- data/Rakefile +113 -0
- data/lib/right_agent.rb +59 -0
- data/lib/right_agent/actor.rb +182 -0
- data/lib/right_agent/actor_registry.rb +76 -0
- data/lib/right_agent/actors/agent_manager.rb +232 -0
- data/lib/right_agent/agent.rb +1149 -0
- data/lib/right_agent/agent_config.rb +480 -0
- data/lib/right_agent/agent_identity.rb +210 -0
- data/lib/right_agent/agent_tag_manager.rb +237 -0
- data/lib/right_agent/audit_formatter.rb +107 -0
- data/lib/right_agent/clients.rb +31 -0
- data/lib/right_agent/clients/api_client.rb +383 -0
- data/lib/right_agent/clients/auth_client.rb +247 -0
- data/lib/right_agent/clients/balanced_http_client.rb +369 -0
- data/lib/right_agent/clients/base_retry_client.rb +495 -0
- data/lib/right_agent/clients/right_http_client.rb +279 -0
- data/lib/right_agent/clients/router_client.rb +493 -0
- data/lib/right_agent/command.rb +30 -0
- data/lib/right_agent/command/agent_manager_commands.rb +150 -0
- data/lib/right_agent/command/command_client.rb +136 -0
- data/lib/right_agent/command/command_constants.rb +33 -0
- data/lib/right_agent/command/command_io.rb +126 -0
- data/lib/right_agent/command/command_parser.rb +87 -0
- data/lib/right_agent/command/command_runner.rb +118 -0
- data/lib/right_agent/command/command_serializer.rb +63 -0
- data/lib/right_agent/connectivity_checker.rb +179 -0
- data/lib/right_agent/console.rb +65 -0
- data/lib/right_agent/core_payload_types.rb +44 -0
- data/lib/right_agent/core_payload_types/cookbook.rb +61 -0
- data/lib/right_agent/core_payload_types/cookbook_position.rb +46 -0
- data/lib/right_agent/core_payload_types/cookbook_repository.rb +116 -0
- data/lib/right_agent/core_payload_types/cookbook_sequence.rb +70 -0
- data/lib/right_agent/core_payload_types/dev_repositories.rb +100 -0
- data/lib/right_agent/core_payload_types/dev_repository.rb +76 -0
- data/lib/right_agent/core_payload_types/event_categories.rb +38 -0
- data/lib/right_agent/core_payload_types/executable_bundle.rb +130 -0
- data/lib/right_agent/core_payload_types/login_policy.rb +72 -0
- data/lib/right_agent/core_payload_types/login_user.rb +79 -0
- data/lib/right_agent/core_payload_types/planned_volume.rb +94 -0
- data/lib/right_agent/core_payload_types/recipe_instantiation.rb +73 -0
- data/lib/right_agent/core_payload_types/repositories_bundle.rb +50 -0
- data/lib/right_agent/core_payload_types/right_script_attachment.rb +95 -0
- data/lib/right_agent/core_payload_types/right_script_instantiation.rb +94 -0
- data/lib/right_agent/core_payload_types/runlist_policy.rb +44 -0
- data/lib/right_agent/core_payload_types/secure_document.rb +66 -0
- data/lib/right_agent/core_payload_types/secure_document_location.rb +63 -0
- data/lib/right_agent/core_payload_types/software_repository_instantiation.rb +61 -0
- data/lib/right_agent/daemonize.rb +35 -0
- data/lib/right_agent/dispatched_cache.rb +109 -0
- data/lib/right_agent/dispatcher.rb +272 -0
- data/lib/right_agent/enrollment_result.rb +221 -0
- data/lib/right_agent/exceptions.rb +87 -0
- data/lib/right_agent/history.rb +145 -0
- data/lib/right_agent/log.rb +460 -0
- data/lib/right_agent/minimal.rb +46 -0
- data/lib/right_agent/monkey_patches.rb +30 -0
- data/lib/right_agent/monkey_patches/ruby_patch.rb +55 -0
- data/lib/right_agent/monkey_patches/ruby_patch/array_patch.rb +29 -0
- data/lib/right_agent/monkey_patches/ruby_patch/darwin_patch.rb +24 -0
- data/lib/right_agent/monkey_patches/ruby_patch/linux_patch.rb +24 -0
- data/lib/right_agent/monkey_patches/ruby_patch/linux_patch/file_patch.rb +30 -0
- data/lib/right_agent/monkey_patches/ruby_patch/object_patch.rb +49 -0
- data/lib/right_agent/monkey_patches/ruby_patch/windows_patch.rb +32 -0
- data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/file_patch.rb +60 -0
- data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/process_patch.rb +63 -0
- data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/stdio_patch.rb +27 -0
- data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/time_patch.rb +55 -0
- data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/win32ole_patch.rb +34 -0
- data/lib/right_agent/multiplexer.rb +102 -0
- data/lib/right_agent/offline_handler.rb +270 -0
- data/lib/right_agent/operation_result.rb +300 -0
- data/lib/right_agent/packets.rb +673 -0
- data/lib/right_agent/payload_formatter.rb +104 -0
- data/lib/right_agent/pending_requests.rb +128 -0
- data/lib/right_agent/pid_file.rb +159 -0
- data/lib/right_agent/platform.rb +770 -0
- data/lib/right_agent/platform/unix/darwin/platform.rb +102 -0
- data/lib/right_agent/platform/unix/linux/platform.rb +305 -0
- data/lib/right_agent/platform/unix/platform.rb +226 -0
- data/lib/right_agent/platform/windows/mingw/platform.rb +447 -0
- data/lib/right_agent/platform/windows/mswin/platform.rb +236 -0
- data/lib/right_agent/platform/windows/platform.rb +1808 -0
- data/lib/right_agent/protocol_version_mixin.rb +69 -0
- data/lib/right_agent/retryable_request.rb +195 -0
- data/lib/right_agent/scripts/agent_controller.rb +543 -0
- data/lib/right_agent/scripts/agent_deployer.rb +400 -0
- data/lib/right_agent/scripts/common_parser.rb +160 -0
- data/lib/right_agent/scripts/log_level_manager.rb +192 -0
- data/lib/right_agent/scripts/stats_manager.rb +268 -0
- data/lib/right_agent/scripts/usage.rb +58 -0
- data/lib/right_agent/secure_identity.rb +92 -0
- data/lib/right_agent/security.rb +32 -0
- data/lib/right_agent/security/cached_certificate_store_proxy.rb +77 -0
- data/lib/right_agent/security/certificate.rb +102 -0
- data/lib/right_agent/security/certificate_cache.rb +89 -0
- data/lib/right_agent/security/distinguished_name.rb +56 -0
- data/lib/right_agent/security/encrypted_document.rb +83 -0
- data/lib/right_agent/security/rsa_key_pair.rb +76 -0
- data/lib/right_agent/security/signature.rb +86 -0
- data/lib/right_agent/security/static_certificate_store.rb +85 -0
- data/lib/right_agent/sender.rb +792 -0
- data/lib/right_agent/serialize.rb +29 -0
- data/lib/right_agent/serialize/message_pack.rb +107 -0
- data/lib/right_agent/serialize/secure_serializer.rb +151 -0
- data/lib/right_agent/serialize/secure_serializer_initializer.rb +47 -0
- data/lib/right_agent/serialize/serializable.rb +151 -0
- data/lib/right_agent/serialize/serializer.rb +159 -0
- data/lib/right_agent/subprocess.rb +38 -0
- data/lib/right_agent/tracer.rb +124 -0
- data/right_agent.gemspec +101 -0
- data/spec/actor_registry_spec.rb +80 -0
- data/spec/actor_spec.rb +162 -0
- data/spec/agent_config_spec.rb +235 -0
- data/spec/agent_identity_spec.rb +78 -0
- data/spec/agent_spec.rb +734 -0
- data/spec/agent_tag_manager_spec.rb +319 -0
- data/spec/clients/api_client_spec.rb +423 -0
- data/spec/clients/auth_client_spec.rb +272 -0
- data/spec/clients/balanced_http_client_spec.rb +576 -0
- data/spec/clients/base_retry_client_spec.rb +635 -0
- data/spec/clients/router_client_spec.rb +594 -0
- data/spec/clients/spec_helper.rb +111 -0
- data/spec/command/agent_manager_commands_spec.rb +51 -0
- data/spec/command/command_io_spec.rb +93 -0
- data/spec/command/command_parser_spec.rb +79 -0
- data/spec/command/command_runner_spec.rb +107 -0
- data/spec/command/command_serializer_spec.rb +51 -0
- data/spec/connectivity_checker_spec.rb +83 -0
- data/spec/core_payload_types/dev_repositories_spec.rb +64 -0
- data/spec/core_payload_types/dev_repository_spec.rb +33 -0
- data/spec/core_payload_types/executable_bundle_spec.rb +67 -0
- data/spec/core_payload_types/login_user_spec.rb +102 -0
- data/spec/core_payload_types/recipe_instantiation_spec.rb +81 -0
- data/spec/core_payload_types/right_script_attachment_spec.rb +65 -0
- data/spec/core_payload_types/right_script_instantiation_spec.rb +79 -0
- data/spec/core_payload_types/spec_helper.rb +23 -0
- data/spec/dispatched_cache_spec.rb +136 -0
- data/spec/dispatcher_spec.rb +324 -0
- data/spec/enrollment_result_spec.rb +53 -0
- data/spec/history_spec.rb +246 -0
- data/spec/log_spec.rb +192 -0
- data/spec/monkey_patches/eventmachine_spec.rb +62 -0
- data/spec/multiplexer_spec.rb +48 -0
- data/spec/offline_handler_spec.rb +340 -0
- data/spec/operation_result_spec.rb +208 -0
- data/spec/packets_spec.rb +461 -0
- data/spec/pending_requests_spec.rb +136 -0
- data/spec/platform/spec_helper.rb +216 -0
- data/spec/platform/unix/darwin/platform_spec.rb +181 -0
- data/spec/platform/unix/linux/platform_spec.rb +540 -0
- data/spec/platform/unix/spec_helper.rb +149 -0
- data/spec/platform/windows/mingw/platform_spec.rb +222 -0
- data/spec/platform/windows/mswin/platform_spec.rb +259 -0
- data/spec/platform/windows/spec_helper.rb +720 -0
- data/spec/retryable_request_spec.rb +306 -0
- data/spec/secure_identity_spec.rb +50 -0
- data/spec/security/cached_certificate_store_proxy_spec.rb +62 -0
- data/spec/security/certificate_cache_spec.rb +71 -0
- data/spec/security/certificate_spec.rb +49 -0
- data/spec/security/distinguished_name_spec.rb +46 -0
- data/spec/security/encrypted_document_spec.rb +55 -0
- data/spec/security/rsa_key_pair_spec.rb +55 -0
- data/spec/security/signature_spec.rb +66 -0
- data/spec/security/static_certificate_store_spec.rb +58 -0
- data/spec/sender_spec.rb +1045 -0
- data/spec/serialize/message_pack_spec.rb +131 -0
- data/spec/serialize/secure_serializer_spec.rb +132 -0
- data/spec/serialize/serializable_spec.rb +90 -0
- data/spec/serialize/serializer_spec.rb +197 -0
- data/spec/spec.opts +2 -0
- data/spec/spec.win32.opts +1 -0
- data/spec/spec_helper.rb +130 -0
- data/spec/tracer_spec.rb +114 -0
- metadata +447 -0
@@ -0,0 +1,69 @@
|
|
1
|
+
##
|
2
|
+
# Copyright (c) 2014 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
|
+
# Mixin for testing for availability of features in agents based on protocol version
|
26
|
+
module ProtocolVersionMixin
|
27
|
+
|
28
|
+
# Mix this module into its own eigenclass to make the module-instance methods
|
29
|
+
# become callable as module methods
|
30
|
+
extend self
|
31
|
+
|
32
|
+
# Test whether given version of agent has the protocol version embedded in each
|
33
|
+
# packet (this is generally inferred by the version in the received packet not being
|
34
|
+
# Packet::DEFAULT_VERSION, which is true of all with version >= 12)
|
35
|
+
def can_put_version_in_packet?(version); version && version != 0 end
|
36
|
+
|
37
|
+
# Test whether given version of agent uses /mapper/query_tags rather than the
|
38
|
+
# deprecated TagQuery packet
|
39
|
+
def can_use_mapper_query_tags?(version); version && version >= 8 end
|
40
|
+
|
41
|
+
# Test whether given version of agent can handle a request that is being retried
|
42
|
+
# as indicated by a retries count in the Request packet
|
43
|
+
def can_handle_request_retries?(version); version && version >= 9 end
|
44
|
+
|
45
|
+
# Test whether given version of agent can handle serialized identity and queue name
|
46
|
+
# that does not incorporate 'nanite'
|
47
|
+
def can_handle_non_nanite_ids?(version); version && version >= 10 end
|
48
|
+
|
49
|
+
# Test whether given version of agent supports routing results to mapper response queue
|
50
|
+
# rather than to the identity queue of the mapper that routed the request
|
51
|
+
def can_route_to_response_queue?(version); version && version >= 10 end
|
52
|
+
|
53
|
+
# Test whether given version of agent can handle receipt of a result containing an
|
54
|
+
# OperationResult with MULTICAST status
|
55
|
+
def can_handle_multicast_result?(version); version && [10, 11].include?(version) end
|
56
|
+
|
57
|
+
# Test whether given version of agent can handle msgpack encoding
|
58
|
+
def can_handle_msgpack_result?(version); version && version >= 12 end
|
59
|
+
|
60
|
+
# Test whether given version of agent can handle receipt of a result containing an
|
61
|
+
# OperationResult with NON_DELIVERY status
|
62
|
+
def can_handle_non_delivery_result?(version); version && version >= 13 end
|
63
|
+
|
64
|
+
# Test whether given version of agent can handle HTTP communication mode
|
65
|
+
def can_handle_http?(version); version && version >= 23 end
|
66
|
+
|
67
|
+
end # ProtocolVersionMixin
|
68
|
+
|
69
|
+
end # RightScale
|
@@ -0,0 +1,195 @@
|
|
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
|
+
# This is a retryable request for use when the execution of the request by the
|
26
|
+
# receiver is known to be idempotent and when there is a need to indefinitely
|
27
|
+
# pursue getting a usable response, e.g., when an instance is launching.
|
28
|
+
# It is implemented as an EM::Deferrable and as such invokes the Proc defined
|
29
|
+
# with its #callback method with the result content from a OperationResult::SUCCESS
|
30
|
+
# response, or it will invoke the Proc defined with its #errback method with error
|
31
|
+
# content if the response is an OperationResult::ERROR or CANCEL, or if the request
|
32
|
+
# has timed out. The request can be canceled with the #cancel method, or the receiver
|
33
|
+
# of the request may respond with a CANCEL result to cause the request to be canceled.
|
34
|
+
# This is useful in situations where the request is never expected to succeed
|
35
|
+
# regardless of the number of retries. By default if the response to the request
|
36
|
+
# is an OperationResult::RETRY or NON_DELIVERY indication, the request is automatically
|
37
|
+
# retried, as is also the case for an ERROR indication if the :retry_on_error option
|
38
|
+
# is specified. The retry algorithm is controlled by the :retry_delay, :retry_delay_count,
|
39
|
+
# and :max_retry_delay settings. The initial retry interval is the default or specified
|
40
|
+
# :retry_delay and this interval is used :retry_delay_count times, at which point the
|
41
|
+
# :retry_delay is doubled and the :retry_delay_count is halved. This backoff is again
|
42
|
+
# applied after the new :retry_delay_count is reached, and so on until :retry_delay
|
43
|
+
# reaches :max_retry_delay which then is used as the interval until the default or
|
44
|
+
# specified :timeout is reached. The default :timeout is 4 days.
|
45
|
+
class RetryableRequest
|
46
|
+
|
47
|
+
include OperationResultHelper
|
48
|
+
include EM::Deferrable
|
49
|
+
|
50
|
+
# Default delay before initial retry in case of failure with -1 meaning no delay
|
51
|
+
DEFAULT_RETRY_DELAY = 5
|
52
|
+
|
53
|
+
# Default minimum number of retries before beginning backoff
|
54
|
+
DEFAULT_RETRY_DELAY_COUNT = 60
|
55
|
+
|
56
|
+
# Maximum default delay before retry when backing off
|
57
|
+
DEFAULT_MAX_RETRY_DELAY = 60
|
58
|
+
|
59
|
+
# Factor used for exponential backoff of retry delay
|
60
|
+
RETRY_BACKOFF_FACTOR = 2
|
61
|
+
|
62
|
+
# Default timeout with -1 meaning never timeout
|
63
|
+
DEFAULT_TIMEOUT = 4 * 24 * 60 * 60
|
64
|
+
|
65
|
+
attr_reader :raw_response
|
66
|
+
|
67
|
+
# Send idempotent request
|
68
|
+
# Retry until timeout is reached (indefinitely if timeout <= 0)
|
69
|
+
# Calls deferrable callback on completion, error callback on timeout
|
70
|
+
#
|
71
|
+
# === Parameters
|
72
|
+
# operation(String):: Request operation (e.g., '/booter/get_boot_bundle')
|
73
|
+
# payload(Hash):: Request payload
|
74
|
+
# options(Hash):: Request options
|
75
|
+
# :targets(Array):: Target agent identities from which to randomly choose one
|
76
|
+
# :retry_on_error(Boolean):: Whether request should be retried if recipient returned an error
|
77
|
+
# :retry_delay(Fixnum):: Number of seconds delay before initial retry with -1 meaning no delay,
|
78
|
+
# defaults to DEFAULT_RETRY_DELAY
|
79
|
+
# :retry_delay_count(Fixnum):: Minimum number of retries at initial :retry_delay value before
|
80
|
+
# increasing delay exponentially and decreasing this count exponentially, defaults to
|
81
|
+
# DEFAULT_RETRY_DELAY_COUNT
|
82
|
+
# :max_retry_delay(Fixnum):: Maximum number of seconds of retry delay, defaults to DEFAULT_MAX_RETRY_DELAY
|
83
|
+
# :timeout(Fixnum):: Number of seconds with no response before error callback gets called, with
|
84
|
+
# -1 meaning never, defaults to DEFAULT_TIMEOUT
|
85
|
+
#
|
86
|
+
# === Raises
|
87
|
+
# ArgumentError:: If operation or payload not specified
|
88
|
+
def initialize(operation, payload, options = {})
|
89
|
+
raise ArgumentError.new("operation is required") unless (@operation = operation)
|
90
|
+
raise ArgumentError.new("payload is required") unless (@payload = payload)
|
91
|
+
@retry_on_error = options[:retry_on_error] || false
|
92
|
+
@timeout = options[:timeout] || DEFAULT_TIMEOUT
|
93
|
+
@retry_delay = options[:retry_delay] || DEFAULT_RETRY_DELAY
|
94
|
+
@retry_delay_count = options[:retry_delay_count] || DEFAULT_RETRY_DELAY_COUNT
|
95
|
+
@max_retry_delay = options[:max_retry_delay] || DEFAULT_MAX_RETRY_DELAY
|
96
|
+
@retries = 0
|
97
|
+
@targets = options[:targets]
|
98
|
+
@raw_response = nil
|
99
|
+
@done = false
|
100
|
+
end
|
101
|
+
|
102
|
+
# Send request and retry until timeout is reached or response is received
|
103
|
+
# Ignore duplicate responses
|
104
|
+
#
|
105
|
+
# === Return
|
106
|
+
# true:: Always return true
|
107
|
+
def run
|
108
|
+
Sender.instance.send_request(@operation, @payload, retrieve_target(@targets)) { |r| handle_response(r) }
|
109
|
+
if @cancel_timer.nil? && @timeout > 0
|
110
|
+
@cancel_timer = EM::Timer.new(@timeout) do
|
111
|
+
msg = "Request #{@operation} timed out after #{@timeout} seconds"
|
112
|
+
Log.info(msg)
|
113
|
+
cancel(msg)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
true
|
117
|
+
end
|
118
|
+
|
119
|
+
# Cancel request and call error callback
|
120
|
+
#
|
121
|
+
# === Parameters
|
122
|
+
# msg(String):: Reason why request is cancelled, given to error callback
|
123
|
+
#
|
124
|
+
# === Return
|
125
|
+
# true:: Always return true
|
126
|
+
def cancel(msg)
|
127
|
+
if @cancel_timer
|
128
|
+
@cancel_timer.cancel
|
129
|
+
@cancel_timer = nil
|
130
|
+
end
|
131
|
+
@done = true
|
132
|
+
fail(msg)
|
133
|
+
true
|
134
|
+
end
|
135
|
+
|
136
|
+
protected
|
137
|
+
|
138
|
+
# Process request response and retry if needed
|
139
|
+
#
|
140
|
+
# === Parameters
|
141
|
+
# r(Result):: Request result
|
142
|
+
#
|
143
|
+
# === Return
|
144
|
+
# true:: Always return true
|
145
|
+
def handle_response(r)
|
146
|
+
return true if @done
|
147
|
+
@raw_response = r
|
148
|
+
res = result_from(r)
|
149
|
+
if res.success?
|
150
|
+
if @cancel_timer
|
151
|
+
@cancel_timer.cancel
|
152
|
+
@cancel_timer = nil
|
153
|
+
end
|
154
|
+
@done = true
|
155
|
+
succeed(res.content)
|
156
|
+
else
|
157
|
+
reason = res.content
|
158
|
+
if res.non_delivery?
|
159
|
+
Log.info("Request non-delivery (#{reason}) for #{@operation}")
|
160
|
+
elsif res.retry?
|
161
|
+
reason = (reason && !reason.empty?) ? reason : "RightScale not ready"
|
162
|
+
Log.info("Request #{@operation} failed (#{reason}) and should be retried")
|
163
|
+
elsif res.cancel?
|
164
|
+
reason = (reason && !reason.empty?) ? reason : "RightScale cannot execute request"
|
165
|
+
Log.info("Request #{@operation} canceled (#{reason})")
|
166
|
+
else
|
167
|
+
Log.info("Request #{@operation} failed (#{reason})")
|
168
|
+
end
|
169
|
+
if (res.non_delivery? || res.retry? || @retry_on_error) && !res.cancel?
|
170
|
+
Log.info("Retrying in #{@retry_delay} seconds...")
|
171
|
+
if @retry_delay > 0
|
172
|
+
this_delay = @retry_delay
|
173
|
+
if (@retries += 1) >= @retry_delay_count
|
174
|
+
@retry_delay = [@retry_delay * RETRY_BACKOFF_FACTOR, @max_retry_delay].min
|
175
|
+
@retry_delay_count = [@retry_delay_count / RETRY_BACKOFF_FACTOR, 1].max
|
176
|
+
@retries = 0
|
177
|
+
end
|
178
|
+
EM.add_timer(this_delay) { run }
|
179
|
+
else
|
180
|
+
EM.next_tick { run }
|
181
|
+
end
|
182
|
+
else
|
183
|
+
cancel(res.content)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
true
|
187
|
+
end
|
188
|
+
|
189
|
+
def retrieve_target(targets)
|
190
|
+
{:agent_id => targets[rand(0xffff) % targets.size]} if targets && targets.any?
|
191
|
+
end
|
192
|
+
|
193
|
+
end # RetryableRequest
|
194
|
+
|
195
|
+
end # RightScale
|
@@ -0,0 +1,543 @@
|
|
1
|
+
# === Synopsis:
|
2
|
+
# RightScale RightAgent Controller (rnac) - (c) 2009-2012 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 this as base ID to build agent's identity
|
55
|
+
# --token, -t TOKEN Use this token to build agent's identity with it plugging
|
56
|
+
# directly in unless --secure-identity is specified
|
57
|
+
# --secure-identity, -S Derive token used in agent identity from given TOKEN and ID
|
58
|
+
# --prefix, -x PREFIX Use this prefix to build agent's identity
|
59
|
+
# --type TYPE Use this agent type to build agent's' identity;
|
60
|
+
# defaults to AGENT with any trailing '_[0-9]+' removed
|
61
|
+
# --list, -l List all configured agents
|
62
|
+
# --user, -u USER Set AMQP user
|
63
|
+
# --pass, -p PASS Set AMQP password
|
64
|
+
# --vhost, -v VHOST Set AMQP vhost
|
65
|
+
# --host, -h HOST Set AMQP server hostname
|
66
|
+
# --port, -P PORT Set AMQP server port
|
67
|
+
# --cfg-dir, -c DIR Set directory containing configuration for all agents
|
68
|
+
# --pid-dir, -z DIR Set directory containing agent process id files
|
69
|
+
# --log-dir DIR Set log directory
|
70
|
+
# --log-level LVL Log level (debug, info, warning, error or fatal)
|
71
|
+
# --foreground, -f Run agent in foreground
|
72
|
+
# --interactive, -I Spawn an irb console after starting agent
|
73
|
+
# --test Use test settings
|
74
|
+
# --help Display help
|
75
|
+
|
76
|
+
require 'rubygems'
|
77
|
+
require 'optparse'
|
78
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'minimal'))
|
79
|
+
require File.normalize_path(File.join(File.dirname(__FILE__), 'usage'))
|
80
|
+
require File.normalize_path(File.join(File.dirname(__FILE__), 'common_parser'))
|
81
|
+
|
82
|
+
module RightScale
|
83
|
+
|
84
|
+
class AgentController
|
85
|
+
|
86
|
+
include CommonParser
|
87
|
+
|
88
|
+
FORCED_OPTIONS =
|
89
|
+
{
|
90
|
+
}
|
91
|
+
|
92
|
+
DEFAULT_OPTIONS =
|
93
|
+
{
|
94
|
+
:log_dir => Platform.filesystem.log_dir,
|
95
|
+
:daemonize => true
|
96
|
+
}
|
97
|
+
|
98
|
+
@@agent = nil
|
99
|
+
|
100
|
+
# Create and run controller
|
101
|
+
#
|
102
|
+
# === Return
|
103
|
+
# true:: Always return true
|
104
|
+
def self.run
|
105
|
+
c = AgentController.new
|
106
|
+
c.control(c.parse_args)
|
107
|
+
end
|
108
|
+
|
109
|
+
# Parse arguments and execute request
|
110
|
+
#
|
111
|
+
# === Parameters
|
112
|
+
# options(Hash):: Command line options
|
113
|
+
#
|
114
|
+
# === Return
|
115
|
+
# true:: Always return true
|
116
|
+
def control(options)
|
117
|
+
|
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.facility = syslog_facility(options)
|
144
|
+
Log.log_to_file_only(options[:log_to_file_only])
|
145
|
+
configure_proxy(options[:http_proxy], options[:http_no_proxy]) if options[:http_proxy]
|
146
|
+
elsif options[:identity]
|
147
|
+
options[:agent_name] = AgentConfig.agent_name(options[:identity])
|
148
|
+
end
|
149
|
+
@options = DEFAULT_OPTIONS.clone.merge(options.merge(FORCED_OPTIONS))
|
150
|
+
FileUtils.mkdir_p(@options[:pid_dir]) unless @options[:pid_dir].nil? || File.directory?(@options[:pid_dir])
|
151
|
+
|
152
|
+
# Execute request
|
153
|
+
success = case action
|
154
|
+
when /show|killall/
|
155
|
+
action = 'stop' if action == 'killall'
|
156
|
+
s = true
|
157
|
+
AgentConfig.cfg_agents.each { |agent_name| s &&= dispatch(action, agent_name) }
|
158
|
+
s
|
159
|
+
when 'kill'
|
160
|
+
kill_process
|
161
|
+
else
|
162
|
+
dispatch(action, @options[:agent_name])
|
163
|
+
end
|
164
|
+
|
165
|
+
exit(1) unless success
|
166
|
+
end
|
167
|
+
|
168
|
+
# Create options hash from command line arguments
|
169
|
+
#
|
170
|
+
# === Return
|
171
|
+
# options(Hash):: Parsed options
|
172
|
+
def parse_args
|
173
|
+
options = {:thin_command_client => false}
|
174
|
+
|
175
|
+
opts = OptionParser.new do |opts|
|
176
|
+
parse_common(opts, options)
|
177
|
+
parse_other_args(opts, options)
|
178
|
+
|
179
|
+
opts.on("-s", "--start AGENT") do |a|
|
180
|
+
options[:action] = 'start'
|
181
|
+
options[:agent_name] = a
|
182
|
+
end
|
183
|
+
|
184
|
+
opts.on("-p", "--stop AGENT") do |a|
|
185
|
+
options[:action] = 'stop'
|
186
|
+
options[:agent_name] = a
|
187
|
+
end
|
188
|
+
|
189
|
+
opts.on("--stop-agent ID") do |id|
|
190
|
+
options[:action] = 'stop'
|
191
|
+
options[:identity] = id
|
192
|
+
end
|
193
|
+
|
194
|
+
opts.on("-k", "--kill PIDFILE") do |file|
|
195
|
+
options[:pid_file] = file
|
196
|
+
options[:action] = 'kill'
|
197
|
+
end
|
198
|
+
|
199
|
+
opts.on("-K", "--killall") do
|
200
|
+
options[:action] = 'killall'
|
201
|
+
end
|
202
|
+
|
203
|
+
opts.on("-U", "--status") do
|
204
|
+
options[:action] = 'show'
|
205
|
+
end
|
206
|
+
|
207
|
+
opts.on("-l", "--list") do
|
208
|
+
options[:list] = true
|
209
|
+
end
|
210
|
+
|
211
|
+
opts.on("--log-level LVL") do |lvl|
|
212
|
+
options[:log_level] = lvl
|
213
|
+
end
|
214
|
+
|
215
|
+
opts.on("-c", "--cfg-dir DIR") do |d|
|
216
|
+
options[:cfg_dir] = d
|
217
|
+
end
|
218
|
+
|
219
|
+
opts.on("-z", "--pid-dir DIR") do |dir|
|
220
|
+
options[:pid_dir] = dir
|
221
|
+
end
|
222
|
+
|
223
|
+
opts.on("--log-dir DIR") do |dir|
|
224
|
+
options[:log_dir] = dir
|
225
|
+
|
226
|
+
# Ensure log directory exists (for windows, etc.)
|
227
|
+
FileUtils.mkdir_p(dir) unless File.directory?(dir)
|
228
|
+
end
|
229
|
+
|
230
|
+
opts.on("-f", "--foreground") do
|
231
|
+
options[:daemonize] = false
|
232
|
+
#Squelch Ruby VM warnings about various things
|
233
|
+
$VERBOSE = nil
|
234
|
+
end
|
235
|
+
|
236
|
+
opts.on("-I", "--interactive") do
|
237
|
+
options[:console] = true
|
238
|
+
end
|
239
|
+
|
240
|
+
opts.on_tail("--help") do
|
241
|
+
puts Usage.scan(__FILE__)
|
242
|
+
exit
|
243
|
+
end
|
244
|
+
|
245
|
+
end
|
246
|
+
|
247
|
+
begin
|
248
|
+
opts.parse(ARGV)
|
249
|
+
rescue Exception => e
|
250
|
+
exit 0 if e.is_a?(SystemExit)
|
251
|
+
fail(e.message, print_usage = true)
|
252
|
+
end
|
253
|
+
|
254
|
+
# allow specific arguments to use a thin command client for faster
|
255
|
+
# execution (on Windows, etc.)
|
256
|
+
unless options[:thin_command_client]
|
257
|
+
# require full right_agent for any commands which do not specify thin
|
258
|
+
# command client.
|
259
|
+
require File.normalize_path(File.join(File.dirname(__FILE__), '..', '..', 'right_agent'))
|
260
|
+
end
|
261
|
+
resolve_identity(options)
|
262
|
+
options
|
263
|
+
end
|
264
|
+
|
265
|
+
protected
|
266
|
+
|
267
|
+
# Parse any other arguments used by agent
|
268
|
+
#
|
269
|
+
# === Parameters
|
270
|
+
# opts(OptionParser):: Options parser with options to be parsed
|
271
|
+
# options(Hash):: Storage for options that are parsed
|
272
|
+
#
|
273
|
+
# === Return
|
274
|
+
# true:: Always return true
|
275
|
+
def parse_other_args(opts, options)
|
276
|
+
true
|
277
|
+
end
|
278
|
+
|
279
|
+
# Dispatch action
|
280
|
+
#
|
281
|
+
# === Parameters
|
282
|
+
# action(String):: Action to be performed
|
283
|
+
# agent_name(String):: Agent name
|
284
|
+
#
|
285
|
+
# === Return
|
286
|
+
# true:: Always return true
|
287
|
+
def dispatch(action, agent_name)
|
288
|
+
# Setup the environment from config if necessary
|
289
|
+
begin
|
290
|
+
eval("#{action}_agent(agent_name)")
|
291
|
+
rescue SystemExit
|
292
|
+
true
|
293
|
+
rescue SignalException
|
294
|
+
true
|
295
|
+
rescue Exception => e
|
296
|
+
puts Log.format("Failed to #{action} #{agent_name}", e, :trace)
|
297
|
+
end
|
298
|
+
true
|
299
|
+
end
|
300
|
+
|
301
|
+
# Kill process defined in pid file
|
302
|
+
#
|
303
|
+
# === Parameters
|
304
|
+
# sig(String):: Signal to be used for kill
|
305
|
+
#
|
306
|
+
# === Return
|
307
|
+
# true:: Always return true
|
308
|
+
def kill_process(sig = 'TERM')
|
309
|
+
content = IO.read(@options[:pid_file])
|
310
|
+
pid = content.to_i
|
311
|
+
fail("Invalid pid file content #{content.inspect}") if pid == 0
|
312
|
+
begin
|
313
|
+
Process.kill(sig, pid)
|
314
|
+
rescue Errno::ESRCH => e
|
315
|
+
fail("Could not find process with pid #{pid}")
|
316
|
+
rescue Errno::EPERM => e
|
317
|
+
fail("You don't have permissions to stop process #{pid}")
|
318
|
+
rescue Exception => e
|
319
|
+
fail(e.message)
|
320
|
+
end
|
321
|
+
true
|
322
|
+
end
|
323
|
+
|
324
|
+
# Start agent
|
325
|
+
#
|
326
|
+
# === Parameters
|
327
|
+
# agent_name(String):: Agent name
|
328
|
+
# agent_class(Agent):: Agent class
|
329
|
+
#
|
330
|
+
# === Return
|
331
|
+
# true:: Always return true
|
332
|
+
def start_agent(agent_name, agent_class = Agent)
|
333
|
+
puts "#{human_readable_name} being started"
|
334
|
+
|
335
|
+
EM.error_handler do |e|
|
336
|
+
Log.error("EM block execution failed with exception", e, :trace)
|
337
|
+
Log.error("\n\n===== Exiting due to EM block exception =====\n\n")
|
338
|
+
# Cannot rely on EM.stop at this point, so exit to give chance for monitor restart
|
339
|
+
exit(1)
|
340
|
+
end
|
341
|
+
|
342
|
+
EM.run do
|
343
|
+
begin
|
344
|
+
@@agent = agent_class.start(@options)
|
345
|
+
rescue SystemExit
|
346
|
+
raise # Let parents of forked (daemonized) processes die
|
347
|
+
rescue PidFile::AlreadyRunning
|
348
|
+
puts "#{human_readable_name} already running"
|
349
|
+
EM.stop
|
350
|
+
rescue Exception => e
|
351
|
+
puts Log.format("#{human_readable_name} failed", e, :trace)
|
352
|
+
EM.stop
|
353
|
+
end
|
354
|
+
end
|
355
|
+
true
|
356
|
+
end
|
357
|
+
|
358
|
+
# Stop agent process
|
359
|
+
#
|
360
|
+
# === Parameters
|
361
|
+
# agent_name(String):: Agent name
|
362
|
+
#
|
363
|
+
# === Return
|
364
|
+
# (Boolean):: true if process was stopped, otherwise false
|
365
|
+
def stop_agent(agent_name)
|
366
|
+
res = false
|
367
|
+
if pid_file = AgentConfig.pid_file(agent_name)
|
368
|
+
name = human_readable_name(agent_name, pid_file.identity)
|
369
|
+
if pid = pid_file.read_pid[:pid]
|
370
|
+
begin
|
371
|
+
Process.kill('TERM', pid)
|
372
|
+
res = true
|
373
|
+
puts "#{name} stopped"
|
374
|
+
rescue Errno::ESRCH
|
375
|
+
puts "#{name} not running"
|
376
|
+
end
|
377
|
+
elsif File.file?(pid_file.to_s)
|
378
|
+
puts "Invalid pid file '#{pid_file.to_s}' content: #{IO.read(pid_file.to_s)}"
|
379
|
+
else
|
380
|
+
puts "#{name} not running"
|
381
|
+
end
|
382
|
+
else
|
383
|
+
puts "Non-existent pid file for #{agent_name}"
|
384
|
+
end
|
385
|
+
res
|
386
|
+
end
|
387
|
+
|
388
|
+
# Show status of agent
|
389
|
+
#
|
390
|
+
# === Parameters
|
391
|
+
# agent_name(String):: Agent name
|
392
|
+
#
|
393
|
+
# === Return
|
394
|
+
# (Boolean):: true if process is running, otherwise false
|
395
|
+
def show_agent(agent_name)
|
396
|
+
res = false
|
397
|
+
if (pid_file = AgentConfig.pid_file(agent_name)) && (pid = pid_file.read_pid[:pid])
|
398
|
+
pgid = Process.getpgid(pid) rescue -1
|
399
|
+
name = human_readable_name(agent_name, pid_file.identity)
|
400
|
+
if pgid != -1
|
401
|
+
psdata = `ps up #{pid}`.split("\n").last.split
|
402
|
+
memory = (psdata[5].to_i / 1024)
|
403
|
+
puts "#{name} is alive, using #{memory}MB of memory"
|
404
|
+
res = true
|
405
|
+
else
|
406
|
+
puts "#{name} is not running but has a stale pid file at #{pid_file}"
|
407
|
+
end
|
408
|
+
elsif identity = AgentConfig.agent_options(agent_name)[:identity]
|
409
|
+
puts "#{human_readable_name(agent_name, identity)} is not running"
|
410
|
+
end
|
411
|
+
res
|
412
|
+
end
|
413
|
+
|
414
|
+
# Generate human readable name for agent
|
415
|
+
#
|
416
|
+
# === Return
|
417
|
+
# (String):: Human readable name
|
418
|
+
def human_readable_name(agent_name = nil, identity = nil)
|
419
|
+
agent_name ||= @options[:agent_name]
|
420
|
+
"Agent #{agent_name + ' ' if agent_name}with ID #{identity || @options[:identity]}"
|
421
|
+
end
|
422
|
+
|
423
|
+
# List all configured agents
|
424
|
+
#
|
425
|
+
# === Return
|
426
|
+
# never
|
427
|
+
def list_configured_agents
|
428
|
+
agents = AgentConfig.cfg_agents
|
429
|
+
if agents.empty?
|
430
|
+
puts "Found no configured agents"
|
431
|
+
else
|
432
|
+
puts "Configured agents:"
|
433
|
+
agents.each { |a| puts " - #{a}" }
|
434
|
+
end
|
435
|
+
exit
|
436
|
+
end
|
437
|
+
|
438
|
+
# Determine syslog program name based on options
|
439
|
+
#
|
440
|
+
# === Parameters
|
441
|
+
# options(Hash):: Command line options
|
442
|
+
#
|
443
|
+
# === Return
|
444
|
+
# (String):: Program name
|
445
|
+
def syslog_program_name(options)
|
446
|
+
'RightAgent'
|
447
|
+
end
|
448
|
+
|
449
|
+
# Determine syslog facility based on options
|
450
|
+
#
|
451
|
+
# === Parameters
|
452
|
+
# options(Hash):: Command line options
|
453
|
+
#
|
454
|
+
# === Return
|
455
|
+
# (String):: 'local0'
|
456
|
+
def syslog_facility(options)
|
457
|
+
'local0'
|
458
|
+
end
|
459
|
+
|
460
|
+
# Determine configuration settings for this agent and persist them if needed
|
461
|
+
# Reuse existing agent identity when possible
|
462
|
+
#
|
463
|
+
# === Parameters
|
464
|
+
# action(String):: Requested action
|
465
|
+
# options(Hash):: Command line options
|
466
|
+
#
|
467
|
+
# === Return
|
468
|
+
# cfg(Hash):: Persisted configuration options
|
469
|
+
def configure_agent(action, options)
|
470
|
+
agent_type = options[:agent_type]
|
471
|
+
agent_name = options[:agent_name]
|
472
|
+
if agent_name != agent_type && cfg = AgentConfig.load_cfg(agent_type)
|
473
|
+
base_id = (options[:base_id] || AgentIdentity.parse(cfg[:identity]).base_id.to_s).to_i
|
474
|
+
unless (identity = AgentConfig.agent_options(agent_name)[:identity]) &&
|
475
|
+
AgentIdentity.parse(identity).base_id == base_id
|
476
|
+
identity = AgentIdentity.new(options[:prefix] || 'rs', options[:agent_type], base_id, options[:token]).to_s
|
477
|
+
end
|
478
|
+
cfg.merge!(:identity => identity)
|
479
|
+
cfg_file = AgentConfig.store_cfg(agent_name, cfg)
|
480
|
+
puts "Generated configuration file for #{agent_name} agent: #{cfg_file}"
|
481
|
+
elsif !(cfg = AgentConfig.load_cfg(agent_name))
|
482
|
+
fail("Deployment is missing configuration file #{AgentConfig.cfg_file(agent_name).inspect}")
|
483
|
+
end
|
484
|
+
cfg
|
485
|
+
end
|
486
|
+
|
487
|
+
# Enable the use of an HTTP proxy for this process and its subprocesses
|
488
|
+
#
|
489
|
+
# === Parameters
|
490
|
+
# proxy_setting(String):: Proxy to use
|
491
|
+
# exceptions(String):: Comma-separated list of proxy exceptions (e.g. metadata server)
|
492
|
+
#
|
493
|
+
# === Return
|
494
|
+
# true:: Always return true
|
495
|
+
def configure_proxy(proxy_setting, exceptions)
|
496
|
+
ENV['HTTP_PROXY'] = proxy_setting
|
497
|
+
ENV['http_proxy'] = proxy_setting
|
498
|
+
ENV['HTTPS_PROXY'] = proxy_setting
|
499
|
+
ENV['https_proxy'] = proxy_setting
|
500
|
+
ENV['NO_PROXY'] = exceptions
|
501
|
+
ENV['no_proxy'] = exceptions
|
502
|
+
true
|
503
|
+
end
|
504
|
+
|
505
|
+
# Print error on console and exit abnormally
|
506
|
+
#
|
507
|
+
# === Parameters
|
508
|
+
# message(String):: Error message to be displayed
|
509
|
+
# print_usage(Boolean):: Whether to display usage information
|
510
|
+
#
|
511
|
+
# === Return
|
512
|
+
# never
|
513
|
+
def fail(message, print_usage = false)
|
514
|
+
puts "** #{message}"
|
515
|
+
puts Usage.scan(__FILE__) if print_usage
|
516
|
+
exit(1)
|
517
|
+
end
|
518
|
+
|
519
|
+
end # AgentController
|
520
|
+
|
521
|
+
end # RightScale
|
522
|
+
|
523
|
+
#
|
524
|
+
# Copyright (c) 2009-2012 RightScale Inc
|
525
|
+
#
|
526
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
527
|
+
# a copy of this software and associated documentation files (the
|
528
|
+
# "Software"), to deal in the Software without restriction, including
|
529
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
530
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
531
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
532
|
+
# the following conditions:
|
533
|
+
#
|
534
|
+
# The above copyright notice and this permission notice shall be
|
535
|
+
# included in all copies or substantial portions of the Software.
|
536
|
+
#
|
537
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
538
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
539
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
540
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
541
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
542
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
543
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|