right_link 5.9.1 → 5.9.2
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/RELEASES.rdoc +40 -5
- data/actors/instance_setup.rb +1 -1
- data/bin/cook_runner +1 -0
- data/lib/instance/cook/audit_logger.rb +1 -3
- data/lib/instance/cook/cook.rb +12 -0
- data/lib/instance/cook/cook_state.rb +6 -13
- data/lib/instance/cook/executable_sequence.rb +8 -0
- data/lib/instance/cook/repose_downloader.rb +5 -5
- data/lib/right_link/version.rb +4 -0
- data/scripts/agent_checker.rb +13 -19
- data/scripts/agent_controller.rb +4 -9
- data/scripts/agent_deployer.rb +1 -1
- data/scripts/bundle_runner.rb +10 -49
- data/scripts/cloud_controller.rb +8 -5
- data/scripts/command_helper.rb +101 -0
- data/scripts/log_level_manager.rb +37 -25
- data/scripts/ohai_runner.rb +1 -1
- data/scripts/reenroller.rb +9 -13
- data/scripts/server_importer.rb +9 -43
- data/scripts/shutdown_client.rb +9 -49
- data/scripts/system_configurator.rb +4 -10
- data/scripts/tagger.rb +96 -168
- data/scripts/thunker.rb +12 -33
- metadata +6 -4
data/RELEASES.rdoc
CHANGED
@@ -1,3 +1,36 @@
|
|
1
|
+
= 5.9.2 (RightLink 5.9 beta 3)
|
2
|
+
|
3
|
+
Released 2013-09-06.
|
4
|
+
|
5
|
+
== New Features
|
6
|
+
|
7
|
+
* RightLink's log level can now be controlled by a tag, "rs_agent_dev:log_level". The rs_log_level
|
8
|
+
command is now an interface for getting or setting this tag.
|
9
|
+
* The log-level tag and command no longer apply to the RightLink agent, only to Chef and RightScript
|
10
|
+
execution. To set the RightLink agent's log level explicitly, use the "--agent" option of
|
11
|
+
rs_log_level.
|
12
|
+
* When running on a RedHat-derived distro, RightLink installs public keys for EPEL signed packages
|
13
|
+
at boot.
|
14
|
+
|
15
|
+
== Changes to Existing Functionality
|
16
|
+
|
17
|
+
* When installing RightLink, the recommended technique is to install _only_ the appropriate
|
18
|
+
cloud-support package for the cloud in which RightLink will run. The other RightLink packages
|
19
|
+
will be installed as dependencies. For instance, to install RightLink on an EC2 instance:
|
20
|
+
apt-get install rightlink-cloud-ec2
|
21
|
+
* The cloud-support packages for Rackspace clouds have been renamed to avoid confusion. The
|
22
|
+
package for Rackspace Classic is suffixed with "rackspace-first-gen". The support package for
|
23
|
+
Rackspace OpenCloud is suffixed with "rackspace-open-cloud".
|
24
|
+
|
25
|
+
== Bug Fixes
|
26
|
+
|
27
|
+
* RightLink now looks in the proper directory (/var/spool/rackspace) for cloud-injected
|
28
|
+
userdata when running on Rackspace OpenCloud.
|
29
|
+
* RightLink now requires a modern version of sudo (we rely on the #includedir directive)
|
30
|
+
* Included SUSE vendor-support tags in our rpmspec to prevent warnings from zypper
|
31
|
+
* RightLink DEBs are now signed
|
32
|
+
* Init scripts have more accurate LSB metadata, preventing warnings from init-updaters
|
33
|
+
|
1
34
|
= 5.9.1 (RightLink 5.9 beta 2)
|
2
35
|
|
3
36
|
Released 2013-08-07.
|
@@ -27,11 +60,13 @@ Released 2013-07-13.
|
|
27
60
|
|
28
61
|
== New Features
|
29
62
|
|
30
|
-
* The RS_DECOM_REASON environment variable is set during decommission script/recipe execution to
|
31
|
-
is running. This variable will have one of the following
|
32
|
-
|
33
|
-
|
34
|
-
|
63
|
+
* The RS_DECOM_REASON environment variable is set during decommission script/recipe execution to
|
64
|
+
indicate the reason why decommission is running. This variable will have one of the following
|
65
|
+
values: 'reboot', 'stop', 'terminate' or 'unknown'. The value will be 'reboot', 'stop' or
|
66
|
+
'terminate' when decommissioning through the RightScale dashboard or when using the rs_shutdown
|
67
|
+
command. The 'unknown' value may be seen when the rightlink service is decommissioned (not
|
68
|
+
stopped) from the console or else the instance is shutdown or rebooted without using the
|
69
|
+
rs_shutdown command.
|
35
70
|
* RightLink is distributed as a modular "tree" of packages, making it easy to install just what you need
|
36
71
|
* Improved package hygiene, e.g. clean uninstall and minimal post-install filesystem tampering
|
37
72
|
* Ability to distinguish between sudo (server_login + server_superuser) and normal (server_login) users
|
data/actors/instance_setup.rb
CHANGED
@@ -169,7 +169,7 @@ class InstanceSetup
|
|
169
169
|
# we are no longer freezing log level for v5.8+
|
170
170
|
tagged_log_level = ::RightScale::CookState.dev_log_level
|
171
171
|
RightScale::Log.level = tagged_log_level if tagged_log_level
|
172
|
-
RightScale::Log.info("Tags discovered at initial startup: #{tags.inspect}
|
172
|
+
RightScale::Log.info("Tags discovered at initial startup: #{tags.inspect}")
|
173
173
|
end
|
174
174
|
|
175
175
|
# Setup suicide timer which will cause instance to shutdown if the rs_launch:type=auto tag
|
data/bin/cook_runner
CHANGED
@@ -15,6 +15,7 @@ require 'right_scraper'
|
|
15
15
|
|
16
16
|
BASE_DIR = File.join(File.dirname(__FILE__), '..')
|
17
17
|
|
18
|
+
require File.normalize_path(File.join(BASE_DIR, 'lib', 'right_link', 'version'))
|
18
19
|
require File.normalize_path(File.join(BASE_DIR, 'lib', 'instance'))
|
19
20
|
require File.normalize_path(File.join(BASE_DIR, 'lib', 'instance', 'cook'))
|
20
21
|
|
@@ -102,9 +102,7 @@ module RightScale
|
|
102
102
|
return true if is_filtered?(severity, message)
|
103
103
|
msg = format_message(format_severity(severity), Time.now, progname, message)
|
104
104
|
case severity
|
105
|
-
when Logger::DEBUG
|
106
|
-
Log.debug(message)
|
107
|
-
when Logger::INFO, Logger::WARN, Logger::UNKNOWN
|
105
|
+
when Logger::INFO, Logger::WARN, Logger::UNKNOWN, Logger::DEBUG
|
108
106
|
AuditStub.instance.append_output(msg)
|
109
107
|
when Logger::ERROR
|
110
108
|
AuditStub.instance.append_error(msg)
|
data/lib/instance/cook/cook.rb
CHANGED
@@ -94,6 +94,7 @@ module RightScale
|
|
94
94
|
EM.run do
|
95
95
|
begin
|
96
96
|
AuditStub.instance.init(options)
|
97
|
+
check_for_missing_inputs(bundle)
|
97
98
|
gatherer.callback { EM.defer { sequence.run } }
|
98
99
|
gatherer.errback { success = false; report_failure(gatherer) }
|
99
100
|
sequence.callback { success = true; send_inputs_patch(sequence) }
|
@@ -113,6 +114,17 @@ module RightScale
|
|
113
114
|
exit(1) unless success
|
114
115
|
end
|
115
116
|
|
117
|
+
def check_for_missing_inputs(bundle)
|
118
|
+
pending_executables = bundle.executables.select { |e| !e.ready }
|
119
|
+
unless pending_executables.empty?
|
120
|
+
pending_executables.each do |e|
|
121
|
+
missing_input_names = e.input_flags.collect {|k,v| k if v.member?("unready")}.compact
|
122
|
+
AuditStub.instance.append_info("Following inputs used by '#{e.nickname} are missing': #{missing_input_names.join(", ")}")
|
123
|
+
end
|
124
|
+
fail("Execution failed", "Missing inputs")
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
116
128
|
# Determines if the current cook process has the default thread for purposes
|
117
129
|
# of concurrency with non-defaulted cooks.
|
118
130
|
def has_default_thread?
|
@@ -112,18 +112,6 @@ module RightScale
|
|
112
112
|
!!@reboot
|
113
113
|
end
|
114
114
|
|
115
|
-
# Is the instance running in dev mode?
|
116
|
-
# dev mode tweaks the behavior of the RightLink agent to help
|
117
|
-
# the development of Chef recipes.
|
118
|
-
# In dev mode, the log level is always debug.
|
119
|
-
#
|
120
|
-
# === Return
|
121
|
-
# true:: If dev tags are defined on this instance
|
122
|
-
# false:: Otherwise
|
123
|
-
def dev_mode_enabled?
|
124
|
-
!!tag_value(DEV_TAG_NAMESPACE)
|
125
|
-
end
|
126
|
-
|
127
115
|
# Determines the developer log level, if any, which forces and supercedes
|
128
116
|
# all other log level configurations.
|
129
117
|
#
|
@@ -202,7 +190,12 @@ module RightScale
|
|
202
190
|
# === Return
|
203
191
|
# level(Integer):: one of Logger::INFO ... Logger::FATAL
|
204
192
|
def log_level
|
205
|
-
@log_level
|
193
|
+
case @log_level
|
194
|
+
when Symbol, String
|
195
|
+
Log.level_from_sym(@log_level.to_sym)
|
196
|
+
else
|
197
|
+
@log_level
|
198
|
+
end
|
206
199
|
end
|
207
200
|
|
208
201
|
# Re-initialize then merge given state
|
@@ -557,6 +557,14 @@ module RightScale
|
|
557
557
|
@audit.create_new_section('Preparing execution')
|
558
558
|
end
|
559
559
|
|
560
|
+
log_desc = "Log level is #{Log.level_to_sym(CookState.log_level)}"
|
561
|
+
if CookState.dev_log_level
|
562
|
+
log_desc << " (overridden by #{CookState::LOG_LEVEL_TAG}=#{CookState.dev_log_level})"
|
563
|
+
end
|
564
|
+
log_desc << '.'
|
565
|
+
@audit.append_info(log_desc)
|
566
|
+
@audit.append_info('The download once flag is set.') if CookState.download_once?
|
567
|
+
|
560
568
|
@audit.append_info("Run list for thread #{@thread_name.inspect} contains #{@run_list.size} items.")
|
561
569
|
@audit.append_info(@run_list.join(', '))
|
562
570
|
|
@@ -109,12 +109,12 @@ module RightScale
|
|
109
109
|
attempts += 1
|
110
110
|
t0 = Time.now
|
111
111
|
|
112
|
-
# Previously we accessed RestClient directly and used it's wrapper method to instantiate
|
112
|
+
# Previously we accessed RestClient directly and used it's wrapper method to instantiate
|
113
113
|
# a RestClient::Request object. This wrapper was not passing all options down the stack
|
114
114
|
# so now we invoke the RestClient::Request object directly, passing it our desired options
|
115
|
-
client.execute(:method => :get, :url => "https://#{endpoint}:443#{resource}", :timeout => calculate_timeout(attempts), :verify_ssl => OpenSSL::SSL::VERIFY_PEER, :ssl_ca_file => get_ca_file, :headers => {:user_agent => "RightLink v#{AgentConfig.protocol_version}"}) do |response, request, result|
|
115
|
+
client.execute(:method => :get, :url => "https://#{endpoint}:443#{resource}", :timeout => calculate_timeout(attempts), :verify_ssl => OpenSSL::SSL::VERIFY_PEER, :ssl_ca_file => get_ca_file, :headers => {:user_agent => "RightLink v#{AgentConfig.protocol_version}", 'X-RightLink-Version' => RightLink::VERSION }) do |response, request, result|
|
116
116
|
if result.kind_of?(Net::HTTPSuccess)
|
117
|
-
@size = result.content_length
|
117
|
+
@size = result.content_length || response.size || 0
|
118
118
|
@speed = @size / (Time.now - t0)
|
119
119
|
yield response
|
120
120
|
else
|
@@ -223,7 +223,7 @@ module RightScale
|
|
223
223
|
|
224
224
|
# Orders ips by hostnames
|
225
225
|
#
|
226
|
-
# The purpose of this method is to sort ips of hostnames so it tries all IPs of hostname 1,
|
226
|
+
# The purpose of this method is to sort ips of hostnames so it tries all IPs of hostname 1,
|
227
227
|
# then all IPs of hostname 2, etc
|
228
228
|
#
|
229
229
|
# == Return
|
@@ -264,7 +264,7 @@ module RightScale
|
|
264
264
|
)
|
265
265
|
end
|
266
266
|
|
267
|
-
# Exponential incremental timeout algorithm. Returns the amount of
|
267
|
+
# Exponential incremental timeout algorithm. Returns the amount of
|
268
268
|
# of time to wait for the next iteration
|
269
269
|
#
|
270
270
|
# === Parameters
|
data/scripts/agent_checker.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# === Synopsis:
|
2
|
-
# RightScale Agent Checker (rchk) - (c) 2010-
|
2
|
+
# RightScale Agent Checker (rchk) - (c) 2010-2013 RightScale Inc
|
3
3
|
#
|
4
4
|
# Checks the agent to see if it is actively communicating with RightNet and if not
|
5
5
|
# triggers it to re-enroll and exits.
|
@@ -37,6 +37,7 @@ require 'right_agent/scripts/common_parser'
|
|
37
37
|
|
38
38
|
require File.normalize_path(File.join(File.dirname(__FILE__), '..', 'lib', 'instance', 'agent_watcher'))
|
39
39
|
require File.normalize_path(File.join(File.dirname(__FILE__), '..', 'lib', 'instance', 'agent_config'))
|
40
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'command_helper'))
|
40
41
|
|
41
42
|
module RightScale
|
42
43
|
|
@@ -81,7 +82,7 @@ module RightScale
|
|
81
82
|
end # AgentCheckerCommands
|
82
83
|
|
83
84
|
class AgentChecker
|
84
|
-
|
85
|
+
include CommandHelper
|
85
86
|
include DaemonizeHelper
|
86
87
|
|
87
88
|
VERSION = [0, 1]
|
@@ -163,7 +164,6 @@ module RightScale
|
|
163
164
|
def start(options)
|
164
165
|
begin
|
165
166
|
setup_traps
|
166
|
-
@command_serializer = Serializer.new
|
167
167
|
@state_serializer = Serializer.new(:json)
|
168
168
|
|
169
169
|
# Retrieve instance agent configuration options
|
@@ -248,7 +248,7 @@ module RightScale
|
|
248
248
|
version ""
|
249
249
|
end
|
250
250
|
|
251
|
-
|
251
|
+
parse do
|
252
252
|
options = parser.parse
|
253
253
|
options.delete(:max_attempts) unless options[:max_attempts] > 0
|
254
254
|
if options[:delete]
|
@@ -256,17 +256,10 @@ module RightScale
|
|
256
256
|
end
|
257
257
|
options.delete(:retry_interval) unless options[:retry_interval] > 0
|
258
258
|
options
|
259
|
-
rescue Trollop::HelpNeeded
|
260
|
-
puts Usage.scan(__FILE__)
|
261
|
-
exit
|
262
|
-
rescue Trollop::CommandlineError => e
|
263
|
-
error("#{e}\nUse --help for additional information", nil, abort = true)
|
264
|
-
rescue Trollop::VersionNeeded
|
265
|
-
puts version
|
266
|
-
exit
|
267
259
|
end
|
268
260
|
end
|
269
261
|
|
262
|
+
|
270
263
|
protected
|
271
264
|
|
272
265
|
# Perform required checks
|
@@ -285,8 +278,7 @@ protected
|
|
285
278
|
info("Stopping checker daemon")
|
286
279
|
if RightScale::Platform.windows?
|
287
280
|
begin
|
288
|
-
|
289
|
-
client.send_command({:name => :terminate}, verbose = @options[:verbose], timeout = 30) do |r|
|
281
|
+
send_command({:name => :terminate}, verbose = @options[:verbose], timeout = 30) do |r|
|
290
282
|
info(r)
|
291
283
|
terminate
|
292
284
|
end
|
@@ -391,11 +383,9 @@ protected
|
|
391
383
|
# true:: Always return true
|
392
384
|
def try_communicating(attempt)
|
393
385
|
begin
|
394
|
-
|
395
|
-
client = CommandClient.new(listen_port, @agent[:cookie])
|
396
|
-
client.send_command({:name => "check_connectivity"}, @options[:verbose], COMMAND_IO_TIMEOUT) do |r|
|
386
|
+
send_command({:name => "check_connectivity"}, @options[:verbose], COMMAND_IO_TIMEOUT) do |r|
|
397
387
|
@command_io_failures = 0
|
398
|
-
res =
|
388
|
+
res = serialize_operation_result(r) rescue nil
|
399
389
|
if res && res.success?
|
400
390
|
info("Successful agent communication" + (attempt > 1 ? " on attempt #{attempt}" : ""))
|
401
391
|
@retry_timer.cancel if @retry_timer
|
@@ -542,7 +532,11 @@ protected
|
|
542
532
|
# === Return
|
543
533
|
# ver(String):: Version information
|
544
534
|
def version
|
545
|
-
ver = "rchk #{VERSION.join('.')} - RightScale Agent Checker (c)
|
535
|
+
ver = "rchk #{VERSION.join('.')} - RightScale Agent Checker (c) 2013 RightScale"
|
536
|
+
end
|
537
|
+
|
538
|
+
def usage
|
539
|
+
Usage.scan(__FILE__)
|
546
540
|
end
|
547
541
|
|
548
542
|
end # AgentChecker
|
data/scripts/agent_controller.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# === Synopsis:
|
2
|
-
# RightScale Agent Controller (rnac) - (c) 2009-
|
2
|
+
# RightScale Agent Controller (rnac) - (c) 2009-2013 RightScale Inc
|
3
3
|
#
|
4
4
|
# rnac is a command line tool for managing a RightLink agent
|
5
5
|
#
|
@@ -79,10 +79,12 @@ require 'rubygems'
|
|
79
79
|
require 'right_agent/scripts/agent_controller'
|
80
80
|
|
81
81
|
require File.normalize_path(File.join(File.dirname(__FILE__), '..', 'lib', 'instance', 'agent_watcher'))
|
82
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'command_helper'))
|
82
83
|
|
83
84
|
module RightScale
|
84
85
|
|
85
86
|
class RightLinkAgentController < AgentController
|
87
|
+
include CommandHelper
|
86
88
|
|
87
89
|
# Create and run controller
|
88
90
|
#
|
@@ -157,16 +159,9 @@ module RightScale
|
|
157
159
|
# === Return
|
158
160
|
# (Boolean):: true if command executed successfully, otherwise false
|
159
161
|
def run_command(message, command)
|
160
|
-
options = AgentConfig.agent_options(@options[:agent_name])
|
161
|
-
listen_port = options[:listen_port]
|
162
|
-
unless listen_port
|
163
|
-
$stderr.puts "Could not retrieve listen port for agent #{@options[:identity]}"
|
164
|
-
return false
|
165
|
-
end
|
166
162
|
puts message
|
167
163
|
begin
|
168
|
-
|
169
|
-
@client.send_command({ :name => command }, verbose = false, timeout = 100) { |r| puts r }
|
164
|
+
send_command({ :name => command }, verbose = false, timeout = 100) { |r| puts r }
|
170
165
|
rescue SystemExit => e
|
171
166
|
raise e
|
172
167
|
rescue Exception => e
|
data/scripts/agent_deployer.rb
CHANGED
data/scripts/bundle_runner.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# === Synopsis:
|
2
|
-
# RightScale Bundle Runner (rs_run_right_script/rs_run_recipe) - (c) 2009-
|
2
|
+
# RightScale Bundle Runner (rs_run_right_script/rs_run_recipe) - (c) 2009-2013 RightScale Inc
|
3
3
|
#
|
4
4
|
# rs_run_right_script and rs_run_recipe are command line tools that allow
|
5
5
|
# running RightScripts and recipes respectively from within an instance
|
@@ -68,10 +68,12 @@ require 'right_agent'
|
|
68
68
|
require 'right_agent/scripts/usage'
|
69
69
|
require 'right_agent/scripts/common_parser'
|
70
70
|
require 'right_agent/core_payload_types'
|
71
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'command_helper'))
|
71
72
|
|
72
73
|
module RightScale
|
73
74
|
|
74
75
|
class BundleRunner
|
76
|
+
include CommandHelper
|
75
77
|
|
76
78
|
# Default number of seconds to wait for command response
|
77
79
|
DEFAULT_TIMEOUT = 20
|
@@ -97,15 +99,10 @@ module RightScale
|
|
97
99
|
cmd = { :options => to_forwarder_options(options) }
|
98
100
|
cmd[:name] = options[:bundle_type] == :right_script ? 'run_right_script' : 'run_recipe'
|
99
101
|
AgentConfig.cfg_dir = options[:cfg_dir]
|
100
|
-
config_options = AgentConfig.agent_options('instance')
|
101
|
-
listen_port = config_options[:listen_port]
|
102
|
-
fail('Could not retrieve listen port', false) unless listen_port
|
103
|
-
command_serializer = Serializer.new
|
104
|
-
client = CommandClient.new(listen_port, config_options[:cookie])
|
105
102
|
|
106
103
|
exit_code = true
|
107
104
|
callback ||= lambda do |r|
|
108
|
-
response =
|
105
|
+
response = serialize_operation_result(r) rescue nil
|
109
106
|
if r == 'OK'
|
110
107
|
puts "Request sent successfully"
|
111
108
|
elsif response.respond_to?(:success?) && response.success?
|
@@ -117,8 +114,9 @@ module RightScale
|
|
117
114
|
end
|
118
115
|
|
119
116
|
begin
|
117
|
+
check_privileges
|
120
118
|
timeout = options[:timeout] || DEFAULT_TIMEOUT
|
121
|
-
|
119
|
+
send_command(cmd, options[:verbose], timeout) { |r| callback.call(r) }
|
122
120
|
rescue Exception => e
|
123
121
|
fail(e.message)
|
124
122
|
end
|
@@ -187,7 +185,7 @@ module RightScale
|
|
187
185
|
version ""
|
188
186
|
end
|
189
187
|
|
190
|
-
|
188
|
+
parse do
|
191
189
|
options.merge!(parser.parse(arguments))
|
192
190
|
options.delete(:name) if options[:id]
|
193
191
|
if options[:parameter]
|
@@ -222,46 +220,10 @@ module RightScale
|
|
222
220
|
end
|
223
221
|
end
|
224
222
|
options
|
225
|
-
rescue Trollop::HelpNeeded
|
226
|
-
puts Usage.scan(__FILE__)
|
227
|
-
exit
|
228
|
-
rescue Trollop::VersionNeeded
|
229
|
-
puts version
|
230
|
-
succeed
|
231
|
-
rescue Exception => e
|
232
|
-
puts e.message + "\nUse --help for additional information"
|
233
|
-
exit(1)
|
234
223
|
end
|
235
224
|
end
|
236
225
|
|
237
226
|
protected
|
238
|
-
|
239
|
-
# Print error on console and exit abnormally
|
240
|
-
#
|
241
|
-
# === Parameter
|
242
|
-
# reason(String|Exception):: Error message or exception, default to nil (no message printed)
|
243
|
-
# print_usage(Boolean):: Whether script usage should be printed, default to false
|
244
|
-
#
|
245
|
-
# === Return
|
246
|
-
# R.I.P. does not return
|
247
|
-
def fail(reason=nil, print_usage=false)
|
248
|
-
case reason
|
249
|
-
when Errno::EACCES
|
250
|
-
STDERR.puts "** #{reason.message}"
|
251
|
-
STDERR.puts "** Try elevating privilege (sudo/runas) before invoking this command."
|
252
|
-
code = 2
|
253
|
-
when Exception
|
254
|
-
STDERR.puts "** #{reason.message}"
|
255
|
-
code = 1
|
256
|
-
else
|
257
|
-
STDERR.puts "** #{reason}" if reason
|
258
|
-
code = 1
|
259
|
-
end
|
260
|
-
|
261
|
-
puts Usage.scan(__FILE__) if print_usage
|
262
|
-
exit(code)
|
263
|
-
end
|
264
|
-
|
265
227
|
# Map arguments options into forwarder actor compatible options
|
266
228
|
#
|
267
229
|
# === Parameters
|
@@ -301,12 +263,11 @@ protected
|
|
301
263
|
# === Return
|
302
264
|
# (String):: Version information
|
303
265
|
def version
|
304
|
-
|
305
|
-
"rs_run_right_script & rs_run_recipe #{gemspec.version} - RightLink's bundle runner (c) 2011 RightScale"
|
266
|
+
"rs_run_right_script & rs_run_recipe #{right_link_version} - RightLink's bundle runner (c) 2013 RightScale"
|
306
267
|
end
|
307
268
|
|
308
|
-
def
|
309
|
-
|
269
|
+
def usage
|
270
|
+
Usage.scan(__FILE__)
|
310
271
|
end
|
311
272
|
|
312
273
|
end # BundleRunner
|
data/scripts/cloud_controller.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# === Synopsis:
|
2
|
-
# RightScale Cloud Controller (cloud) - Copyright (c)
|
2
|
+
# RightScale Cloud Controller (cloud) - Copyright (c) 2013 by RightScale Inc
|
3
3
|
#
|
4
4
|
# cloud is a command line tool which invokes cloud-specific actions
|
5
5
|
#
|
@@ -37,10 +37,12 @@ require 'right_agent/scripts/usage'
|
|
37
37
|
|
38
38
|
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'instance', 'agent_config'))
|
39
39
|
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'clouds', 'register_clouds'))
|
40
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'command_helper'))
|
40
41
|
|
41
42
|
module RightScale
|
42
43
|
|
43
44
|
class CloudController
|
45
|
+
include CommandHelper
|
44
46
|
|
45
47
|
# Convenience wrapper
|
46
48
|
def self.run
|
@@ -121,7 +123,7 @@ module RightScale
|
|
121
123
|
opt :quiet # note that :quiet is deprecated (use -v instead) because Trollop cannot easily support inverse flags that default to true
|
122
124
|
opt :verbose
|
123
125
|
end
|
124
|
-
|
126
|
+
parse do
|
125
127
|
options = parser.parse
|
126
128
|
if options[:parameters_given]
|
127
129
|
if options[:parameters].start_with?("[")
|
@@ -131,12 +133,13 @@ module RightScale
|
|
131
133
|
end
|
132
134
|
end
|
133
135
|
options
|
134
|
-
rescue Trollop::HelpNeeded
|
135
|
-
puts Usage.scan(__FILE__)
|
136
|
-
exit 0
|
137
136
|
end
|
138
137
|
end
|
139
138
|
|
139
|
+
def usage
|
140
|
+
Usage.scan(__FILE__)
|
141
|
+
end
|
142
|
+
|
140
143
|
# Default logger for printing to console
|
141
144
|
def default_logger(verbose)
|
142
145
|
if verbose
|
@@ -0,0 +1,101 @@
|
|
1
|
+
module RightScale
|
2
|
+
module CommandHelper
|
3
|
+
def check_privileges
|
4
|
+
config_options = ::RightScale::AgentConfig.agent_options('instance')
|
5
|
+
pid_dir = config_options[:pid_dir]
|
6
|
+
identity = config_options[:identity]
|
7
|
+
raise ::ArgumentError.new('Could not get cookie file path') if (pid_dir.nil? & identity.nil?)
|
8
|
+
cookie_file = File.join(pid_dir, "#{identity}.cookie")
|
9
|
+
File.open(cookie_file, "r") { |f| f.close }
|
10
|
+
true
|
11
|
+
rescue Errno::EACCES => e
|
12
|
+
fail(e)
|
13
|
+
end
|
14
|
+
# Creates a command client and sends the given payload.
|
15
|
+
#
|
16
|
+
# === Parameters
|
17
|
+
# @param [Hash] cmd as a payload hash
|
18
|
+
# @param [TrueClass, FalseClass] verbose flag
|
19
|
+
# @param [TrueClass, FalseClass] timeout or nil
|
20
|
+
#
|
21
|
+
# === Block
|
22
|
+
# @yield [response] callback for response
|
23
|
+
# @yieldparam response [Object] response of any type
|
24
|
+
def send_command(cmd, verbose, timeout=20)
|
25
|
+
config_options = ::RightScale::AgentConfig.agent_options('instance')
|
26
|
+
listen_port = config_options[:listen_port]
|
27
|
+
raise ::ArgumentError.new('Could not retrieve agent listen port') unless listen_port
|
28
|
+
client = ::RightScale::CommandClient.new(listen_port, config_options[:cookie])
|
29
|
+
result = nil
|
30
|
+
block = Proc.new do |res|
|
31
|
+
result = res
|
32
|
+
yield res if block_given?
|
33
|
+
end
|
34
|
+
client.send_command(cmd, verbose, timeout, &block)
|
35
|
+
result
|
36
|
+
end
|
37
|
+
|
38
|
+
def serialize_operation_result(res)
|
39
|
+
command_serializer = ::RightScale::Serializer.new
|
40
|
+
::RightScale::OperationResult.from_results(command_serializer.load(res))
|
41
|
+
end
|
42
|
+
|
43
|
+
# Exit with success.
|
44
|
+
#
|
45
|
+
# === Return
|
46
|
+
# R.I.P. does not return
|
47
|
+
def succeed
|
48
|
+
exit(0)
|
49
|
+
end
|
50
|
+
|
51
|
+
# Print error on console and exit abnormally
|
52
|
+
#
|
53
|
+
# === Parameter
|
54
|
+
# reason(Exception|String|Integer):: Exception, error message or numeric failure code
|
55
|
+
#
|
56
|
+
# === Return
|
57
|
+
# R.I.P. does not return
|
58
|
+
def fail(reason=nil)
|
59
|
+
case reason
|
60
|
+
when Errno::EACCES
|
61
|
+
STDERR.puts reason.message
|
62
|
+
STDERR.puts "Try elevating privilege (sudo/runas) before invoking this command."
|
63
|
+
code = 2
|
64
|
+
when Exception
|
65
|
+
STDERR.puts reason.message
|
66
|
+
code = reason.respond_to(:code) ? reason.code : 50
|
67
|
+
when String
|
68
|
+
STDERR.puts reason
|
69
|
+
code = 50
|
70
|
+
when Integer
|
71
|
+
code = reason
|
72
|
+
else
|
73
|
+
code = 1
|
74
|
+
end
|
75
|
+
|
76
|
+
exit(code)
|
77
|
+
end
|
78
|
+
|
79
|
+
def parse
|
80
|
+
begin
|
81
|
+
yield
|
82
|
+
rescue Trollop::VersionNeeded
|
83
|
+
STDOUT.puts(version)
|
84
|
+
succeed
|
85
|
+
rescue Trollop::HelpNeeded
|
86
|
+
STDOUT.puts(usage)
|
87
|
+
succeed
|
88
|
+
rescue Trollop::CommandlineError => e
|
89
|
+
puts e.message + "\nUse --help for additional information"
|
90
|
+
fail
|
91
|
+
rescue SystemExit => e
|
92
|
+
raise e
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def right_link_version
|
97
|
+
gemspec = eval(File.read(File.join(File.dirname(__FILE__), '..', 'right_link.gemspec')))
|
98
|
+
gemspec.version
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|