right_agent 2.0.7-x86-mingw32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +20 -0
- data/README.rdoc +82 -0
- data/Rakefile +113 -0
- data/lib/right_agent.rb +59 -0
- data/lib/right_agent/actor.rb +182 -0
- data/lib/right_agent/actor_registry.rb +76 -0
- data/lib/right_agent/actors/agent_manager.rb +232 -0
- data/lib/right_agent/agent.rb +1149 -0
- data/lib/right_agent/agent_config.rb +480 -0
- data/lib/right_agent/agent_identity.rb +210 -0
- data/lib/right_agent/agent_tag_manager.rb +237 -0
- data/lib/right_agent/audit_formatter.rb +107 -0
- data/lib/right_agent/clients.rb +31 -0
- data/lib/right_agent/clients/api_client.rb +383 -0
- data/lib/right_agent/clients/auth_client.rb +247 -0
- data/lib/right_agent/clients/balanced_http_client.rb +369 -0
- data/lib/right_agent/clients/base_retry_client.rb +495 -0
- data/lib/right_agent/clients/right_http_client.rb +279 -0
- data/lib/right_agent/clients/router_client.rb +493 -0
- data/lib/right_agent/command.rb +30 -0
- data/lib/right_agent/command/agent_manager_commands.rb +150 -0
- data/lib/right_agent/command/command_client.rb +136 -0
- data/lib/right_agent/command/command_constants.rb +33 -0
- data/lib/right_agent/command/command_io.rb +126 -0
- data/lib/right_agent/command/command_parser.rb +87 -0
- data/lib/right_agent/command/command_runner.rb +118 -0
- data/lib/right_agent/command/command_serializer.rb +63 -0
- data/lib/right_agent/connectivity_checker.rb +179 -0
- data/lib/right_agent/console.rb +65 -0
- data/lib/right_agent/core_payload_types.rb +44 -0
- data/lib/right_agent/core_payload_types/cookbook.rb +61 -0
- data/lib/right_agent/core_payload_types/cookbook_position.rb +46 -0
- data/lib/right_agent/core_payload_types/cookbook_repository.rb +116 -0
- data/lib/right_agent/core_payload_types/cookbook_sequence.rb +70 -0
- data/lib/right_agent/core_payload_types/dev_repositories.rb +100 -0
- data/lib/right_agent/core_payload_types/dev_repository.rb +76 -0
- data/lib/right_agent/core_payload_types/event_categories.rb +38 -0
- data/lib/right_agent/core_payload_types/executable_bundle.rb +130 -0
- data/lib/right_agent/core_payload_types/login_policy.rb +72 -0
- data/lib/right_agent/core_payload_types/login_user.rb +79 -0
- data/lib/right_agent/core_payload_types/planned_volume.rb +94 -0
- data/lib/right_agent/core_payload_types/recipe_instantiation.rb +73 -0
- data/lib/right_agent/core_payload_types/repositories_bundle.rb +50 -0
- data/lib/right_agent/core_payload_types/right_script_attachment.rb +95 -0
- data/lib/right_agent/core_payload_types/right_script_instantiation.rb +94 -0
- data/lib/right_agent/core_payload_types/runlist_policy.rb +44 -0
- data/lib/right_agent/core_payload_types/secure_document.rb +66 -0
- data/lib/right_agent/core_payload_types/secure_document_location.rb +63 -0
- data/lib/right_agent/core_payload_types/software_repository_instantiation.rb +61 -0
- data/lib/right_agent/daemonize.rb +35 -0
- data/lib/right_agent/dispatched_cache.rb +109 -0
- data/lib/right_agent/dispatcher.rb +272 -0
- data/lib/right_agent/enrollment_result.rb +221 -0
- data/lib/right_agent/exceptions.rb +87 -0
- data/lib/right_agent/history.rb +145 -0
- data/lib/right_agent/log.rb +460 -0
- data/lib/right_agent/minimal.rb +46 -0
- data/lib/right_agent/monkey_patches.rb +30 -0
- data/lib/right_agent/monkey_patches/ruby_patch.rb +55 -0
- data/lib/right_agent/monkey_patches/ruby_patch/array_patch.rb +29 -0
- data/lib/right_agent/monkey_patches/ruby_patch/darwin_patch.rb +24 -0
- data/lib/right_agent/monkey_patches/ruby_patch/linux_patch.rb +24 -0
- data/lib/right_agent/monkey_patches/ruby_patch/linux_patch/file_patch.rb +30 -0
- data/lib/right_agent/monkey_patches/ruby_patch/object_patch.rb +49 -0
- data/lib/right_agent/monkey_patches/ruby_patch/windows_patch.rb +32 -0
- data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/file_patch.rb +60 -0
- data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/process_patch.rb +63 -0
- data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/stdio_patch.rb +27 -0
- data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/time_patch.rb +55 -0
- data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/win32ole_patch.rb +34 -0
- data/lib/right_agent/multiplexer.rb +102 -0
- data/lib/right_agent/offline_handler.rb +270 -0
- data/lib/right_agent/operation_result.rb +300 -0
- data/lib/right_agent/packets.rb +673 -0
- data/lib/right_agent/payload_formatter.rb +104 -0
- data/lib/right_agent/pending_requests.rb +128 -0
- data/lib/right_agent/pid_file.rb +159 -0
- data/lib/right_agent/platform.rb +770 -0
- data/lib/right_agent/platform/unix/darwin/platform.rb +102 -0
- data/lib/right_agent/platform/unix/linux/platform.rb +305 -0
- data/lib/right_agent/platform/unix/platform.rb +226 -0
- data/lib/right_agent/platform/windows/mingw/platform.rb +447 -0
- data/lib/right_agent/platform/windows/mswin/platform.rb +236 -0
- data/lib/right_agent/platform/windows/platform.rb +1808 -0
- data/lib/right_agent/protocol_version_mixin.rb +69 -0
- data/lib/right_agent/retryable_request.rb +195 -0
- data/lib/right_agent/scripts/agent_controller.rb +543 -0
- data/lib/right_agent/scripts/agent_deployer.rb +400 -0
- data/lib/right_agent/scripts/common_parser.rb +160 -0
- data/lib/right_agent/scripts/log_level_manager.rb +192 -0
- data/lib/right_agent/scripts/stats_manager.rb +268 -0
- data/lib/right_agent/scripts/usage.rb +58 -0
- data/lib/right_agent/secure_identity.rb +92 -0
- data/lib/right_agent/security.rb +32 -0
- data/lib/right_agent/security/cached_certificate_store_proxy.rb +77 -0
- data/lib/right_agent/security/certificate.rb +102 -0
- data/lib/right_agent/security/certificate_cache.rb +89 -0
- data/lib/right_agent/security/distinguished_name.rb +56 -0
- data/lib/right_agent/security/encrypted_document.rb +83 -0
- data/lib/right_agent/security/rsa_key_pair.rb +76 -0
- data/lib/right_agent/security/signature.rb +86 -0
- data/lib/right_agent/security/static_certificate_store.rb +85 -0
- data/lib/right_agent/sender.rb +792 -0
- data/lib/right_agent/serialize.rb +29 -0
- data/lib/right_agent/serialize/message_pack.rb +107 -0
- data/lib/right_agent/serialize/secure_serializer.rb +151 -0
- data/lib/right_agent/serialize/secure_serializer_initializer.rb +47 -0
- data/lib/right_agent/serialize/serializable.rb +151 -0
- data/lib/right_agent/serialize/serializer.rb +159 -0
- data/lib/right_agent/subprocess.rb +38 -0
- data/lib/right_agent/tracer.rb +124 -0
- data/right_agent.gemspec +101 -0
- data/spec/actor_registry_spec.rb +80 -0
- data/spec/actor_spec.rb +162 -0
- data/spec/agent_config_spec.rb +235 -0
- data/spec/agent_identity_spec.rb +78 -0
- data/spec/agent_spec.rb +734 -0
- data/spec/agent_tag_manager_spec.rb +319 -0
- data/spec/clients/api_client_spec.rb +423 -0
- data/spec/clients/auth_client_spec.rb +272 -0
- data/spec/clients/balanced_http_client_spec.rb +576 -0
- data/spec/clients/base_retry_client_spec.rb +635 -0
- data/spec/clients/router_client_spec.rb +594 -0
- data/spec/clients/spec_helper.rb +111 -0
- data/spec/command/agent_manager_commands_spec.rb +51 -0
- data/spec/command/command_io_spec.rb +93 -0
- data/spec/command/command_parser_spec.rb +79 -0
- data/spec/command/command_runner_spec.rb +107 -0
- data/spec/command/command_serializer_spec.rb +51 -0
- data/spec/connectivity_checker_spec.rb +83 -0
- data/spec/core_payload_types/dev_repositories_spec.rb +64 -0
- data/spec/core_payload_types/dev_repository_spec.rb +33 -0
- data/spec/core_payload_types/executable_bundle_spec.rb +67 -0
- data/spec/core_payload_types/login_user_spec.rb +102 -0
- data/spec/core_payload_types/recipe_instantiation_spec.rb +81 -0
- data/spec/core_payload_types/right_script_attachment_spec.rb +65 -0
- data/spec/core_payload_types/right_script_instantiation_spec.rb +79 -0
- data/spec/core_payload_types/spec_helper.rb +23 -0
- data/spec/dispatched_cache_spec.rb +136 -0
- data/spec/dispatcher_spec.rb +324 -0
- data/spec/enrollment_result_spec.rb +53 -0
- data/spec/history_spec.rb +246 -0
- data/spec/log_spec.rb +192 -0
- data/spec/monkey_patches/eventmachine_spec.rb +62 -0
- data/spec/multiplexer_spec.rb +48 -0
- data/spec/offline_handler_spec.rb +340 -0
- data/spec/operation_result_spec.rb +208 -0
- data/spec/packets_spec.rb +461 -0
- data/spec/pending_requests_spec.rb +136 -0
- data/spec/platform/spec_helper.rb +216 -0
- data/spec/platform/unix/darwin/platform_spec.rb +181 -0
- data/spec/platform/unix/linux/platform_spec.rb +540 -0
- data/spec/platform/unix/spec_helper.rb +149 -0
- data/spec/platform/windows/mingw/platform_spec.rb +222 -0
- data/spec/platform/windows/mswin/platform_spec.rb +259 -0
- data/spec/platform/windows/spec_helper.rb +720 -0
- data/spec/retryable_request_spec.rb +306 -0
- data/spec/secure_identity_spec.rb +50 -0
- data/spec/security/cached_certificate_store_proxy_spec.rb +62 -0
- data/spec/security/certificate_cache_spec.rb +71 -0
- data/spec/security/certificate_spec.rb +49 -0
- data/spec/security/distinguished_name_spec.rb +46 -0
- data/spec/security/encrypted_document_spec.rb +55 -0
- data/spec/security/rsa_key_pair_spec.rb +55 -0
- data/spec/security/signature_spec.rb +66 -0
- data/spec/security/static_certificate_store_spec.rb +58 -0
- data/spec/sender_spec.rb +1045 -0
- data/spec/serialize/message_pack_spec.rb +131 -0
- data/spec/serialize/secure_serializer_spec.rb +132 -0
- data/spec/serialize/serializable_spec.rb +90 -0
- data/spec/serialize/serializer_spec.rb +197 -0
- data/spec/spec.opts +2 -0
- data/spec/spec.win32.opts +1 -0
- data/spec/spec_helper.rb +130 -0
- data/spec/tracer_spec.rb +114 -0
- metadata +447 -0
@@ -0,0 +1,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
|