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.
Files changed (176) hide show
  1. data/LICENSE +20 -0
  2. data/README.rdoc +82 -0
  3. data/Rakefile +113 -0
  4. data/lib/right_agent.rb +59 -0
  5. data/lib/right_agent/actor.rb +182 -0
  6. data/lib/right_agent/actor_registry.rb +76 -0
  7. data/lib/right_agent/actors/agent_manager.rb +232 -0
  8. data/lib/right_agent/agent.rb +1149 -0
  9. data/lib/right_agent/agent_config.rb +480 -0
  10. data/lib/right_agent/agent_identity.rb +210 -0
  11. data/lib/right_agent/agent_tag_manager.rb +237 -0
  12. data/lib/right_agent/audit_formatter.rb +107 -0
  13. data/lib/right_agent/clients.rb +31 -0
  14. data/lib/right_agent/clients/api_client.rb +383 -0
  15. data/lib/right_agent/clients/auth_client.rb +247 -0
  16. data/lib/right_agent/clients/balanced_http_client.rb +369 -0
  17. data/lib/right_agent/clients/base_retry_client.rb +495 -0
  18. data/lib/right_agent/clients/right_http_client.rb +279 -0
  19. data/lib/right_agent/clients/router_client.rb +493 -0
  20. data/lib/right_agent/command.rb +30 -0
  21. data/lib/right_agent/command/agent_manager_commands.rb +150 -0
  22. data/lib/right_agent/command/command_client.rb +136 -0
  23. data/lib/right_agent/command/command_constants.rb +33 -0
  24. data/lib/right_agent/command/command_io.rb +126 -0
  25. data/lib/right_agent/command/command_parser.rb +87 -0
  26. data/lib/right_agent/command/command_runner.rb +118 -0
  27. data/lib/right_agent/command/command_serializer.rb +63 -0
  28. data/lib/right_agent/connectivity_checker.rb +179 -0
  29. data/lib/right_agent/console.rb +65 -0
  30. data/lib/right_agent/core_payload_types.rb +44 -0
  31. data/lib/right_agent/core_payload_types/cookbook.rb +61 -0
  32. data/lib/right_agent/core_payload_types/cookbook_position.rb +46 -0
  33. data/lib/right_agent/core_payload_types/cookbook_repository.rb +116 -0
  34. data/lib/right_agent/core_payload_types/cookbook_sequence.rb +70 -0
  35. data/lib/right_agent/core_payload_types/dev_repositories.rb +100 -0
  36. data/lib/right_agent/core_payload_types/dev_repository.rb +76 -0
  37. data/lib/right_agent/core_payload_types/event_categories.rb +38 -0
  38. data/lib/right_agent/core_payload_types/executable_bundle.rb +130 -0
  39. data/lib/right_agent/core_payload_types/login_policy.rb +72 -0
  40. data/lib/right_agent/core_payload_types/login_user.rb +79 -0
  41. data/lib/right_agent/core_payload_types/planned_volume.rb +94 -0
  42. data/lib/right_agent/core_payload_types/recipe_instantiation.rb +73 -0
  43. data/lib/right_agent/core_payload_types/repositories_bundle.rb +50 -0
  44. data/lib/right_agent/core_payload_types/right_script_attachment.rb +95 -0
  45. data/lib/right_agent/core_payload_types/right_script_instantiation.rb +94 -0
  46. data/lib/right_agent/core_payload_types/runlist_policy.rb +44 -0
  47. data/lib/right_agent/core_payload_types/secure_document.rb +66 -0
  48. data/lib/right_agent/core_payload_types/secure_document_location.rb +63 -0
  49. data/lib/right_agent/core_payload_types/software_repository_instantiation.rb +61 -0
  50. data/lib/right_agent/daemonize.rb +35 -0
  51. data/lib/right_agent/dispatched_cache.rb +109 -0
  52. data/lib/right_agent/dispatcher.rb +272 -0
  53. data/lib/right_agent/enrollment_result.rb +221 -0
  54. data/lib/right_agent/exceptions.rb +87 -0
  55. data/lib/right_agent/history.rb +145 -0
  56. data/lib/right_agent/log.rb +460 -0
  57. data/lib/right_agent/minimal.rb +46 -0
  58. data/lib/right_agent/monkey_patches.rb +30 -0
  59. data/lib/right_agent/monkey_patches/ruby_patch.rb +55 -0
  60. data/lib/right_agent/monkey_patches/ruby_patch/array_patch.rb +29 -0
  61. data/lib/right_agent/monkey_patches/ruby_patch/darwin_patch.rb +24 -0
  62. data/lib/right_agent/monkey_patches/ruby_patch/linux_patch.rb +24 -0
  63. data/lib/right_agent/monkey_patches/ruby_patch/linux_patch/file_patch.rb +30 -0
  64. data/lib/right_agent/monkey_patches/ruby_patch/object_patch.rb +49 -0
  65. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch.rb +32 -0
  66. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/file_patch.rb +60 -0
  67. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/process_patch.rb +63 -0
  68. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/stdio_patch.rb +27 -0
  69. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/time_patch.rb +55 -0
  70. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/win32ole_patch.rb +34 -0
  71. data/lib/right_agent/multiplexer.rb +102 -0
  72. data/lib/right_agent/offline_handler.rb +270 -0
  73. data/lib/right_agent/operation_result.rb +300 -0
  74. data/lib/right_agent/packets.rb +673 -0
  75. data/lib/right_agent/payload_formatter.rb +104 -0
  76. data/lib/right_agent/pending_requests.rb +128 -0
  77. data/lib/right_agent/pid_file.rb +159 -0
  78. data/lib/right_agent/platform.rb +770 -0
  79. data/lib/right_agent/platform/unix/darwin/platform.rb +102 -0
  80. data/lib/right_agent/platform/unix/linux/platform.rb +305 -0
  81. data/lib/right_agent/platform/unix/platform.rb +226 -0
  82. data/lib/right_agent/platform/windows/mingw/platform.rb +447 -0
  83. data/lib/right_agent/platform/windows/mswin/platform.rb +236 -0
  84. data/lib/right_agent/platform/windows/platform.rb +1808 -0
  85. data/lib/right_agent/protocol_version_mixin.rb +69 -0
  86. data/lib/right_agent/retryable_request.rb +195 -0
  87. data/lib/right_agent/scripts/agent_controller.rb +543 -0
  88. data/lib/right_agent/scripts/agent_deployer.rb +400 -0
  89. data/lib/right_agent/scripts/common_parser.rb +160 -0
  90. data/lib/right_agent/scripts/log_level_manager.rb +192 -0
  91. data/lib/right_agent/scripts/stats_manager.rb +268 -0
  92. data/lib/right_agent/scripts/usage.rb +58 -0
  93. data/lib/right_agent/secure_identity.rb +92 -0
  94. data/lib/right_agent/security.rb +32 -0
  95. data/lib/right_agent/security/cached_certificate_store_proxy.rb +77 -0
  96. data/lib/right_agent/security/certificate.rb +102 -0
  97. data/lib/right_agent/security/certificate_cache.rb +89 -0
  98. data/lib/right_agent/security/distinguished_name.rb +56 -0
  99. data/lib/right_agent/security/encrypted_document.rb +83 -0
  100. data/lib/right_agent/security/rsa_key_pair.rb +76 -0
  101. data/lib/right_agent/security/signature.rb +86 -0
  102. data/lib/right_agent/security/static_certificate_store.rb +85 -0
  103. data/lib/right_agent/sender.rb +792 -0
  104. data/lib/right_agent/serialize.rb +29 -0
  105. data/lib/right_agent/serialize/message_pack.rb +107 -0
  106. data/lib/right_agent/serialize/secure_serializer.rb +151 -0
  107. data/lib/right_agent/serialize/secure_serializer_initializer.rb +47 -0
  108. data/lib/right_agent/serialize/serializable.rb +151 -0
  109. data/lib/right_agent/serialize/serializer.rb +159 -0
  110. data/lib/right_agent/subprocess.rb +38 -0
  111. data/lib/right_agent/tracer.rb +124 -0
  112. data/right_agent.gemspec +101 -0
  113. data/spec/actor_registry_spec.rb +80 -0
  114. data/spec/actor_spec.rb +162 -0
  115. data/spec/agent_config_spec.rb +235 -0
  116. data/spec/agent_identity_spec.rb +78 -0
  117. data/spec/agent_spec.rb +734 -0
  118. data/spec/agent_tag_manager_spec.rb +319 -0
  119. data/spec/clients/api_client_spec.rb +423 -0
  120. data/spec/clients/auth_client_spec.rb +272 -0
  121. data/spec/clients/balanced_http_client_spec.rb +576 -0
  122. data/spec/clients/base_retry_client_spec.rb +635 -0
  123. data/spec/clients/router_client_spec.rb +594 -0
  124. data/spec/clients/spec_helper.rb +111 -0
  125. data/spec/command/agent_manager_commands_spec.rb +51 -0
  126. data/spec/command/command_io_spec.rb +93 -0
  127. data/spec/command/command_parser_spec.rb +79 -0
  128. data/spec/command/command_runner_spec.rb +107 -0
  129. data/spec/command/command_serializer_spec.rb +51 -0
  130. data/spec/connectivity_checker_spec.rb +83 -0
  131. data/spec/core_payload_types/dev_repositories_spec.rb +64 -0
  132. data/spec/core_payload_types/dev_repository_spec.rb +33 -0
  133. data/spec/core_payload_types/executable_bundle_spec.rb +67 -0
  134. data/spec/core_payload_types/login_user_spec.rb +102 -0
  135. data/spec/core_payload_types/recipe_instantiation_spec.rb +81 -0
  136. data/spec/core_payload_types/right_script_attachment_spec.rb +65 -0
  137. data/spec/core_payload_types/right_script_instantiation_spec.rb +79 -0
  138. data/spec/core_payload_types/spec_helper.rb +23 -0
  139. data/spec/dispatched_cache_spec.rb +136 -0
  140. data/spec/dispatcher_spec.rb +324 -0
  141. data/spec/enrollment_result_spec.rb +53 -0
  142. data/spec/history_spec.rb +246 -0
  143. data/spec/log_spec.rb +192 -0
  144. data/spec/monkey_patches/eventmachine_spec.rb +62 -0
  145. data/spec/multiplexer_spec.rb +48 -0
  146. data/spec/offline_handler_spec.rb +340 -0
  147. data/spec/operation_result_spec.rb +208 -0
  148. data/spec/packets_spec.rb +461 -0
  149. data/spec/pending_requests_spec.rb +136 -0
  150. data/spec/platform/spec_helper.rb +216 -0
  151. data/spec/platform/unix/darwin/platform_spec.rb +181 -0
  152. data/spec/platform/unix/linux/platform_spec.rb +540 -0
  153. data/spec/platform/unix/spec_helper.rb +149 -0
  154. data/spec/platform/windows/mingw/platform_spec.rb +222 -0
  155. data/spec/platform/windows/mswin/platform_spec.rb +259 -0
  156. data/spec/platform/windows/spec_helper.rb +720 -0
  157. data/spec/retryable_request_spec.rb +306 -0
  158. data/spec/secure_identity_spec.rb +50 -0
  159. data/spec/security/cached_certificate_store_proxy_spec.rb +62 -0
  160. data/spec/security/certificate_cache_spec.rb +71 -0
  161. data/spec/security/certificate_spec.rb +49 -0
  162. data/spec/security/distinguished_name_spec.rb +46 -0
  163. data/spec/security/encrypted_document_spec.rb +55 -0
  164. data/spec/security/rsa_key_pair_spec.rb +55 -0
  165. data/spec/security/signature_spec.rb +66 -0
  166. data/spec/security/static_certificate_store_spec.rb +58 -0
  167. data/spec/sender_spec.rb +1045 -0
  168. data/spec/serialize/message_pack_spec.rb +131 -0
  169. data/spec/serialize/secure_serializer_spec.rb +132 -0
  170. data/spec/serialize/serializable_spec.rb +90 -0
  171. data/spec/serialize/serializer_spec.rb +197 -0
  172. data/spec/spec.opts +2 -0
  173. data/spec/spec.win32.opts +1 -0
  174. data/spec/spec_helper.rb +130 -0
  175. data/spec/tracer_spec.rb +114 -0
  176. metadata +447 -0
@@ -0,0 +1,30 @@
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
+ COMMAND_BASE_DIR = File.join(File.dirname(__FILE__), 'command')
24
+
25
+ require File.normalize_path(File.join(COMMAND_BASE_DIR, 'command_constants'))
26
+ require File.normalize_path(File.join(COMMAND_BASE_DIR, 'command_parser'))
27
+ require File.normalize_path(File.join(COMMAND_BASE_DIR, 'command_serializer'))
28
+ require File.normalize_path(File.join(COMMAND_BASE_DIR, 'command_io'))
29
+ require File.normalize_path(File.join(COMMAND_BASE_DIR, 'command_runner'))
30
+ require File.normalize_path(File.join(COMMAND_BASE_DIR, 'command_client'))
@@ -0,0 +1,150 @@
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
+ # Commands exposed by agent that has an AgentManager actor
26
+ class AgentManagerCommands
27
+
28
+ # List of command names associated with description
29
+ # The commands should be implemented in methods in this class named '<name>_command'
30
+ # where <name> is the name of the command.
31
+ COMMANDS = {
32
+ :list => 'List all available commands with their description',
33
+ :set_log_level => 'Set log level to options[:level]',
34
+ :get_log_level => 'Get log level',
35
+ :ping => 'Ping agent',
36
+ :stats => 'Get statistics about agent operation',
37
+ :profile => 'Manage memory profiling',
38
+ :terminate => 'Terminate agent'
39
+ }
40
+
41
+ # Build hash of commands associating command names with block
42
+ #
43
+ # === Parameter
44
+ # agent_manager(AgentManager):: Agent manager used by ping and stats commands
45
+ #
46
+ # === Return
47
+ # cmds(Hash):: Hash of command blocks keyed by command names
48
+ def self.get(agent_manager)
49
+ cmds = {}
50
+ target = new(agent_manager)
51
+ COMMANDS.each { |k, v| cmds[k] = lambda { |opts, conn| opts[:conn] = conn; target.send("#{k.to_s}_command", opts) } }
52
+ cmds
53
+ end
54
+
55
+ # Initialize command server
56
+ #
57
+ # === Parameter
58
+ # agent_manager(AgentManager):: Agent manager used by ping and stats commands
59
+ def initialize(agent_manager)
60
+ @agent_manager = agent_manager
61
+ @serializer = Serializer.new
62
+ end
63
+
64
+ protected
65
+
66
+ # List command implementation
67
+ #
68
+ # === Parameters
69
+ # opts(Hash):: Should contain the connection for sending data
70
+ #
71
+ # === Return
72
+ # true:: Always return true
73
+ def list_command(opts)
74
+ usage = "Agent exposes the following commands:\n"
75
+ COMMANDS.reject { |k, _| k == :list || k.to_s =~ /test/ }.each do |c|
76
+ c.each { |k, v| usage += " - #{k.to_s}: #{v}\n" }
77
+ end
78
+ CommandIO.instance.reply(opts[:conn], usage)
79
+ end
80
+
81
+ # Set log level command
82
+ #
83
+ # === Return
84
+ # true:: Always return true
85
+ def set_log_level_command(opts)
86
+ Log.level = opts[:level] if [ :debug, :info, :warn, :error, :fatal ].include?(opts[:level])
87
+ CommandIO.instance.reply(opts[:conn], Log.level)
88
+ end
89
+
90
+ # Get log level command
91
+ #
92
+ # === Return
93
+ # true:: Always return true
94
+ def get_log_level_command(opts)
95
+ CommandIO.instance.reply(opts[:conn], Log.level)
96
+ end
97
+
98
+ # Ping command
99
+ #
100
+ # === Parameters
101
+ # opts[:conn](EM::Connection):: Connection used to send reply
102
+ #
103
+ # === Return
104
+ # true
105
+ def ping_command(opts)
106
+ CommandIO.instance.reply(opts[:conn], @serializer.dump(@agent_manager.ping))
107
+ end
108
+
109
+ # Stats command
110
+ #
111
+ # === Parameters
112
+ # opts[:conn](EM::Connection):: Connection used to send reply
113
+ # opts[:reset](Boolean):: Whether to reset stats
114
+ #
115
+ # === Return
116
+ # true
117
+ def stats_command(opts)
118
+ CommandIO.instance.reply(opts[:conn], @serializer.dump(@agent_manager.stats({:reset => opts[:reset]})))
119
+ end
120
+
121
+ # Profile command
122
+ #
123
+ # === Parameters
124
+ # opts[:conn](EM::Connection):: Connection used to send reply
125
+ # opts[:start](Boolean):: Whether to start profiling
126
+ # opts[:stats](Boolean):: Whether to display profile statistics to stdout
127
+ # opts[:reset](Boolean):: Whether to reset profile statistics when after displaying them
128
+ # opts[:stop](Boolean):: Whether to stop profiling
129
+ #
130
+ # === Return
131
+ # true
132
+ def profile_command(opts)
133
+ CommandIO.instance.reply(opts[:conn], @serializer.dump(@agent_manager.profile(opts)))
134
+ end
135
+
136
+ # Terminate command
137
+ #
138
+ # === Parameters
139
+ # opts[:conn](EM::Connection):: Connection used to send reply
140
+ #
141
+ # === Return
142
+ # true:: Always return true
143
+ def terminate_command(opts)
144
+ CommandIO.instance.reply(opts[:conn], 'Terminating')
145
+ @agent_manager.terminate
146
+ end
147
+
148
+ end # AgentManagerCommands
149
+
150
+ end # RightScale
@@ -0,0 +1,136 @@
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
+ class CommandClient
26
+
27
+ # Agent response if any
28
+ attr_accessor :response
29
+
30
+ # Create client
31
+ #
32
+ # === Parameters
33
+ # socket_port(Integer):: Socket port on which to connect to agent
34
+ # cookie(String):: Cookie associated with command server
35
+ def initialize(socket_port, cookie)
36
+ @socket_port = socket_port
37
+ @cookie = cookie
38
+ @pending = 0
39
+ end
40
+
41
+ # Stop command client
42
+ #
43
+ # === Block
44
+ # Given block gets called back once last response has been received or timeout
45
+ def stop(&close_handler)
46
+ if @pending > 0
47
+ @close_timeout = EM::Timer.new(@last_timeout) { close_handler.call(timeout=true) }
48
+ @close_handler = lambda { @close_timeout.cancel; close_handler.call(timeout=false) }
49
+ else
50
+ close_handler.call(timeout=false)
51
+ end
52
+ end
53
+
54
+ # Send command to running agent
55
+ #
56
+ # === Parameters
57
+ # options(Hash):: Hash of options and command name
58
+ # options[:name]:: Command name
59
+ # options[:...]:: Other command specific options, passed through to agent
60
+ # verbose(Boolean):: Whether client should display debug info
61
+ # timeout(Integer):: Number of seconds we should wait for a reply from the agent
62
+ #
63
+ # === Block
64
+ # handler: Command results handler
65
+ #
66
+ # === Return
67
+ # true:: Always return true
68
+ #
69
+ # === Raise
70
+ # RuntimeError:: Timed out waiting for result, raised in EM thread
71
+ def send_command(options, verbose=false, timeout=20, &handler)
72
+ return if @closing
73
+ @last_timeout = timeout
74
+ manage_em = !EM.reactor_running?
75
+ response_handler = lambda do
76
+ EM.stop if manage_em
77
+ handler.call(@response) if handler && @response
78
+ @pending -= 1
79
+ @close_handler.call if @close_handler && @pending == 0
80
+ end
81
+ send_handler = lambda do
82
+ @pending += 1
83
+ command = options.dup
84
+ command[:verbose] = verbose
85
+ command[:cookie] = @cookie
86
+ EM.next_tick { EM.connect('127.0.0.1', @socket_port, ConnectionHandler, command, self, response_handler) }
87
+ EM.add_timer(timeout) { EM.stop; raise 'Timed out waiting for agent reply' } if manage_em
88
+ end
89
+ if manage_em
90
+ EM.run { send_handler.call }
91
+ else
92
+ send_handler.call
93
+ end
94
+ true
95
+ end
96
+
97
+ protected
98
+
99
+ # EventMachine connection handler which sends command to agent
100
+ # and waits for response
101
+ module ConnectionHandler
102
+
103
+ # Initialize command
104
+ #
105
+ # === Parameters
106
+ # command(Hash):: Command to be sent
107
+ # client(RightScale::CommandClient):: Client whose response field should be initialized
108
+ # callback(Proc):: Called back after response has been set
109
+ def initialize(command, client, callback)
110
+ @command = command
111
+ @parser = CommandParser.new do |data|
112
+ close_connection
113
+ client.response = data
114
+ callback.call
115
+ end
116
+ end
117
+
118
+ # Send command to agent
119
+ # Called by EventMachine after connection with agent has been established
120
+ #
121
+ # === Return
122
+ # true:: Always return true
123
+ def post_init
124
+ puts "Sending command #{@command.inspect}" if @command[:verbose]
125
+ send_data(CommandSerializer.dump(@command))
126
+ true
127
+ end
128
+
129
+ # Handle agent response
130
+ def receive_data(data)
131
+ @parser.parse_chunk(data)
132
+ end
133
+ end
134
+
135
+ end
136
+ end
@@ -0,0 +1,33 @@
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
+
24
+ module RightScale
25
+
26
+ class CommandConstants
27
+
28
+ # Ports used for command protocol
29
+ BASE_INSTANCE_AGENT_SOCKET_PORT = 53843
30
+ BASE_INSTANCE_AGENT_CHECKER_SOCKET_PORT = 53844
31
+
32
+ end
33
+ end
@@ -0,0 +1,126 @@
1
+ # Copyright (c) 2009-2011 RightScale, Inc, All Rights Reserved Worldwide.
2
+ #
3
+ # THIS PROGRAM IS CONFIDENTIAL AND PROPRIETARY TO RIGHTSCALE
4
+ # AND CONSTITUTES A VALUABLE TRADE SECRET. Any unauthorized use,
5
+ # reproduction, modification, or disclosure of this program is
6
+ # strictly prohibited. Any use of this program by an authorized
7
+ # licensee is strictly subject to the terms and conditions,
8
+ # including confidentiality obligations, set forth in the applicable
9
+ # License Agreement between RightScale.com, Inc. and
10
+ # the licensee.
11
+
12
+ module RightScale
13
+
14
+ # Class which allows listening for data and sending data on sockets
15
+ # This allows other processes running on the same machine to send commands to
16
+ # the agent without having to go through RabbitMQ.
17
+ class CommandIO
18
+
19
+ include RightSupport::Ruby::EasySingleton
20
+
21
+ # ensure uniqueness of handler to avoid confusion.
22
+ raise "#{ServerInputHandler.name} is already defined" if defined?(ServerInputHandler)
23
+
24
+ # EventMachine connection
25
+ # Define event loop callbacks handler
26
+ module ServerInputHandler
27
+
28
+ # Keep block used to handle incoming data
29
+ #
30
+ # === Parameters
31
+ # handler(Proc):: Incoming data handler should take two arguments:
32
+ # * First argument contains command
33
+ # * Second argument contains connection used to reply
34
+ def initialize(handler)
35
+ @handler = handler
36
+ @parser = CommandParser.new { |cmd| handler.call(cmd, self) }
37
+ end
38
+
39
+ # EventMachine loop callback called whenever there is data coming from the socket
40
+ #
41
+ # === Parameter
42
+ # data(String):: Incoming data
43
+ #
44
+ # === Return
45
+ # true:: Always return true
46
+ def receive_data(data)
47
+ @parser.parse_chunk(data)
48
+ true
49
+ end
50
+
51
+ end
52
+
53
+ # Is listener currently waiting for input?
54
+ #
55
+ # === Return
56
+ # true:: If 'listen' was last called
57
+ # false:: Otherwise
58
+ def listening
59
+ !@conn.nil?
60
+ end
61
+
62
+ # Open command socket and wait for input on it
63
+ # This can only be called again after 'stop_listening' was called
64
+ #
65
+ # === Parameters
66
+ # socket_port(Integer):: Socket port on which to listen
67
+ #
68
+ # === Block
69
+ # The given block should take two arguments:
70
+ # * First argument will be given the commands sent through the socket
71
+ # Commands should be serialized using RightScale::CommandSerializer.
72
+ # * Second argument contains the connection that should be given back to
73
+ # +reply+ to send reply
74
+ #
75
+ # === Return
76
+ # true:: Always return true
77
+ #
78
+ # === Raise
79
+ # (ArgumentError):: If block is missing
80
+ # (Exceptions::Application):: If +listen+ has already been called and +stop+ hasn't since
81
+ # (Exceptions::Application):: If port is already bound
82
+ def listen(socket_port, &block)
83
+ raise ArgumentError, 'Missing listener block' unless block_given?
84
+ raise Exceptions::Application, 'Already listening' if listening
85
+ begin
86
+ @conn = EM.start_server('127.0.0.1', socket_port, ServerInputHandler, block)
87
+ rescue Exception => e
88
+ raise Exceptions::IO, 'Listen port unavailable' if e.message =~ /no acceptor/
89
+ end
90
+ true
91
+ end
92
+
93
+ # Stop listening for commands
94
+ # Do nothing if already stopped
95
+ #
96
+ # === Return
97
+ # true:: If command listener was listening
98
+ # false:: Otherwise
99
+ def stop_listening
100
+ res = !@conn.nil?
101
+ if res
102
+ EM.stop_server(@conn)
103
+ @conn = nil
104
+ end
105
+ res
106
+ end
107
+
108
+ # Write given data to socket, must be listening
109
+ #
110
+ # === Parameters
111
+ # conn(EM::Connection):: Connection used to send data
112
+ # data(String):: Data that should be written
113
+ # close_after_writing(TrueClass|FalseClass):: Whether TCP connection with client should be
114
+ # closed after reply is sent
115
+ #
116
+ # === Return
117
+ # true:: Always return true
118
+ def reply(conn, data, close_after_writing=true)
119
+ conn.send_data(CommandSerializer.dump(data))
120
+ conn.close_connection_after_writing if close_after_writing
121
+ true
122
+ end
123
+
124
+ end
125
+
126
+ end