right_agent 0.17.2 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. data/lib/right_agent.rb +0 -1
  2. data/lib/right_agent/agent_config.rb +1 -1
  3. data/lib/right_agent/minimal.rb +8 -7
  4. data/lib/right_agent/monkey_patches.rb +4 -2
  5. data/lib/right_agent/monkey_patches/ruby_patch.rb +9 -9
  6. data/lib/right_agent/monkey_patches/ruby_patch/linux_patch/file_patch.rb +2 -2
  7. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/file_patch.rb +21 -51
  8. data/lib/right_agent/packets.rb +5 -1
  9. data/lib/right_agent/platform.rb +727 -299
  10. data/lib/right_agent/platform/unix/darwin/platform.rb +102 -0
  11. data/lib/right_agent/platform/unix/linux/platform.rb +305 -0
  12. data/lib/right_agent/platform/unix/platform.rb +226 -0
  13. data/lib/right_agent/platform/windows/mingw/platform.rb +447 -0
  14. data/lib/right_agent/platform/windows/mswin/platform.rb +236 -0
  15. data/lib/right_agent/platform/windows/platform.rb +1808 -0
  16. data/right_agent.gemspec +13 -8
  17. data/spec/platform/spec_helper.rb +216 -0
  18. data/spec/platform/unix/darwin/platform_spec.rb +181 -0
  19. data/spec/platform/unix/linux/platform_spec.rb +540 -0
  20. data/spec/platform/unix/spec_helper.rb +149 -0
  21. data/spec/platform/windows/mingw/platform_spec.rb +222 -0
  22. data/spec/platform/windows/mswin/platform_spec.rb +259 -0
  23. data/spec/platform/windows/spec_helper.rb +720 -0
  24. metadata +45 -30
  25. data/lib/right_agent/platform/darwin.rb +0 -285
  26. data/lib/right_agent/platform/linux.rb +0 -537
  27. data/lib/right_agent/platform/windows.rb +0 -1384
  28. data/spec/platform/darwin_spec.rb +0 -13
  29. data/spec/platform/linux_spec.rb +0 -38
  30. data/spec/platform/linux_volume_manager_spec.rb +0 -201
  31. data/spec/platform/platform_spec.rb +0 -80
  32. data/spec/platform/windows_spec.rb +0 -13
  33. data/spec/platform/windows_volume_manager_spec.rb +0 -318
@@ -0,0 +1,102 @@
1
+ #
2
+ # Copyright (c) 2009-2013 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 ::File.expand_path('../../platform', __FILE__)
24
+
25
+ module RightScale
26
+
27
+ # Mac OS specific implementation
28
+ class Platform
29
+
30
+ # Provides utilities for managing volumes (disks).
31
+ class VolumeManager
32
+
33
+ # Overrides base VolumeManager#volumes
34
+ def volumes(conditions = nil)
35
+ raise ::NotImplementedError, 'Not yet supporting Mac OS volume query'
36
+ end
37
+
38
+ # Overrides base VolumeManager#mount_volume
39
+ def mount_volume(volume, mountpoint)
40
+ raise ::NotImplementedError, 'Not yet supporting Mac OS volume mounting'
41
+ end
42
+ end
43
+
44
+ class Shell
45
+
46
+ # Overrides base Shell#uptime
47
+ def uptime
48
+ return (Time.now.to_i.to_f - booted_at.to_f) rescue 0.0
49
+ end
50
+
51
+ # Overrides base Shell#booted_at
52
+ def booted_at
53
+ output_text = execute('sysctl kern.boottime')
54
+ match = /sec = ([0-9]+)/.match(output_text)
55
+ if match && (match[1].to_i > 0)
56
+ return match[1].to_i
57
+ else
58
+ return nil
59
+ end
60
+ end
61
+ end # Shell
62
+
63
+ class Controller
64
+
65
+ # Overrides base Controller#reboot
66
+ def reboot
67
+ execute('shutdown -r now 2>&1')
68
+ true
69
+ end
70
+
71
+ # Overrides base Controller#shutdown
72
+ def shutdown
73
+ execute('shutdown -h now 2>&1')
74
+ true
75
+ end
76
+ end # Controller
77
+
78
+ class Installer
79
+
80
+ # Overrides base Installer#install
81
+ def install(packages)
82
+ raise ::NotImplementedError, 'Not yet supporting Mac OS package install'
83
+ end
84
+ end # Installer
85
+
86
+ private
87
+
88
+ # Overrides base Platform#initialize_species
89
+ def initialize_species
90
+ @flavor = 'mac_os_x'
91
+ begin
92
+ @release = execute('sw_vers -productVersion 2>&1').strip
93
+ @codename = '' # TEAL FIX cannot find a way to query osx codename by CLI
94
+ rescue ::RightScale::Platform::CommandError
95
+ @release = @codename = 'unknown'
96
+ end
97
+ true
98
+ end
99
+
100
+ end # Platform
101
+
102
+ end # RightScale
@@ -0,0 +1,305 @@
1
+ #
2
+ # Copyright (c) 2009-2013 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 ::File.expand_path('../../platform', __FILE__)
24
+
25
+ module RightScale
26
+
27
+ # Linux specific implementation
28
+ class Platform
29
+
30
+ FEDORA_REL = '/etc/fedora-release'
31
+ FEDORA_SIG = /Fedora release ([0-9]+) \((.*)\)/
32
+
33
+ # Is this machine running Ubuntu?
34
+ #
35
+ # @return [TrueClass|FalseClass] true if Linux flavor is Ubuntu
36
+ def ubuntu?
37
+ !!(@flavor =~ /ubuntu/)
38
+ end
39
+
40
+ # Is this machine running CentOS?
41
+ #
42
+ # @return [TrueClass|FalseClass] true if Linux flavor is CentOS
43
+ def centos?
44
+ !!(@flavor =~ /centos/)
45
+ end
46
+
47
+ # Is this machine running Suse?
48
+ #
49
+ # @return [TrueClass|FalseClass] true if Linux flavor is Suse
50
+ def suse?
51
+ !!(@flavor =~ /suse/)
52
+ end
53
+
54
+ # Is this machine running RHEL?
55
+ #
56
+ # @return [TrueClass|FalseClass] true if Linux flavor is RHEL
57
+ def rhel?
58
+ !!(@flavor =~ /redhatenterpriseserver/)
59
+ end
60
+
61
+ # Provides utilities for managing volumes (disks).
62
+ class VolumeManager
63
+
64
+ # Overrides base VolumeManager#volumes
65
+ def volumes(conditions = nil)
66
+ blkid_resp = execute('blkid 2>&1')
67
+ return parse_volumes(blkid_resp, conditions)
68
+ rescue ::RightScale::Platform::CommandError => e
69
+ raise VolumeError, "Failed to list volumes: #{e.message}"
70
+ end
71
+
72
+ # Overrides base VolumeManager#mount_volume
73
+ def mount_volume(volume, mountpoint)
74
+ unless volume.is_a?(::Hash) && volume[:device]
75
+ raise ::ArgumentError, "Invalid volume argument = #{volume.inspect}"
76
+ end
77
+ mount_list_output = nil
78
+ begin
79
+ mount_list_output = execute('mount 2>&1')
80
+ rescue ::RightScale::Platform::CommandError => e
81
+ raise VolumeError, "Failed interrogation of current mounts: #{e.message}"
82
+ end
83
+
84
+ device_match = /^#{volume[:device]} on (.+?)\s/.match(mount_list_output)
85
+ mountpoint_from_device_match = device_match ? device_match[1] : mountpoint
86
+ unless (mountpoint_from_device_match && mountpoint_from_device_match == mountpoint)
87
+ raise VolumeError,
88
+ "Attempted to mount volume \"#{volume[:device]}\" at \"#{mountpoint}\" but it was already mounted at #{mountpoint_from_device_match}"
89
+ end
90
+
91
+ mountpoint_match = /^(.+?) on #{mountpoint}/.match(mount_list_output)
92
+ device_from_mountpoint_match = mountpoint_match ? mountpoint_match[1] : volume[:device]
93
+ unless (device_from_mountpoint_match && device_from_mountpoint_match == volume[:device])
94
+ raise VolumeError.new("Attempted to mount volume \"#{volume[:device]}\" at \"#{mountpoint}\" but \"#{device_from_mountpoint_match}\" was already mounted there.")
95
+ end
96
+
97
+ # The volume is already mounted at the correct mountpoint
98
+ return true if /^#{volume[:device]} on #{mountpoint}/.match(mount_list_output)
99
+
100
+ # TODO: Maybe validate that the mountpoint is valid *nix path?
101
+ begin
102
+ execute("mount -t #{volume[:filesystem].strip} #{volume[:device]} #{mountpoint} 2>&1")
103
+ rescue ::RightScale::Platform::CommandError => e
104
+ raise VolumeError, "Failed to mount volume to \"#{mountpoint}\" with device \"#{volume[:device]}\": #{e.message}"
105
+ end
106
+ true
107
+ end
108
+
109
+ private
110
+
111
+ # Parses raw output from `blkid` into a hash of volumes.
112
+ #
113
+ # The hash will contain the device name with a key of :device, and each
114
+ # key value pair for the device. In order to keep parity with the Windows
115
+ # VolumeManager.parse_volumes method, the :type key will be duplicated as
116
+ # :filesystem
117
+ #
118
+ # Example of raw output from `blkid`
119
+ # /dev/xvdh1: SEC_TYPE="msdos" LABEL="METADATA" UUID="681B-8C5D" TYPE="vfat"
120
+ # /dev/xvdb1: LABEL="SWAP-xvdb1" UUID="d51fcca0-6b10-4934-a572-f3898dfd8840" TYPE="swap"
121
+ # /dev/xvda1: UUID="f4746f9c-0557-4406-9267-5e918e87ca2e" TYPE="ext3"
122
+ # /dev/xvda2: UUID="14d88b9e-9fe6-4974-a8d6-180acdae4016" TYPE="ext3"
123
+ #
124
+ # @param [String] output_text from blkid
125
+ # @param [Hash] conditions to match (Default = no conditions)
126
+ #
127
+ # @return [Array] volume info as an array of hashes or empty
128
+ #
129
+ # @raise [ParserError] on failure to parse volume list
130
+ def parse_volumes(output_text, conditions = nil)
131
+ results = []
132
+ output_text.lines.each do |line|
133
+ volume = {}
134
+ line_regex = /^([\/a-z0-9_\-\.]+):(.*)/
135
+ volmatch = line_regex.match(line)
136
+ raise ParserError.new("Failed to parse volume info from #{line.inspect} using #{line_regex.inspect}") unless volmatch
137
+ volume[:device] = volmatch[1]
138
+ volmatch[2].split(' ').each do |pair|
139
+ pair_regex = /([a-zA-Z_\-]+)=(.*)/
140
+ match = pair_regex.match(pair)
141
+ raise ParserError.new("Failed to parse volume info from #{pair} using #{pair_regex.inspect}") unless match
142
+ volume[:"#{match[1].downcase}"] = match[2].gsub('"', '')
143
+ # Make this as much like the windows output as possible
144
+ if match[1] == 'TYPE'
145
+ volume[:filesystem] = match[2].gsub('"', '')
146
+ end
147
+ end
148
+ if conditions
149
+ matched = true
150
+ conditions.each do |key,value|
151
+ unless volume[key] == value
152
+ matched = false
153
+ break
154
+ end
155
+ end
156
+ results << volume if matched
157
+ else
158
+ results << volume
159
+ end
160
+ end
161
+ results
162
+ end
163
+ end # VolumeManager
164
+
165
+ class Shell
166
+
167
+ # Overrides base Shell#uptime
168
+ def uptime
169
+ return ::File.read('/proc/uptime').split(/\s+/)[0].to_f rescue 0.0
170
+ end
171
+
172
+ # Overrides base Shell#booted_at
173
+ def booted_at
174
+ match = /btime ([0-9]+)/.match(::File.read('/proc/stat')) rescue nil
175
+ if match && (match[1].to_i > 0)
176
+ return match[1].to_i
177
+ else
178
+ return nil
179
+ end
180
+ end
181
+ end # Shell
182
+
183
+ class Controller
184
+
185
+ # Overrides base Controller#reboot
186
+ def reboot
187
+ execute('init 6 2>&1')
188
+ true
189
+ end
190
+
191
+ # Overrides base Controller#shutdown
192
+ def shutdown
193
+ execute('init 0 2>&1')
194
+ true
195
+ end
196
+ end # Controller
197
+
198
+ class Installer
199
+
200
+ # Does this machine have aptitude?
201
+ #
202
+ # @return [TrueClass|FalseClass] true if aptitude is available in the expected directory
203
+ def aptitude?
204
+ ::File.executable? '/usr/bin/apt-get'
205
+ end
206
+
207
+ # Does this machine have yum?
208
+ #
209
+ # @return [TrueClass|FalseClass] true if yum is available in the expected directory
210
+ def yum?
211
+ ::File.executable? '/usr/bin/yum'
212
+ end
213
+
214
+ # Does this machine have zypper?
215
+ #
216
+ # @return [TrueClass|FalseClass] true if zypper is available in the expected directory
217
+ def zypper?
218
+ ::File.executable? '/usr/bin/zypper'
219
+ end
220
+
221
+ # Overrides base Installer#install
222
+ def install(packages)
223
+ packages = Array(packages)
224
+ return true if packages.empty?
225
+
226
+ packages = packages.uniq.join(' ')
227
+
228
+ if yum?
229
+ command = "yum install -y #{packages} 2>&1"
230
+ regex = /No package (.*) available\./
231
+ elsif aptitude?
232
+ old_debian_frontend = ENV['DEBIAN_FRONTEND']
233
+ ENV['DEBIAN_FRONTEND'] = 'noninteractive'
234
+ command = "apt-get install -y #{packages} 2>&1"
235
+ # note the error message for apt-get seems to have changed between
236
+ # versions of aptitude.
237
+ regex = /E: (Couldn't find package|Unable to locate package) (.*)/
238
+ elsif zypper?
239
+ command = "zypper --no-gpg-checks -n #{packages} 2>&1"
240
+ regex = /Package '(.*)' not found\./
241
+ else
242
+ raise PackageManagerNotFound,
243
+ 'No package manager binary (apt, yum, zypper) found in /usr/bin'
244
+ end
245
+
246
+ failed_packages = nil
247
+ begin
248
+ # TEAL FIX it's not clear from legacy implementation if having failed
249
+ # packages consistently exits non-zero from all supported installers.
250
+ # for that reason, also scan for failed packages on exit zero.
251
+ failed_packages = scan_for_failed_packages(execute(command), regex)
252
+ rescue ::RightScale::Platform::CommandError => e
253
+ # command could fail for reasons other than failed packages (e.g. not
254
+ # being sudo) but legacy code raised a specific error for failed
255
+ # packages.
256
+ failed_packages = scan_for_failed_packages(e.output_text, regex)
257
+ raise if failed_packages.empty?
258
+ ensure
259
+ ENV['DEBIAN_FRONTEND'] = old_debian_frontend if aptitude?
260
+ end
261
+ unless failed_packages.empty?
262
+ raise PackageNotFound,
263
+ "The following packages were not available: #{failed_packages.join(', ')}"
264
+ end
265
+ true
266
+ end
267
+
268
+ private
269
+
270
+ def scan_for_failed_packages(output_text, regex)
271
+ @output = output_text
272
+ failed_packages = []
273
+ output_text.scan(regex) { |package| failed_packages << package.last }
274
+ failed_packages
275
+ end
276
+ end # Installer
277
+
278
+ private
279
+
280
+ # Overrides base Platform#initialize_species
281
+ def initialize_species
282
+ # Use the lsb_release utility if it's available
283
+ begin
284
+ # TEAL FIX: not sure if we really need to check if --help succeeds or
285
+ # if we would only need to call lsb_release -is but that was the legacy
286
+ # behavior and retesting all supported flavors of Linux isn't trivial.
287
+ execute('lsb_release --help >/dev/null 2>&1')
288
+ @flavor = execute('lsb_release -is', :raise_on_failure => false).strip.downcase
289
+ @release = execute('lsb_release -rs', :raise_on_failure => false).strip
290
+ @codename = execute('lsb_release -cs', :raise_on_failure => false).strip
291
+ rescue ::RightScale::Platform::CommandError
292
+ if ::File.exist?(FEDORA_REL) && (match = FEDORA_SIG.match(::File.read(FEDORA_REL)))
293
+ # Parse the fedora-release file if it exists
294
+ @flavor = 'fedora'
295
+ @release = match[1]
296
+ @codename = match[2]
297
+ else
298
+ @flavor = @release = @codename = 'unknown'
299
+ end
300
+ end
301
+ true
302
+ end
303
+
304
+ end # Platform
305
+ end # RightScale
@@ -0,0 +1,226 @@
1
+ #
2
+ # Copyright (c) 2013 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 ::File.expand_path('../../../platform', __FILE__)
24
+
25
+ module RightScale
26
+
27
+ # Unix-specific implementation
28
+ class Platform
29
+
30
+ class Filesystem
31
+
32
+ # Overrides base Filesystem#find_executable_in_path
33
+ def find_executable_in_path(command_name)
34
+ ::ENV['PATH'].split(/;|:/).each do |dir|
35
+ path = ::File.join(dir, command_name)
36
+ return path if ::File.executable?(path)
37
+ end
38
+ return nil
39
+ end
40
+
41
+ # Overrides base Filesystem#right_agent_cfg_dir
42
+ def right_agent_cfg_dir
43
+ '/var/lib/rightscale/right_agent'
44
+ end
45
+
46
+ # Overrides base Filesystem#right_scale_static_state_dir
47
+ def right_scale_static_state_dir
48
+ '/etc/rightscale.d'
49
+ end
50
+
51
+ # Overrides base Filesystem#right_link_static_state_dir
52
+ def right_link_static_state_dir
53
+ '/etc/rightscale.d/right_link'
54
+ end
55
+
56
+ # Overrides base Filesystem#right_link_dynamic_state_dir
57
+ def right_link_dynamic_state_dir
58
+ '/var/lib/rightscale/right_link'
59
+ end
60
+
61
+ # Overrides base Filesystem#spool_dir
62
+ def spool_dir
63
+ '/var/spool'
64
+ end
65
+
66
+ # Overrides base Filesystem#ssh_cfg_dir
67
+ def ssh_cfg_dir
68
+ '/etc/ssh'
69
+ end
70
+
71
+ # Overrides base Filesystem#cache_dir
72
+ def cache_dir
73
+ '/var/cache'
74
+ end
75
+
76
+ # Overrides base Filesystem#log_dir
77
+ def log_dir
78
+ '/var/log'
79
+ end
80
+
81
+ # Overrides base Filesystem#source_code_dir
82
+ def source_code_dir
83
+ '/usr/src'
84
+ end
85
+
86
+ # Overrides base Filesystem#temp_dir
87
+ def temp_dir
88
+ '/tmp'
89
+ end
90
+
91
+ # Overrides base Filesystem#pid_dir
92
+ def pid_dir
93
+ '/var/run'
94
+ end
95
+
96
+ # Overrides base Filesystem#right_link_home_dir
97
+ def right_link_home_dir
98
+ # TEAL FIX could the user choose a different directory when installing
99
+ # the RightLink v5.9+ package manually?
100
+ '/opt/rightscale'
101
+ end
102
+
103
+ # Overrides base Filesystem#private_bin_dir
104
+ def private_bin_dir
105
+ ::File.join(right_link_home_dir, 'bin')
106
+ end
107
+
108
+ # Overrides base Filesystem#sandbox_dir
109
+ def sandbox_dir
110
+ ::File.join(right_link_home_dir, 'sandbox')
111
+ end
112
+
113
+ # Overrides base Filesystem#long_path_to_short_path
114
+ def long_path_to_short_path(long_path)
115
+ return long_path
116
+ end
117
+
118
+ # Overrides base Filesystem#pretty_path
119
+ def pretty_path(path, native_fs_flag = false)
120
+ return path
121
+ end
122
+
123
+ # Overrides base Filesystem#ensure_local_drive_path
124
+ def ensure_local_drive_path(path, temp_dir_name)
125
+ return path
126
+ end
127
+
128
+ # Overrides base Filesystem#create_symlink
129
+ def create_symlink(from_path, to_path)
130
+ ::File.symlink(from_path, to_path)
131
+ end
132
+ end
133
+
134
+ # Provides utilities for managing volumes (disks).
135
+ class VolumeManager
136
+
137
+ # Mounts a volume (returned by VolumeManager.volumes) to the mountpoint
138
+ # specified.
139
+ #
140
+ # @param [Hash] volume info hash (as returned by VolumeManager.volumes)
141
+ # @param [String] mountpoint where the device will be mounted in the file system
142
+ #
143
+ # @return [TrueClass] always true
144
+ #
145
+ # @raise [VolumeError] on a failure to mount the device
146
+ def mount_volume(volume, mountpoint)
147
+ must_be_overridden
148
+ end
149
+ end # VolumeManager
150
+
151
+ class Shell
152
+ # defined for backward compatibility; use Shell#null_output_name
153
+ NULL_OUTPUT_NAME = '/dev/null'
154
+
155
+ # Overrides base Shell#null_output_name
156
+ def null_output_name
157
+ NULL_OUTPUT_NAME
158
+ end
159
+
160
+ # Overrides base Shell#format_script_file_name
161
+ def format_script_file_name(partial_script_file_path, default_extension = nil)
162
+ # shell files containing shebang are directly executable in Unix, so
163
+ # assume our scripts have shebang. if not, the error should be obvious.
164
+ return partial_script_file_path
165
+ end
166
+
167
+ # Overrides base Shell#format_executable_command
168
+ def format_executable_command(executable_file_path, *arguments)
169
+ escaped = []
170
+ space = ' '
171
+ double_quote = '"'
172
+ single_quote = "'"
173
+ [executable_file_path, arguments].flatten.each do |arg|
174
+ value = arg.to_s
175
+ needs_escape =
176
+ value.index(space) ||
177
+ value.index(double_quote) ||
178
+ value.index(single_quote)
179
+ escaped << (needs_escape ? "\"#{value.gsub(double_quote, "\\\"")}\"" : value)
180
+ end
181
+ return escaped.join(space)
182
+ end
183
+
184
+ # Overrides base Shell#format_shell_command
185
+ def format_shell_command(shell_script_file_path, *arguments)
186
+ # shell files containing shebang are directly executable in Unix, so
187
+ # assume our scripts have shebang. if not, the error should be obvious.
188
+ return format_executable_command(shell_script_file_path, arguments)
189
+ end
190
+
191
+ # Overrides base Shell#sandbox_ruby
192
+ def sandbox_ruby
193
+ "#{::RightScale::Platform.filesystem.sandbox_dir}/bin/ruby"
194
+ end
195
+ end
196
+
197
+ class Rng
198
+
199
+ # Overrides base Rng#pseudorandom_bytes
200
+ def pseudorandom_bytes(count)
201
+ result = nil
202
+ ::File.open('/dev/urandom', 'r') { |f| result = f.read(count) }
203
+ result
204
+ end
205
+ end
206
+
207
+ class Process
208
+
209
+ # Overrides base Process#resident_set_size
210
+ def resident_set_size(pid = nil)
211
+ pid = $$ unless pid
212
+ output_text = execute("ps -o rss= -p #{pid}")
213
+ return output_text.to_i
214
+ end
215
+ end
216
+
217
+ private
218
+
219
+ # Overrides base Platform#initialize_genus
220
+ def initialize_genus
221
+ true # do nothing
222
+ end
223
+
224
+ end # Platform
225
+
226
+ end # RightScale