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.
- data/LICENSE +20 -0
- data/README.rdoc +78 -0
- data/Rakefile +86 -0
- data/lib/right_agent.rb +66 -0
- data/lib/right_agent/actor.rb +163 -0
- data/lib/right_agent/actor_registry.rb +76 -0
- data/lib/right_agent/actors/agent_manager.rb +189 -0
- data/lib/right_agent/agent.rb +735 -0
- data/lib/right_agent/agent_config.rb +403 -0
- data/lib/right_agent/agent_identity.rb +209 -0
- data/lib/right_agent/agent_tags_manager.rb +213 -0
- data/lib/right_agent/audit_formatter.rb +107 -0
- data/lib/right_agent/broker_client.rb +683 -0
- data/lib/right_agent/command.rb +30 -0
- data/lib/right_agent/command/agent_manager_commands.rb +134 -0
- data/lib/right_agent/command/command_client.rb +136 -0
- data/lib/right_agent/command/command_constants.rb +42 -0
- data/lib/right_agent/command/command_io.rb +128 -0
- data/lib/right_agent/command/command_parser.rb +87 -0
- data/lib/right_agent/command/command_runner.rb +105 -0
- data/lib/right_agent/command/command_serializer.rb +63 -0
- data/lib/right_agent/console.rb +65 -0
- data/lib/right_agent/core_payload_types.rb +42 -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 +90 -0
- data/lib/right_agent/core_payload_types/event_categories.rb +38 -0
- data/lib/right_agent/core_payload_types/executable_bundle.rb +138 -0
- data/lib/right_agent/core_payload_types/login_policy.rb +72 -0
- data/lib/right_agent/core_payload_types/login_user.rb +62 -0
- data/lib/right_agent/core_payload_types/planned_volume.rb +94 -0
- data/lib/right_agent/core_payload_types/recipe_instantiation.rb +60 -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 +73 -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/dispatcher.rb +348 -0
- data/lib/right_agent/enrollment_result.rb +217 -0
- data/lib/right_agent/exceptions.rb +30 -0
- data/lib/right_agent/ha_broker_client.rb +1278 -0
- data/lib/right_agent/idempotent_request.rb +140 -0
- data/lib/right_agent/log.rb +418 -0
- data/lib/right_agent/monkey_patches.rb +29 -0
- data/lib/right_agent/monkey_patches/amqp_patch.rb +274 -0
- data/lib/right_agent/monkey_patches/ruby_patch.rb +49 -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/singleton_patch.rb +46 -0
- data/lib/right_agent/monkey_patches/ruby_patch/string_patch.rb +107 -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 +90 -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 +91 -0
- data/lib/right_agent/operation_result.rb +270 -0
- data/lib/right_agent/packets.rb +637 -0
- data/lib/right_agent/payload_formatter.rb +104 -0
- data/lib/right_agent/pid_file.rb +159 -0
- data/lib/right_agent/platform.rb +319 -0
- data/lib/right_agent/platform/darwin.rb +227 -0
- data/lib/right_agent/platform/linux.rb +268 -0
- data/lib/right_agent/platform/windows.rb +1204 -0
- data/lib/right_agent/scripts/agent_controller.rb +522 -0
- data/lib/right_agent/scripts/agent_deployer.rb +379 -0
- data/lib/right_agent/scripts/common_parser.rb +153 -0
- data/lib/right_agent/scripts/log_level_manager.rb +193 -0
- data/lib/right_agent/scripts/stats_manager.rb +256 -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 +63 -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 +84 -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 +69 -0
- data/lib/right_agent/sender.rb +937 -0
- data/lib/right_agent/serialize.rb +29 -0
- data/lib/right_agent/serialize/message_pack.rb +102 -0
- data/lib/right_agent/serialize/secure_serializer.rb +131 -0
- data/lib/right_agent/serialize/secure_serializer_initializer.rb +47 -0
- data/lib/right_agent/serialize/serializable.rb +135 -0
- data/lib/right_agent/serialize/serializer.rb +149 -0
- data/lib/right_agent/stats_helper.rb +731 -0
- data/lib/right_agent/subprocess.rb +38 -0
- data/lib/right_agent/tracer.rb +124 -0
- data/right_agent.gemspec +60 -0
- data/spec/actor_registry_spec.rb +81 -0
- data/spec/actor_spec.rb +99 -0
- data/spec/agent_config_spec.rb +226 -0
- data/spec/agent_identity_spec.rb +75 -0
- data/spec/agent_spec.rb +571 -0
- data/spec/broker_client_spec.rb +961 -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 +72 -0
- data/spec/command/command_serializer_spec.rb +51 -0
- data/spec/core_payload_types/dev_repositories_spec.rb +64 -0
- data/spec/core_payload_types/executable_bundle_spec.rb +59 -0
- data/spec/core_payload_types/login_user_spec.rb +98 -0
- data/spec/core_payload_types/right_script_attachment_spec.rb +65 -0
- data/spec/core_payload_types/spec_helper.rb +23 -0
- data/spec/dispatcher_spec.rb +372 -0
- data/spec/enrollment_result_spec.rb +53 -0
- data/spec/ha_broker_client_spec.rb +1673 -0
- data/spec/idempotent_request_spec.rb +136 -0
- data/spec/log_spec.rb +177 -0
- data/spec/monkey_patches/amqp_patch_spec.rb +100 -0
- data/spec/monkey_patches/eventmachine_spec.rb +62 -0
- data/spec/monkey_patches/string_patch_spec.rb +99 -0
- data/spec/multiplexer_spec.rb +48 -0
- data/spec/operation_result_spec.rb +171 -0
- data/spec/packets_spec.rb +418 -0
- data/spec/platform/platform_spec.rb +60 -0
- data/spec/results_mock.rb +45 -0
- data/spec/secure_identity_spec.rb +50 -0
- data/spec/security/cached_certificate_store_proxy_spec.rb +56 -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 +52 -0
- data/spec/sender_spec.rb +887 -0
- data/spec/serialize/message_pack_spec.rb +131 -0
- data/spec/serialize/secure_serializer_spec.rb +102 -0
- data/spec/serialize/serializable_spec.rb +90 -0
- data/spec/serialize/serializer_spec.rb +174 -0
- data/spec/spec.opts +2 -0
- data/spec/spec_helper.rb +77 -0
- data/spec/stats_helper_spec.rb +681 -0
- data/spec/tracer_spec.rb +114 -0
- metadata +320 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright (c) 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
|
+
require 'rubygems'
|
|
24
|
+
require 'rbconfig'
|
|
25
|
+
|
|
26
|
+
MONKEY_PATCHES_BASE_DIR = File.join(File.dirname(__FILE__), 'monkey_patches')
|
|
27
|
+
|
|
28
|
+
require File.normalize_path(File.join(MONKEY_PATCHES_BASE_DIR, 'amqp_patch'))
|
|
29
|
+
require File.normalize_path(File.join(MONKEY_PATCHES_BASE_DIR, 'ruby_patch'))
|
|
@@ -0,0 +1,274 @@
|
|
|
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
|
+
class MQ
|
|
24
|
+
|
|
25
|
+
class Queue
|
|
26
|
+
# Asks the broker to redeliver all unacknowledged messages on a
|
|
27
|
+
# specified channel. Zero or more messages may be redelivered.
|
|
28
|
+
#
|
|
29
|
+
# * requeue (default false)
|
|
30
|
+
# If this parameter is false, the message will be redelivered to the original recipient.
|
|
31
|
+
# If this flag is true, the server will attempt to requeue the message, potentially then
|
|
32
|
+
# delivering it to an alternative subscriber.
|
|
33
|
+
#
|
|
34
|
+
def recover(requeue = false)
|
|
35
|
+
@mq.callback{
|
|
36
|
+
@mq.send Protocol::Basic::Recover.new({ :requeue => requeue })
|
|
37
|
+
}
|
|
38
|
+
self
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# May raise a MQ::Error exception when the frame payload contains a
|
|
43
|
+
# Protocol::Channel::Close object.
|
|
44
|
+
#
|
|
45
|
+
# This usually occurs when a client attempts to perform an illegal
|
|
46
|
+
# operation. A short, and incomplete, list of potential illegal operations
|
|
47
|
+
# follows:
|
|
48
|
+
# * publish a message to a deleted exchange (NOT_FOUND)
|
|
49
|
+
# * declare an exchange using the reserved 'amq.' naming structure (ACCESS_REFUSED)
|
|
50
|
+
#
|
|
51
|
+
def process_frame frame
|
|
52
|
+
log :received, frame
|
|
53
|
+
|
|
54
|
+
case frame
|
|
55
|
+
when Frame::Header
|
|
56
|
+
@header = frame.payload
|
|
57
|
+
@body = ''
|
|
58
|
+
|
|
59
|
+
when Frame::Body
|
|
60
|
+
@body << frame.payload
|
|
61
|
+
if @body.length >= @header.size
|
|
62
|
+
if @method.is_a? Protocol::Basic::Return
|
|
63
|
+
@on_return_message.call @method, @body if @on_return_message
|
|
64
|
+
else
|
|
65
|
+
@header.properties.update(@method.arguments)
|
|
66
|
+
@consumer.receive @header, @body if @consumer
|
|
67
|
+
end
|
|
68
|
+
@body = @header = @consumer = @method = nil
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
when Frame::Method
|
|
72
|
+
case method = frame.payload
|
|
73
|
+
when Protocol::Channel::OpenOk
|
|
74
|
+
send Protocol::Access::Request.new(:realm => '/data',
|
|
75
|
+
:read => true,
|
|
76
|
+
:write => true,
|
|
77
|
+
:active => true,
|
|
78
|
+
:passive => true)
|
|
79
|
+
|
|
80
|
+
when Protocol::Access::RequestOk
|
|
81
|
+
@ticket = method.ticket
|
|
82
|
+
callback{
|
|
83
|
+
send Protocol::Channel::Close.new(:reply_code => 200,
|
|
84
|
+
:reply_text => 'bye',
|
|
85
|
+
:method_id => 0,
|
|
86
|
+
:class_id => 0)
|
|
87
|
+
} if @closing
|
|
88
|
+
succeed
|
|
89
|
+
|
|
90
|
+
when Protocol::Basic::CancelOk
|
|
91
|
+
if @consumer = consumers[ method.consumer_tag ]
|
|
92
|
+
@consumer.cancelled
|
|
93
|
+
else
|
|
94
|
+
MQ.error "Basic.CancelOk for invalid consumer tag: #{method.consumer_tag}"
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
when Protocol::Queue::DeclareOk
|
|
98
|
+
queues[ method.queue ].receive_status method
|
|
99
|
+
|
|
100
|
+
when Protocol::Basic::Deliver, Protocol::Basic::GetOk
|
|
101
|
+
@method = method
|
|
102
|
+
@header = nil
|
|
103
|
+
@body = ''
|
|
104
|
+
|
|
105
|
+
if method.is_a? Protocol::Basic::GetOk
|
|
106
|
+
@consumer = get_queue{|q| q.shift }
|
|
107
|
+
MQ.error "No pending Basic.GetOk requests" unless @consumer
|
|
108
|
+
else
|
|
109
|
+
@consumer = consumers[ method.consumer_tag ]
|
|
110
|
+
MQ.error "Basic.Deliver for invalid consumer tag: #{method.consumer_tag}" unless @consumer
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
when Protocol::Basic::GetEmpty
|
|
114
|
+
if @consumer = get_queue{|q| q.shift }
|
|
115
|
+
@consumer.receive nil, nil
|
|
116
|
+
else
|
|
117
|
+
MQ.error "Basic.GetEmpty for invalid consumer"
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
when Protocol::Basic::Return
|
|
121
|
+
@method = method
|
|
122
|
+
@header = nil
|
|
123
|
+
@body = ''
|
|
124
|
+
|
|
125
|
+
when Protocol::Channel::Close
|
|
126
|
+
raise Error, "#{method.reply_text} in #{Protocol.classes[method.class_id].methods[method.method_id]} on #{@channel}"
|
|
127
|
+
|
|
128
|
+
when Protocol::Channel::CloseOk
|
|
129
|
+
@closing = false
|
|
130
|
+
conn.callback{ |c|
|
|
131
|
+
c.channels.delete @channel
|
|
132
|
+
c.close if c.channels.empty?
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
when Protocol::Basic::ConsumeOk
|
|
136
|
+
if @consumer = consumers[ method.consumer_tag ]
|
|
137
|
+
@consumer.confirm_subscribe
|
|
138
|
+
else
|
|
139
|
+
MQ.error "Basic.ConsumeOk for invalid consumer tag: #{method.consumer_tag}"
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# Provide callback to be activated when a message is returned
|
|
146
|
+
def return_message(&blk)
|
|
147
|
+
@on_return_message = blk
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
# monkey patch to the amqp gem that adds :no_declare => true option for new Queue objects.
|
|
153
|
+
# This allows an instance that has no configuration privileges to enroll without blowing
|
|
154
|
+
# up the AMQP gem when it tries to subscribe to its queue before it has been created.
|
|
155
|
+
# Exchange :no_declare support is already in the eventmachine-0.12.10 gem.
|
|
156
|
+
# temporary until we get this into amqp proper
|
|
157
|
+
MQ::Queue.class_eval do
|
|
158
|
+
def initialize mq, name, opts = {}
|
|
159
|
+
@mq = mq
|
|
160
|
+
@opts = opts
|
|
161
|
+
@bindings ||= {}
|
|
162
|
+
@mq.queues[@name = name] ||= self
|
|
163
|
+
unless opts[:no_declare]
|
|
164
|
+
@mq.callback{
|
|
165
|
+
@mq.send AMQP::Protocol::Queue::Declare.new({ :queue => name,
|
|
166
|
+
:nowait => true }.merge(opts))
|
|
167
|
+
}
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
begin
|
|
173
|
+
# Monkey patch AMQP reconnect backoff
|
|
174
|
+
AMQP::Client.module_eval do
|
|
175
|
+
def initialize opts = {}
|
|
176
|
+
@settings = opts
|
|
177
|
+
extend AMQP.client
|
|
178
|
+
|
|
179
|
+
@on_disconnect ||= proc{ @connection_status.call(:failed) if @connection_status }
|
|
180
|
+
|
|
181
|
+
timeout @settings[:timeout] if @settings[:timeout]
|
|
182
|
+
errback{ @on_disconnect.call } unless @reconnecting
|
|
183
|
+
|
|
184
|
+
@connected = false
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def reconnect(force = false)
|
|
188
|
+
if @reconnecting and not force
|
|
189
|
+
# Wait after first reconnect attempt and in between each subsequent attempt
|
|
190
|
+
EM.add_timer(@settings[:reconnect_interval] || 5) { reconnect(true) }
|
|
191
|
+
return
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
unless @reconnecting
|
|
195
|
+
@deferred_status = nil
|
|
196
|
+
initialize(@settings)
|
|
197
|
+
|
|
198
|
+
mqs = @channels
|
|
199
|
+
@channels = {}
|
|
200
|
+
mqs.each{ |_,mq| mq.reset } if mqs
|
|
201
|
+
|
|
202
|
+
@reconnecting = true
|
|
203
|
+
|
|
204
|
+
again = @settings[:reconnect_delay]
|
|
205
|
+
again = again.call if again.is_a?(Proc)
|
|
206
|
+
if again.is_a?(Numeric)
|
|
207
|
+
# Wait before making initial reconnect attempt
|
|
208
|
+
EM.add_timer(again) { reconnect(true) }
|
|
209
|
+
return
|
|
210
|
+
elsif ![nil, true].include?(again)
|
|
211
|
+
raise ::AMQP::Error, "Could not interpret :reconnect_delay => #{again.inspect}; expected nil, true, or Numeric"
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
RightScale::Log.warning("Attempting to reconnect to broker " +
|
|
216
|
+
"#{RightScale::AgentIdentity.new('rs', 'broker', @settings[:port].to_i, @settings[:host].gsub('-', '~')).to_s}")
|
|
217
|
+
log 'reconnecting'
|
|
218
|
+
EM.reconnect(@settings[:host], @settings[:port], self)
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
# Monkey patch AMQP to clean up @conn when an error is raised after a broker request failure,
|
|
223
|
+
# otherwise AMQP becomes unusable
|
|
224
|
+
AMQP.module_eval do
|
|
225
|
+
def self.start *args, &blk
|
|
226
|
+
begin
|
|
227
|
+
EM.run{
|
|
228
|
+
@conn ||= connect *args
|
|
229
|
+
@conn.callback(&blk) if blk
|
|
230
|
+
@conn
|
|
231
|
+
}
|
|
232
|
+
rescue Exception => e
|
|
233
|
+
@conn = nil
|
|
234
|
+
raise e
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
# This monkey patch catches exceptions that would otherwise cause EM to stop or be in a bad
|
|
240
|
+
# state if a top level EM error handler was setup. Instead close the connection and leave EM
|
|
241
|
+
# alone.
|
|
242
|
+
# Don't log an error if the environment variable IGNORE_AMQP_FAILURES is set (used in the
|
|
243
|
+
# enroll script)
|
|
244
|
+
AMQP::Client.module_eval do
|
|
245
|
+
alias :orig_receive_data :receive_data
|
|
246
|
+
def receive_data(*args)
|
|
247
|
+
begin
|
|
248
|
+
orig_receive_data(*args)
|
|
249
|
+
rescue Exception => e
|
|
250
|
+
RightScale::Log.error("Exception caught while processing AMQP frame, closing connection",
|
|
251
|
+
e, :trace) unless ENV['IGNORE_AMQP_FAILURES']
|
|
252
|
+
close_connection
|
|
253
|
+
end
|
|
254
|
+
end
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
# Add a new callback to amqp gem that triggers once the handshake with the broker completed
|
|
258
|
+
# The 'connected' status callback happens before the handshake is done and if it results in
|
|
259
|
+
# a lot of activity it might prevent EM from being able to call the code handling the
|
|
260
|
+
# incoming handshake packet in a timely fashion causing the broker to close the connection
|
|
261
|
+
AMQP::BasicClient.module_eval do
|
|
262
|
+
alias :orig_process_frame :process_frame
|
|
263
|
+
def process_frame(frame)
|
|
264
|
+
orig_process_frame(frame)
|
|
265
|
+
@connection_status.call(:ready) if @connection_status && frame.payload.is_a?(AMQP::Protocol::Connection::Start)
|
|
266
|
+
end
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
rescue LoadError => e
|
|
270
|
+
# Make sure we're dealing with a legitimate missing-file LoadError
|
|
271
|
+
raise e unless e.message =~ /^no such file to load/
|
|
272
|
+
# Missing 'amqp' indicates that the AMQP gem is not installed; we can ignore this
|
|
273
|
+
end
|
|
274
|
+
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright (c) 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
|
+
# This file may get required twice on Windows: Once using long path and once
|
|
24
|
+
# using short path. Since this is where we define the File.normalize_path
|
|
25
|
+
# method to alleviate this issue, we have a chicken & egg problem. So detect if
|
|
26
|
+
# we already required this file and skip the rest if that was the case.
|
|
27
|
+
unless defined?(RUBY_PATCH_BASE_DIR)
|
|
28
|
+
|
|
29
|
+
# Load platform-specific patches before any other patches (in order to define
|
|
30
|
+
# File.normalize_path, etc.)
|
|
31
|
+
case (family = RbConfig::CONFIG['host_os'])
|
|
32
|
+
when /mswin|win32|dos|mingw|cygwin/i
|
|
33
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'ruby_patch', 'windows_patch'))
|
|
34
|
+
when /linux/i
|
|
35
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'ruby_patch', 'linux_patch'))
|
|
36
|
+
when /darwin/i
|
|
37
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'ruby_patch', 'darwin_patch'))
|
|
38
|
+
else
|
|
39
|
+
raise LoadError, "Unsupported platform: #{family}"
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
RUBY_PATCH_BASE_DIR = File.join(File.dirname(__FILE__), 'ruby_patch')
|
|
43
|
+
|
|
44
|
+
require File.normalize_path(File.join(RUBY_PATCH_BASE_DIR, 'array_patch'))
|
|
45
|
+
require File.normalize_path(File.join(RUBY_PATCH_BASE_DIR, 'string_patch'))
|
|
46
|
+
require File.normalize_path(File.join(RUBY_PATCH_BASE_DIR, 'object_patch'))
|
|
47
|
+
require File.normalize_path(File.join(RUBY_PATCH_BASE_DIR, 'singleton_patch'))
|
|
48
|
+
|
|
49
|
+
end # Unless already defined
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright (c) 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
|
+
class Array
|
|
24
|
+
|
|
25
|
+
def rotate!
|
|
26
|
+
push shift
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright (c) 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
|
+
# darwin currently has no difference from linux platform patches.
|
|
24
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'linux_patch'))
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright (c) 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
|
+
# load File monkey-patch first to enable use of File.normalize_path
|
|
24
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'linux_patch', 'file_patch'))
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright (c) 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
|
+
class File
|
|
24
|
+
|
|
25
|
+
# On *nix systems, resolves to File.expand_path
|
|
26
|
+
def self.normalize_path(file_name, *dir_string)
|
|
27
|
+
File.expand_path(file_name, *dir_string)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
end
|