right_agent 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. data/LICENSE +20 -0
  2. data/README.rdoc +78 -0
  3. data/Rakefile +86 -0
  4. data/lib/right_agent.rb +66 -0
  5. data/lib/right_agent/actor.rb +163 -0
  6. data/lib/right_agent/actor_registry.rb +76 -0
  7. data/lib/right_agent/actors/agent_manager.rb +189 -0
  8. data/lib/right_agent/agent.rb +735 -0
  9. data/lib/right_agent/agent_config.rb +403 -0
  10. data/lib/right_agent/agent_identity.rb +209 -0
  11. data/lib/right_agent/agent_tags_manager.rb +213 -0
  12. data/lib/right_agent/audit_formatter.rb +107 -0
  13. data/lib/right_agent/broker_client.rb +683 -0
  14. data/lib/right_agent/command.rb +30 -0
  15. data/lib/right_agent/command/agent_manager_commands.rb +134 -0
  16. data/lib/right_agent/command/command_client.rb +136 -0
  17. data/lib/right_agent/command/command_constants.rb +42 -0
  18. data/lib/right_agent/command/command_io.rb +128 -0
  19. data/lib/right_agent/command/command_parser.rb +87 -0
  20. data/lib/right_agent/command/command_runner.rb +105 -0
  21. data/lib/right_agent/command/command_serializer.rb +63 -0
  22. data/lib/right_agent/console.rb +65 -0
  23. data/lib/right_agent/core_payload_types.rb +42 -0
  24. data/lib/right_agent/core_payload_types/cookbook.rb +61 -0
  25. data/lib/right_agent/core_payload_types/cookbook_position.rb +46 -0
  26. data/lib/right_agent/core_payload_types/cookbook_repository.rb +116 -0
  27. data/lib/right_agent/core_payload_types/cookbook_sequence.rb +70 -0
  28. data/lib/right_agent/core_payload_types/dev_repositories.rb +90 -0
  29. data/lib/right_agent/core_payload_types/event_categories.rb +38 -0
  30. data/lib/right_agent/core_payload_types/executable_bundle.rb +138 -0
  31. data/lib/right_agent/core_payload_types/login_policy.rb +72 -0
  32. data/lib/right_agent/core_payload_types/login_user.rb +62 -0
  33. data/lib/right_agent/core_payload_types/planned_volume.rb +94 -0
  34. data/lib/right_agent/core_payload_types/recipe_instantiation.rb +60 -0
  35. data/lib/right_agent/core_payload_types/repositories_bundle.rb +50 -0
  36. data/lib/right_agent/core_payload_types/right_script_attachment.rb +95 -0
  37. data/lib/right_agent/core_payload_types/right_script_instantiation.rb +73 -0
  38. data/lib/right_agent/core_payload_types/secure_document.rb +66 -0
  39. data/lib/right_agent/core_payload_types/secure_document_location.rb +63 -0
  40. data/lib/right_agent/core_payload_types/software_repository_instantiation.rb +61 -0
  41. data/lib/right_agent/daemonize.rb +35 -0
  42. data/lib/right_agent/dispatcher.rb +348 -0
  43. data/lib/right_agent/enrollment_result.rb +217 -0
  44. data/lib/right_agent/exceptions.rb +30 -0
  45. data/lib/right_agent/ha_broker_client.rb +1278 -0
  46. data/lib/right_agent/idempotent_request.rb +140 -0
  47. data/lib/right_agent/log.rb +418 -0
  48. data/lib/right_agent/monkey_patches.rb +29 -0
  49. data/lib/right_agent/monkey_patches/amqp_patch.rb +274 -0
  50. data/lib/right_agent/monkey_patches/ruby_patch.rb +49 -0
  51. data/lib/right_agent/monkey_patches/ruby_patch/array_patch.rb +29 -0
  52. data/lib/right_agent/monkey_patches/ruby_patch/darwin_patch.rb +24 -0
  53. data/lib/right_agent/monkey_patches/ruby_patch/linux_patch.rb +24 -0
  54. data/lib/right_agent/monkey_patches/ruby_patch/linux_patch/file_patch.rb +30 -0
  55. data/lib/right_agent/monkey_patches/ruby_patch/object_patch.rb +49 -0
  56. data/lib/right_agent/monkey_patches/ruby_patch/singleton_patch.rb +46 -0
  57. data/lib/right_agent/monkey_patches/ruby_patch/string_patch.rb +107 -0
  58. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch.rb +32 -0
  59. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/file_patch.rb +90 -0
  60. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/process_patch.rb +63 -0
  61. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/stdio_patch.rb +27 -0
  62. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/time_patch.rb +55 -0
  63. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/win32ole_patch.rb +34 -0
  64. data/lib/right_agent/multiplexer.rb +91 -0
  65. data/lib/right_agent/operation_result.rb +270 -0
  66. data/lib/right_agent/packets.rb +637 -0
  67. data/lib/right_agent/payload_formatter.rb +104 -0
  68. data/lib/right_agent/pid_file.rb +159 -0
  69. data/lib/right_agent/platform.rb +319 -0
  70. data/lib/right_agent/platform/darwin.rb +227 -0
  71. data/lib/right_agent/platform/linux.rb +268 -0
  72. data/lib/right_agent/platform/windows.rb +1204 -0
  73. data/lib/right_agent/scripts/agent_controller.rb +522 -0
  74. data/lib/right_agent/scripts/agent_deployer.rb +379 -0
  75. data/lib/right_agent/scripts/common_parser.rb +153 -0
  76. data/lib/right_agent/scripts/log_level_manager.rb +193 -0
  77. data/lib/right_agent/scripts/stats_manager.rb +256 -0
  78. data/lib/right_agent/scripts/usage.rb +58 -0
  79. data/lib/right_agent/secure_identity.rb +92 -0
  80. data/lib/right_agent/security.rb +32 -0
  81. data/lib/right_agent/security/cached_certificate_store_proxy.rb +63 -0
  82. data/lib/right_agent/security/certificate.rb +102 -0
  83. data/lib/right_agent/security/certificate_cache.rb +89 -0
  84. data/lib/right_agent/security/distinguished_name.rb +56 -0
  85. data/lib/right_agent/security/encrypted_document.rb +84 -0
  86. data/lib/right_agent/security/rsa_key_pair.rb +76 -0
  87. data/lib/right_agent/security/signature.rb +86 -0
  88. data/lib/right_agent/security/static_certificate_store.rb +69 -0
  89. data/lib/right_agent/sender.rb +937 -0
  90. data/lib/right_agent/serialize.rb +29 -0
  91. data/lib/right_agent/serialize/message_pack.rb +102 -0
  92. data/lib/right_agent/serialize/secure_serializer.rb +131 -0
  93. data/lib/right_agent/serialize/secure_serializer_initializer.rb +47 -0
  94. data/lib/right_agent/serialize/serializable.rb +135 -0
  95. data/lib/right_agent/serialize/serializer.rb +149 -0
  96. data/lib/right_agent/stats_helper.rb +731 -0
  97. data/lib/right_agent/subprocess.rb +38 -0
  98. data/lib/right_agent/tracer.rb +124 -0
  99. data/right_agent.gemspec +60 -0
  100. data/spec/actor_registry_spec.rb +81 -0
  101. data/spec/actor_spec.rb +99 -0
  102. data/spec/agent_config_spec.rb +226 -0
  103. data/spec/agent_identity_spec.rb +75 -0
  104. data/spec/agent_spec.rb +571 -0
  105. data/spec/broker_client_spec.rb +961 -0
  106. data/spec/command/agent_manager_commands_spec.rb +51 -0
  107. data/spec/command/command_io_spec.rb +93 -0
  108. data/spec/command/command_parser_spec.rb +79 -0
  109. data/spec/command/command_runner_spec.rb +72 -0
  110. data/spec/command/command_serializer_spec.rb +51 -0
  111. data/spec/core_payload_types/dev_repositories_spec.rb +64 -0
  112. data/spec/core_payload_types/executable_bundle_spec.rb +59 -0
  113. data/spec/core_payload_types/login_user_spec.rb +98 -0
  114. data/spec/core_payload_types/right_script_attachment_spec.rb +65 -0
  115. data/spec/core_payload_types/spec_helper.rb +23 -0
  116. data/spec/dispatcher_spec.rb +372 -0
  117. data/spec/enrollment_result_spec.rb +53 -0
  118. data/spec/ha_broker_client_spec.rb +1673 -0
  119. data/spec/idempotent_request_spec.rb +136 -0
  120. data/spec/log_spec.rb +177 -0
  121. data/spec/monkey_patches/amqp_patch_spec.rb +100 -0
  122. data/spec/monkey_patches/eventmachine_spec.rb +62 -0
  123. data/spec/monkey_patches/string_patch_spec.rb +99 -0
  124. data/spec/multiplexer_spec.rb +48 -0
  125. data/spec/operation_result_spec.rb +171 -0
  126. data/spec/packets_spec.rb +418 -0
  127. data/spec/platform/platform_spec.rb +60 -0
  128. data/spec/results_mock.rb +45 -0
  129. data/spec/secure_identity_spec.rb +50 -0
  130. data/spec/security/cached_certificate_store_proxy_spec.rb +56 -0
  131. data/spec/security/certificate_cache_spec.rb +71 -0
  132. data/spec/security/certificate_spec.rb +49 -0
  133. data/spec/security/distinguished_name_spec.rb +46 -0
  134. data/spec/security/encrypted_document_spec.rb +55 -0
  135. data/spec/security/rsa_key_pair_spec.rb +55 -0
  136. data/spec/security/signature_spec.rb +66 -0
  137. data/spec/security/static_certificate_store_spec.rb +52 -0
  138. data/spec/sender_spec.rb +887 -0
  139. data/spec/serialize/message_pack_spec.rb +131 -0
  140. data/spec/serialize/secure_serializer_spec.rb +102 -0
  141. data/spec/serialize/serializable_spec.rb +90 -0
  142. data/spec/serialize/serializer_spec.rb +174 -0
  143. data/spec/spec.opts +2 -0
  144. data/spec/spec_helper.rb +77 -0
  145. data/spec/stats_helper_spec.rb +681 -0
  146. data/spec/tracer_spec.rb +114 -0
  147. metadata +320 -0
@@ -0,0 +1,227 @@
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
+ # Mac OS specific implementation
26
+ class Platform
27
+
28
+ attr_reader :flavor, :release
29
+
30
+ # Initialize flavor and release
31
+ def init
32
+ @flavor = 'mac_os_x'
33
+ @release = `sw_vers -productVersion`
34
+ end
35
+
36
+ class Filesystem
37
+
38
+ # Is given command available in the PATH?
39
+ #
40
+ # === Parameters
41
+ # command_name(String):: Name of command to be tested
42
+ #
43
+ # === Return
44
+ # true:: If command is in path
45
+ # false:: Otherwise
46
+ def has_executable_in_path(command_name)
47
+ return nil != find_executable_in_path(command_name)
48
+ end
49
+
50
+ # Finds the given command name in the PATH. this emulates the 'which'
51
+ # command from linux (without the terminating newline).
52
+ #
53
+ # === Parameters
54
+ # command_name(String):: Name of command to be tested
55
+ #
56
+ # === Return
57
+ # path to first matching executable file in PATH or nil
58
+ def find_executable_in_path(command_name)
59
+ ENV['PATH'].split(/;|:/).each do |dir|
60
+ path = File.join(dir, command_name)
61
+ return path if File.executable?(path)
62
+ end
63
+ return nil
64
+ end
65
+
66
+ # Path to directory containing generated agent configuration files
67
+ def cfg_dir
68
+ '/etc/right_agent'
69
+ end
70
+
71
+ def right_scale_state_dir
72
+ '/etc/rightscale.d'
73
+ end
74
+
75
+ def spool_dir
76
+ '/var/spool'
77
+ end
78
+
79
+ def cache_dir
80
+ '/var/cache/rightscale'
81
+ end
82
+
83
+ def log_dir
84
+ '/var/log'
85
+ end
86
+
87
+ def temp_dir
88
+ '/tmp'
89
+ end
90
+
91
+ # Path to place pid files
92
+ def pid_dir
93
+ '/var/run'
94
+ end
95
+
96
+ def right_link_dir
97
+ '/opt/rightscale/right_link'
98
+ end
99
+
100
+ # Path to right link configuration and internal usage scripts
101
+ def private_bin_dir
102
+ '/opt/rightscale/bin'
103
+ end
104
+
105
+ def sandbox_dir
106
+ '/opt/rightscale/sandbox'
107
+ end
108
+
109
+ # for windows compatibility; has no significance in darwin
110
+ def long_path_to_short_path(long_path)
111
+ return long_path
112
+ end
113
+
114
+ # for windows compatibility; has no significance in darwin
115
+ def pretty_path(path, native_fs_flag = false)
116
+ return path
117
+ end
118
+
119
+ # for windows compatibility; has no significance in linux
120
+ def ensure_local_drive_path(path, temp_dir_name)
121
+ return path
122
+ end
123
+
124
+ # for windows compatibility; just use File.symlink on Mac
125
+ def create_symlink(old_name, new_name)
126
+ File.symlink(old_name, new_name)
127
+ end
128
+ end # Filesystem
129
+
130
+ # Provides utilities for managing volumes (disks).
131
+ class VolumeManager
132
+ def initialize
133
+ raise "not yet implemented"
134
+ end
135
+ end
136
+
137
+ class Shell
138
+
139
+ NULL_OUTPUT_NAME = "/dev/null"
140
+
141
+ def format_script_file_name(partial_script_file_path, default_extension = nil)
142
+ # shell file extensions are not required in darwin assuming the script
143
+ # contains a shebang. if not, the error should be obvious.
144
+ return partial_script_file_path
145
+ end
146
+
147
+ def format_executable_command(executable_file_path, *arguments)
148
+ escaped = []
149
+ [executable_file_path, arguments].flatten.each do |arg|
150
+ value = arg.to_s
151
+ needs_escape = value.index(" ") || value.index("\"") || value.index("'")
152
+ escaped << (needs_escape ? "\"#{value.gsub("\"", "\\\"")}\"" : value)
153
+ end
154
+ return escaped.join(" ")
155
+ end
156
+
157
+ def format_shell_command(shell_script_file_path, *arguments)
158
+ # shell files containing shebang are directly executable in darwin, so
159
+ # assume our scripts have shebang. if not, the error should be obvious.
160
+ return format_executable_command(shell_script_file_path, arguments)
161
+ end
162
+
163
+ def format_redirect_stdout(cmd, target = NULL_OUTPUT_NAME)
164
+ return cmd + " 1>#{target}"
165
+ end
166
+
167
+ def format_redirect_stderr(cmd, target = NULL_OUTPUT_NAME)
168
+ return cmd + " 2>#{target}"
169
+ end
170
+
171
+ def format_redirect_both(cmd, target = NULL_OUTPUT_NAME)
172
+ return cmd + " 1>#{target} 2>&1"
173
+ end
174
+
175
+ def sandbox_ruby
176
+ "#{RightScale::Platform.filesystem.sandbox_dir}/bin/ruby"
177
+ end
178
+
179
+ # Gets the current system uptime.
180
+ #
181
+ # === Return
182
+ # the time the machine has been up in seconds, 0 if there was an error.
183
+ def uptime
184
+ return (Time.now.to_i.to_f - booted_at.to_f) rescue 0.0
185
+ end
186
+
187
+ # Gets the time at which the system was booted
188
+ #
189
+ # === Return
190
+ # the UTC timestamp at which the system was booted
191
+ def booted_at
192
+ match = /sec = ([0-9]+)/.match(`sysctl kern.boottime`)
193
+
194
+ if match && (match[1].to_i > 0)
195
+ return match[1].to_i
196
+ else
197
+ return nil
198
+ end
199
+ end
200
+
201
+ end # Shell
202
+
203
+ class Controller
204
+ # Shutdown machine now
205
+ def shutdown
206
+ `shutdown -h now`
207
+ end
208
+
209
+ # Reboot machine now
210
+ def reboot
211
+ `shutdown -r now`
212
+ end
213
+ end
214
+
215
+ class Rng
216
+ def pseudorandom_bytes(count)
217
+ f = File.open('/dev/urandom', 'r')
218
+ bytes = f.read(count)
219
+ f.close
220
+
221
+ bytes
222
+ end
223
+ end
224
+
225
+ end # Platform
226
+
227
+ end # RightScale
@@ -0,0 +1,268 @@
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
+ # Linux specific implementation
26
+ class Platform
27
+
28
+ FEDORA_REL = '/etc/fedora-release'
29
+ FEDORA_SIG = /Fedora release ([0-9]+) \(.*\)/
30
+
31
+ attr_reader :flavor, :release, :codename
32
+
33
+ # Initialize flavor, release and codename
34
+ def init
35
+ system('lsb_release --help > /dev/null 2>&1')
36
+ if $?.success?
37
+ # Use the lsb_release utility if it's available
38
+ @flavor = `lsb_release -is`.strip.downcase
39
+ @release = `lsb_release -rs`.strip
40
+ @codename = `lsb_release -cs`.strip
41
+ elsif File.exist?(FEDORA_REL) && (match = FEDORA_SIG.match(File.read(FEDORA_REL)))
42
+ # Parse the fedora-release file if it exists
43
+ @flavor = 'fedora'
44
+ @release = match[1]
45
+ @codename = match[2]
46
+ else
47
+ @distro = @release = @codename = 'unknown'
48
+ end
49
+ end
50
+
51
+ # Is this machine running Ubuntu?
52
+ #
53
+ # === Return
54
+ # true:: If Linux flavor is Ubuntu
55
+ # false:: Otherwise
56
+ def ubuntu?
57
+ @flavor =~ /ubuntu/
58
+ end
59
+
60
+ # Is this machine running CentOS?
61
+ #
62
+ # === Return
63
+ # true:: If Linux flavor is CentOS
64
+ # false:: Otherwise
65
+ def centos?
66
+ @flavor =~ /centos/
67
+ end
68
+
69
+ # Is this machine running Suse
70
+ #
71
+ # === Return
72
+ # true:: If Linux flavor is Suse
73
+ # false:: Otherwise
74
+ def suse?
75
+ @flavor =~ /suse/
76
+ end
77
+
78
+ class Filesystem
79
+
80
+ # Is given command available in the PATH?
81
+ #
82
+ # === Parameters
83
+ # command_name(String):: Name of command to be tested
84
+ #
85
+ # === Return
86
+ # true:: If command is in path
87
+ # false:: Otherwise
88
+ def has_executable_in_path(command_name)
89
+ return nil != find_executable_in_path(command_name)
90
+ end
91
+
92
+ # Finds the given command name in the PATH. this emulates the 'which'
93
+ # command from linux (without the terminating newline).
94
+ #
95
+ # === Parameters
96
+ # command_name(String):: Name of command to be tested
97
+ #
98
+ # === Return
99
+ # path to first matching executable file in PATH or nil
100
+ def find_executable_in_path(command_name)
101
+ ENV['PATH'].split(/;|:/).each do |dir|
102
+ path = File.join(dir, command_name)
103
+ return path if File.executable?(path)
104
+ end
105
+ return nil
106
+ end
107
+
108
+ # Path to directory containing generated agent configuration files
109
+ def cfg_dir
110
+ '/etc/right_agent'
111
+ end
112
+
113
+ def right_scale_state_dir
114
+ '/etc/rightscale.d'
115
+ end
116
+
117
+ def spool_dir
118
+ '/var/spool'
119
+ end
120
+
121
+ def cache_dir
122
+ '/var/cache'
123
+ end
124
+
125
+ def log_dir
126
+ '/var/log'
127
+ end
128
+
129
+ def temp_dir
130
+ '/tmp'
131
+ end
132
+
133
+ # Path to place pid files
134
+ def pid_dir
135
+ '/var/run'
136
+ end
137
+
138
+ def right_link_dir
139
+ '/opt/rightscale/right_link'
140
+ end
141
+
142
+ # Path to right link configuration and internal usage scripts
143
+ def private_bin_dir
144
+ '/opt/rightscale/bin'
145
+ end
146
+
147
+ def sandbox_dir
148
+ '/opt/rightscale/sandbox'
149
+ end
150
+
151
+ # for windows compatibility; has no significance in linux
152
+ def long_path_to_short_path(long_path)
153
+ return long_path
154
+ end
155
+
156
+ # for windows compatibility; has no significance in linux
157
+ def pretty_path(path, native_fs_flag = false)
158
+ return path
159
+ end
160
+
161
+ # for windows compatibility; has no significance in linux
162
+ def ensure_local_drive_path(path, temp_dir_name)
163
+ return path
164
+ end
165
+
166
+ # for windows compatibility; just use File.symlink on Linux
167
+ def create_symlink(old_name, new_name)
168
+ File.symlink(old_name, new_name)
169
+ end
170
+ end
171
+
172
+ # Provides utilities for managing volumes (disks).
173
+ class VolumeManager
174
+ def initialize
175
+ raise "not yet implemented"
176
+ end
177
+ end
178
+
179
+ class Shell
180
+
181
+ NULL_OUTPUT_NAME = "/dev/null"
182
+
183
+ def format_script_file_name(partial_script_file_path, default_extension = nil)
184
+ # shell file extensions are not required in linux assuming the script
185
+ # contains a shebang. if not, the error should be obvious.
186
+ return partial_script_file_path
187
+ end
188
+
189
+ def format_executable_command(executable_file_path, *arguments)
190
+ escaped = []
191
+ [executable_file_path, arguments].flatten.each do |arg|
192
+ value = arg.to_s
193
+ needs_escape = value.index(" ") || value.index("\"") || value.index("'")
194
+ escaped << (needs_escape ? "\"#{value.gsub("\"", "\\\"")}\"" : value)
195
+ end
196
+ return escaped.join(" ")
197
+ end
198
+
199
+ def format_shell_command(shell_script_file_path, *arguments)
200
+ # shell files containing shebang are directly executable in linux, so
201
+ # assume our scripts have shebang. if not, the error should be obvious.
202
+ return format_executable_command(shell_script_file_path, arguments)
203
+ end
204
+
205
+ def format_redirect_stdout(cmd, target = NULL_OUTPUT_NAME)
206
+ return cmd + " 1>#{target}"
207
+ end
208
+
209
+ def format_redirect_stderr(cmd, target = NULL_OUTPUT_NAME)
210
+ return cmd + " 2>#{target}"
211
+ end
212
+
213
+ def format_redirect_both(cmd, target = NULL_OUTPUT_NAME)
214
+ return cmd + " 1>#{target} 2>&1"
215
+ end
216
+
217
+ def sandbox_ruby
218
+ "#{RightScale::Platform.filesystem.sandbox_dir}/bin/ruby"
219
+ end
220
+
221
+ # Gets the current system uptime.
222
+ #
223
+ # === Return
224
+ # the time the machine has been up in seconds, 0 if there was an error.
225
+ def uptime
226
+ return File.read('/proc/uptime').split(/\s+/)[0].to_f rescue 0.0
227
+ end
228
+
229
+ # Gets the time at which the system was booted
230
+ #
231
+ # === Return
232
+ # the UTC timestamp at which the system was booted
233
+ def booted_at
234
+ match = /btime ([0-9]+)/.match(File.read('/proc/stat')) rescue nil
235
+
236
+ if match && (match[1].to_i > 0)
237
+ return match[1].to_i
238
+ else
239
+ return nil
240
+ end
241
+ end
242
+ end
243
+
244
+ class Controller
245
+ # Shutdown machine now
246
+ def shutdown
247
+ `init 0`
248
+ end
249
+
250
+ # Reboot machine now
251
+ def reboot
252
+ `init 6`
253
+ end
254
+ end
255
+
256
+ class Rng
257
+ def pseudorandom_bytes(count)
258
+ f = File.open('/dev/urandom', 'r')
259
+ bytes = f.read(count)
260
+ f.close
261
+
262
+ bytes
263
+ end
264
+ end
265
+
266
+ end # Platform
267
+
268
+ end # RightScale