right_link 5.9.0
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/actors/agent_manager.rb +88 -0
- data/actors/instance_scheduler.rb +321 -0
- data/actors/instance_services.rb +64 -0
- data/actors/instance_setup.rb +567 -0
- data/bin/cloud +25 -0
- data/bin/cook_runner +44 -0
- data/bin/deploy +120 -0
- data/bin/enroll +385 -0
- data/bin/rad +32 -0
- data/bin/rchk +29 -0
- data/bin/rnac +39 -0
- data/bin/rs_connect +33 -0
- data/bin/rs_log_level +31 -0
- data/bin/rs_ohai +28 -0
- data/bin/rs_reenroll +31 -0
- data/bin/rs_run_recipe +34 -0
- data/bin/rs_run_right_script +34 -0
- data/bin/rs_shutdown +33 -0
- data/bin/rs_tag +33 -0
- data/bin/rs_thunk +33 -0
- data/bin/rstat +31 -0
- data/bin/system +16 -0
- data/ext/Rakefile +18 -0
- data/init/config.yml +5 -0
- data/init/init.rb +79 -0
- data/lib/chef/ohai_setup.rb +51 -0
- data/lib/chef/plugins/cloud.rb +91 -0
- data/lib/chef/plugins/cloudstack.rb +23 -0
- data/lib/chef/plugins/ec2.rb +23 -0
- data/lib/chef/plugins/linux/block_device2.rb +24 -0
- data/lib/chef/plugins/rackspace.rb +23 -0
- data/lib/chef/plugins/rightscale.rb +125 -0
- data/lib/chef/plugins/windows/network.rb +114 -0
- data/lib/chef/plugins.rb +74 -0
- data/lib/chef/providers/dns_dnsmadeeasy_provider.rb +81 -0
- data/lib/chef/providers/dns_resource.rb +100 -0
- data/lib/chef/providers/executable_schedule_provider.rb +70 -0
- data/lib/chef/providers/executable_schedule_resource.rb +144 -0
- data/lib/chef/providers/remote_recipe_provider.rb +86 -0
- data/lib/chef/providers/remote_recipe_resource.rb +101 -0
- data/lib/chef/providers/right_link_tag_provider.rb +73 -0
- data/lib/chef/providers/right_link_tag_resource.rb +59 -0
- data/lib/chef/providers/right_script_provider.rb +190 -0
- data/lib/chef/providers/right_script_resource.rb +113 -0
- data/lib/chef/providers/rs_shutdown_provider.rb +75 -0
- data/lib/chef/providers/rs_shutdown_resource.rb +55 -0
- data/lib/chef/providers/server_collection_provider.rb +66 -0
- data/lib/chef/providers/server_collection_resource.rb +93 -0
- data/lib/chef/providers/windows/powershell_provider.rb +151 -0
- data/lib/chef/providers/windows/powershell_resource.rb +111 -0
- data/lib/chef/providers/windows/unsupported_provider.rb +51 -0
- data/lib/chef/right_providers.rb +55 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/ChefNodeCmdlet.csproj +104 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/ChefNodeCmdlet.dll-Help.xml +141 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/Exceptions.cs +182 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/GetChefNodeCommand.cs +58 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/GetChefNodeRequest.cs +46 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/GetChefNodeResponse.cs +45 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/GetCurrentResourceCommand.cs +58 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/GetCurrentResourceRequest.cs +46 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/GetCurrentResourceResponse.cs +45 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/GetNewResourceCommand.cs +58 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/GetNewResourceRequest.cs +46 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/GetNewResourceResponse.cs +45 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/GetNextActionCommand.cs +178 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/GetNextActionRequest.cs +67 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/GetNextActionResponse.cs +58 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/GetNodeValueCommandBase.cs +142 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/GetNodeValueRequestBase.cs +64 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/GetNodeValueResponseBase.cs +69 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/JsonTransport.cs +110 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/PipeClient.cs +158 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/PipeServer.cs +142 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/Properties/AssemblyInfo.cs +16 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/ProtocolConstants.cs +55 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/ProtocolUtilities.cs +77 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/ReadMe.txt +53 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/SetChefNodeCommand.cs +59 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/SetChefNodeRequest.cs +46 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/SetChefNodeResponse.cs +58 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/SetCurrentResourceCommand.cs +59 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/SetCurrentResourceRequest.cs +46 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/SetCurrentResourceResponse.cs +40 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/SetNewResourceCommand.cs +59 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/SetNewResourceRequest.cs +46 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/SetNewResourceResponse.cs +40 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/SetNodeValueCommandBase.cs +293 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/SetNodeValueRequestBase.cs +75 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/SetNodeValueResponseBase.cs +45 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet/Transport.cs +91 -0
- data/lib/chef/windows/ChefNodeCmdlet/ChefNodeCmdlet.sln +35 -0
- data/lib/chef/windows/ChefNodeCmdlet/TestChefNodeCmdlet/Program.cs +374 -0
- data/lib/chef/windows/ChefNodeCmdlet/TestChefNodeCmdlet/Properties/AssemblyInfo.cs +16 -0
- data/lib/chef/windows/ChefNodeCmdlet/TestChefNodeCmdlet/TestChefNodeCmdlet.csproj +65 -0
- data/lib/chef/windows/ChefNodeCmdlet/TestNextActionCmdlet/Program.cs +136 -0
- data/lib/chef/windows/ChefNodeCmdlet/TestNextActionCmdlet/Properties/AssemblyInfo.cs +36 -0
- data/lib/chef/windows/ChefNodeCmdlet/TestNextActionCmdlet/ReadMe.txt +46 -0
- data/lib/chef/windows/ChefNodeCmdlet/TestNextActionCmdlet/TestNextActionCmdlet.csproj +68 -0
- data/lib/chef/windows/bin/Newtonsoft.Json.dll +0 -0
- data/lib/chef/windows/chef_node_server.rb +463 -0
- data/lib/chef/windows/dynamic_powershell_provider.rb +296 -0
- data/lib/chef/windows/pipe_server.rb +283 -0
- data/lib/chef/windows/powershell_host.rb +285 -0
- data/lib/chef/windows/powershell_pipe_server.rb +136 -0
- data/lib/chef/windows/powershell_provider_base.rb +92 -0
- data/lib/chef/windows/scripts/run_loop.ps1 +105 -0
- data/lib/clouds/cloud.rb +557 -0
- data/lib/clouds/cloud_factory.rb +250 -0
- data/lib/clouds/cloud_utilities.rb +244 -0
- data/lib/clouds/clouds/azure.rb +106 -0
- data/lib/clouds/clouds/cloudstack.rb +114 -0
- data/lib/clouds/clouds/ec2.rb +113 -0
- data/lib/clouds/clouds/eucalyptus.rb +46 -0
- data/lib/clouds/clouds/google.rb +102 -0
- data/lib/clouds/clouds/none.rb +76 -0
- data/lib/clouds/clouds/openstack.rb +30 -0
- data/lib/clouds/clouds/rackspace-ng.rb +54 -0
- data/lib/clouds/clouds/rackspace.rb +78 -0
- data/lib/clouds/clouds/softlayer.rb +91 -0
- data/lib/clouds/metadata_formatter.rb +108 -0
- data/lib/clouds/metadata_provider.rb +128 -0
- data/lib/clouds/metadata_source.rb +87 -0
- data/lib/clouds/metadata_sources/certificate_metadata_source.rb +207 -0
- data/lib/clouds/metadata_sources/config_drive_metadata_source.rb +129 -0
- data/lib/clouds/metadata_sources/file_metadata_source.rb +74 -0
- data/lib/clouds/metadata_sources/http_metadata_source.rb +277 -0
- data/lib/clouds/metadata_sources/selective_metadata_source.rb +122 -0
- data/lib/clouds/metadata_tree_climber.rb +144 -0
- data/lib/clouds/metadata_writer.rb +155 -0
- data/lib/clouds/metadata_writers/dictionary_metadata_writer.rb +72 -0
- data/lib/clouds/metadata_writers/ruby_metadata_writer.rb +76 -0
- data/lib/clouds/metadata_writers/shell_metadata_writer.rb +121 -0
- data/lib/clouds/register_clouds.rb +34 -0
- data/lib/clouds.rb +32 -0
- data/lib/gem_dependencies.rb +83 -0
- data/lib/git_hooks/commit-msg.rb +7 -0
- data/lib/instance/agent_config.rb +168 -0
- data/lib/instance/agent_watcher.rb +233 -0
- data/lib/instance/audit_cook_stub.rb +104 -0
- data/lib/instance/audit_proxy.rb +247 -0
- data/lib/instance/bundle_queue.rb +104 -0
- data/lib/instance/cook/agent_connection.rb +109 -0
- data/lib/instance/cook/audit_logger.rb +165 -0
- data/lib/instance/cook/audit_stub.rb +142 -0
- data/lib/instance/cook/ca-bundle.crt +2794 -0
- data/lib/instance/cook/chef_state.rb +211 -0
- data/lib/instance/cook/cook.rb +306 -0
- data/lib/instance/cook/cook_state.rb +298 -0
- data/lib/instance/cook/cookbook_path_mapping.rb +66 -0
- data/lib/instance/cook/cookbook_repo_retriever.rb +190 -0
- data/lib/instance/cook/executable_sequence.rb +765 -0
- data/lib/instance/cook/external_parameter_gatherer.rb +190 -0
- data/lib/instance/cook/repose_downloader.rb +349 -0
- data/lib/instance/cook/shutdown_request_proxy.rb +121 -0
- data/lib/instance/cook.rb +41 -0
- data/lib/instance/downloader.rb +208 -0
- data/lib/instance/duplicable.rb +67 -0
- data/lib/instance/exceptions.rb +49 -0
- data/lib/instance/executable_sequence_proxy.rb +278 -0
- data/lib/instance/instance_commands.rb +577 -0
- data/lib/instance/instance_state.rb +633 -0
- data/lib/instance/json_utilities.rb +102 -0
- data/lib/instance/login_manager.rb +533 -0
- data/lib/instance/login_user_manager.rb +522 -0
- data/lib/instance/message_encoder.rb +118 -0
- data/lib/instance/multi_thread_bundle_queue.rb +232 -0
- data/lib/instance/operation_context.rb +60 -0
- data/lib/instance/options_bag.rb +65 -0
- data/lib/instance/payload_formatter.rb +46 -0
- data/lib/instance/policy.rb +53 -0
- data/lib/instance/policy_audit.rb +100 -0
- data/lib/instance/policy_manager.rb +146 -0
- data/lib/instance/reenroll_manager.rb +104 -0
- data/lib/instance/right_scripts_cookbook.rb +181 -0
- data/lib/instance/shutdown_request.rb +221 -0
- data/lib/instance/single_thread_bundle_queue.rb +189 -0
- data/lib/instance/volume_management.rb +450 -0
- data/lib/instance.rb +50 -0
- data/lib/repo_conf_generators/apt_conf_generators.rb +106 -0
- data/lib/repo_conf_generators/gem_conf_generators.rb +80 -0
- data/lib/repo_conf_generators/rightscale_conf_generators.rb +254 -0
- data/lib/repo_conf_generators/rightscale_key.pub +17 -0
- data/lib/repo_conf_generators/yum_conf_generators.rb +225 -0
- data/lib/repo_conf_generators.rb +30 -0
- data/lib/run_shell.rb +28 -0
- data/scripts/agent_checker.rb +571 -0
- data/scripts/agent_controller.rb +247 -0
- data/scripts/agent_deployer.rb +148 -0
- data/scripts/bundle_runner.rb +336 -0
- data/scripts/cloud_controller.rb +176 -0
- data/scripts/log_level_manager.rb +142 -0
- data/scripts/ohai_runner.rb +33 -0
- data/scripts/reenroller.rb +193 -0
- data/scripts/server_importer.rb +293 -0
- data/scripts/shutdown_client.rb +183 -0
- data/scripts/system_configurator.rb +367 -0
- data/scripts/tagger.rb +381 -0
- data/scripts/thunker.rb +356 -0
- metadata +418 -0
@@ -0,0 +1,88 @@
|
|
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
|
+
require 'socket'
|
24
|
+
require 'right_agent/actors/agent_manager'
|
25
|
+
|
26
|
+
# Extend generic agent manager for fault handling
|
27
|
+
AgentManager.class_eval do
|
28
|
+
|
29
|
+
include RightScale::Actor
|
30
|
+
include RightScale::OperationResultHelper
|
31
|
+
|
32
|
+
on_exception { |_, _, _| }
|
33
|
+
|
34
|
+
expose :record_fault, :reenroll
|
35
|
+
|
36
|
+
# Process fault (i.e. mapper failed to decrypt one of our packets)
|
37
|
+
# Vote for re-enrollment
|
38
|
+
#
|
39
|
+
# === Return
|
40
|
+
# (RightScale::OperationResult):: Always returns success
|
41
|
+
def record_fault(_)
|
42
|
+
RightScale::ReenrollManager.vote
|
43
|
+
success_result
|
44
|
+
end
|
45
|
+
|
46
|
+
# Force agent to reenroll now
|
47
|
+
#
|
48
|
+
# === Return
|
49
|
+
# (RightScale::OperationResult):: Always returns success
|
50
|
+
def reenroll(_)
|
51
|
+
RightScale::ReenrollManager.reenroll
|
52
|
+
success_result
|
53
|
+
end
|
54
|
+
|
55
|
+
# Process exception raised by handling of packet
|
56
|
+
# If it's a serialization error and the packet has a valid signature, vote for re-enroll
|
57
|
+
#
|
58
|
+
# === Parameters
|
59
|
+
# e(Exception):: Exception to be analyzed
|
60
|
+
# msg(String):: Serialized message that triggered error
|
61
|
+
#
|
62
|
+
# === Return
|
63
|
+
# true:: Always return true
|
64
|
+
def self.process_exception(e, msg)
|
65
|
+
if e.is_a?(RightScale::Serializer::SerializationError)
|
66
|
+
begin
|
67
|
+
serializer = RightScale::Serializer.new
|
68
|
+
data = serializer.load(msg)
|
69
|
+
sig = RightScale::Signature.from_data(data['signature'])
|
70
|
+
@cert ||= RightScale::Certificate.load(RightScale::AgentConfig.certs_file('mapper.cert'))
|
71
|
+
RightScale::ReenrollManager.vote if sig.match?(@cert)
|
72
|
+
rescue Exception => _
|
73
|
+
RightScale::Log.error("Failed processing serialization error", e)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
true
|
77
|
+
end
|
78
|
+
|
79
|
+
# Process request to restart agent by voting to reenroll
|
80
|
+
#
|
81
|
+
# === Return
|
82
|
+
# true:: Always return true
|
83
|
+
def self.process_restart
|
84
|
+
RightScale::ReenrollManager.vote
|
85
|
+
true
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
@@ -0,0 +1,321 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2009-2012 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
|
+
class InstanceScheduler
|
24
|
+
|
25
|
+
include RightScale::Actor
|
26
|
+
include RightScale::OperationResultHelper
|
27
|
+
|
28
|
+
expose :schedule_bundle, :execute, :schedule_decommission
|
29
|
+
|
30
|
+
SHUTDOWN_DELAY = 180 # Number of seconds to wait for decommission scripts to finish before forcing shutdown
|
31
|
+
|
32
|
+
# Setup signal traps for running decommission scripts
|
33
|
+
# Start worker thread for processing executable bundles
|
34
|
+
#
|
35
|
+
# === Parameters
|
36
|
+
# agent(RightScale::Agent):: Host agent
|
37
|
+
def initialize(agent)
|
38
|
+
@agent = agent
|
39
|
+
@agent_identity = agent.identity
|
40
|
+
|
41
|
+
# invoke the bundles queue factory method as an assist to testing.
|
42
|
+
@bundle_queue_closed_callback = nil
|
43
|
+
@bundle_queue = self.class.create_bundle_queue { @bundle_queue_closed_callback.call }
|
44
|
+
|
45
|
+
# Wait until instance setup actor has initialized the instance state
|
46
|
+
# We need to wait until after the InstanceSetup actor has run its
|
47
|
+
# bundle in the Chef thread before we can use it
|
48
|
+
EM.next_tick do
|
49
|
+
if RightScale::InstanceState.value != 'booting'
|
50
|
+
@bundle_queue.activate
|
51
|
+
else
|
52
|
+
RightScale::InstanceState.observe { |s| @bundle_queue.activate if s != 'booting' }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# Schedule given script bundle so it's run as soon as possible
|
58
|
+
#
|
59
|
+
# === Parameter
|
60
|
+
# bundle(RightScale::ExecutableBundle):: Bundle to be scheduled
|
61
|
+
#
|
62
|
+
# === Return
|
63
|
+
# res(RightScale::OperationResult):: Always returns success
|
64
|
+
def schedule_bundle(bundle)
|
65
|
+
unless bundle.executables.empty?
|
66
|
+
if bundle.respond_to?(:runlist_policy) && bundle.runlist_policy && bundle.runlist_policy.policy_name
|
67
|
+
if RightScale::PolicyManager.registered?(bundle)
|
68
|
+
policy_audit = RightScale::PolicyManager.get_audit(bundle)
|
69
|
+
queue_bundle(bundle, policy_audit)
|
70
|
+
else
|
71
|
+
RightScale::PolicyManager.register(bundle) do |b, policy_audit|
|
72
|
+
queue_bundle(b, policy_audit)
|
73
|
+
end
|
74
|
+
return success_result
|
75
|
+
end
|
76
|
+
else
|
77
|
+
audit = RightScale::AuditProxy.new(bundle.audit_id)
|
78
|
+
queue_bundle(bundle, audit)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
res = success_result
|
82
|
+
end
|
83
|
+
|
84
|
+
def queue_bundle(bundle, audit)
|
85
|
+
thread_name = get_thread_name_from_bundle(bundle)
|
86
|
+
if thread_name == RightScale::AgentConfig.default_thread_name
|
87
|
+
on_thread = ''
|
88
|
+
else
|
89
|
+
on_thread = " on thread #{thread_name}"
|
90
|
+
end
|
91
|
+
|
92
|
+
if @bundle_queue.busy?
|
93
|
+
audit.update_status("Enqueueing #{bundle.to_s} for execution#{on_thread}")
|
94
|
+
else
|
95
|
+
audit.update_status("Scheduling execution of #{bundle.to_s}#{on_thread}")
|
96
|
+
end
|
97
|
+
|
98
|
+
context = RightScale::OperationContext.new(bundle, audit)
|
99
|
+
@bundle_queue.push(context)
|
100
|
+
end
|
101
|
+
|
102
|
+
# FIX: thread_name should never be nil from the core in future, but
|
103
|
+
# temporarily we must supply the default thread_name before if nil. in
|
104
|
+
# future we should fail execution when thread_name is reliably present and
|
105
|
+
# for any reason does not match ::RightScale::AgentConfig.valid_thread_name
|
106
|
+
# see also ExecutableSequenceProxy#initialize
|
107
|
+
#
|
108
|
+
# === Parameters
|
109
|
+
# bundle(ExecutableBundle):: An executable bundle
|
110
|
+
#
|
111
|
+
# === Return
|
112
|
+
# result(String):: Thread name of this bundle
|
113
|
+
def get_thread_name_from_bundle(bundle)
|
114
|
+
thread_name = nil
|
115
|
+
thread_name = bundle.runlist_policy.thread_name if bundle.respond_to?(:runlist_policy) && bundle.runlist_policy
|
116
|
+
RightScale::Log.warn("Encountered a nil thread name unexpectedly, defaulting to '#{RightScale::AgentConfig.default_thread_name}'") unless thread_name
|
117
|
+
thread_name ||= RightScale::AgentConfig.default_thread_name
|
118
|
+
unless thread_name =~ RightScale::AgentConfig.valid_thread_name
|
119
|
+
raise ArgumentError, "Invalid thread name #{thread_name.inspect}"
|
120
|
+
end
|
121
|
+
thread_name
|
122
|
+
end
|
123
|
+
|
124
|
+
# Schedules a shutdown by appending it to the bundles queue.
|
125
|
+
#
|
126
|
+
# === Return
|
127
|
+
# always true
|
128
|
+
def schedule_shutdown
|
129
|
+
@bundle_queue.push(RightScale::BundleQueue::SHUTDOWN_BUNDLE)
|
130
|
+
true
|
131
|
+
end
|
132
|
+
|
133
|
+
# Ask agent to execute given recipe or RightScript
|
134
|
+
# Agent must forward request to core agent which will in turn run schedule_bundle on this agent
|
135
|
+
#
|
136
|
+
# === Parameters
|
137
|
+
# options[:recipe](String):: Recipe name
|
138
|
+
# options[:recipe_id](Integer):: Recipe id
|
139
|
+
# options[:right_script](String):: RightScript name
|
140
|
+
# options[:right_script_id](Integer):: RightScript id
|
141
|
+
# options[:json](Hash):: Serialized hash of attributes to be used when running recipe
|
142
|
+
# options[:thread](String):: Thread name (default is 'default')
|
143
|
+
# options[:arguments](Hash):: RightScript inputs hash
|
144
|
+
#
|
145
|
+
# === Return
|
146
|
+
# true:: Always return true
|
147
|
+
def execute(options)
|
148
|
+
payload = options = RightScale::SerializationHelper.symbolize_keys(options)
|
149
|
+
payload[:agent_identity] = @agent_identity
|
150
|
+
|
151
|
+
forwarder = lambda do |type|
|
152
|
+
send_retryable_request("/forwarder/schedule_#{type}", payload) do |r|
|
153
|
+
r = result_from(r)
|
154
|
+
RightScale::Log.error("Failed executing #{type} for #{payload.inspect}", r.content) unless r.success?
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
if options[:recipe] || options[:recipe_id]
|
159
|
+
forwarder.call("recipe")
|
160
|
+
elsif options[:right_script] || options[:right_script_id]
|
161
|
+
forwarder.call("right_script")
|
162
|
+
else
|
163
|
+
RightScale::Log.error("Unrecognized execute request: #{options.inspect}")
|
164
|
+
return true
|
165
|
+
end
|
166
|
+
true
|
167
|
+
end
|
168
|
+
|
169
|
+
# Schedule decommission, returns an error if instance is already decommissioning
|
170
|
+
#
|
171
|
+
# === Parameter
|
172
|
+
# options[:bundle](RightScale::ExecutableBundle):: Decommission bundle
|
173
|
+
# options[:user_id](Integer):: User id which requested decommission
|
174
|
+
# options[:skip_db_update](FalseClass|TrueClass):: Whether to requery instance state (false)
|
175
|
+
# options[:kind](String):: 'terminate', 'stop' or 'reboot'
|
176
|
+
#
|
177
|
+
# === Return
|
178
|
+
# (RightScale::OperationResult):: Status value, either success or error with message
|
179
|
+
def schedule_decommission(options)
|
180
|
+
case RightScale::InstanceState.value
|
181
|
+
when 'decommissioning', 'decommissioned'
|
182
|
+
return error_result('Instance is already decommissioning')
|
183
|
+
end
|
184
|
+
options = RightScale::SerializationHelper.symbolize_keys(options)
|
185
|
+
bundle = options[:bundle]
|
186
|
+
decommission_type = options[:kind]
|
187
|
+
audit = RightScale::AuditProxy.new(bundle.audit_id)
|
188
|
+
|
189
|
+
# see note below for reason why decommission_type would be nil.
|
190
|
+
context = RightScale::OperationContext.new(
|
191
|
+
bundle, audit,
|
192
|
+
:decommission_type => decommission_type || 'unknown')
|
193
|
+
|
194
|
+
# This is the tricky bit: only set a post decommission callback if there wasn't one already set
|
195
|
+
# by 'run_decommission'. This default callback will shutdown the instance for soft-termination.
|
196
|
+
# The callback set by 'run_decommission' can do other things before calling 'terminate' manually.
|
197
|
+
# 'terminate' will *not* shutdown the machine. This is so that when running the decommission
|
198
|
+
# sequence as part of a non-soft termination we don't call shutdown.
|
199
|
+
unless @bundle_queue_closed_callback
|
200
|
+
@shutdown_timeout = EM::Timer.new(SHUTDOWN_DELAY) do
|
201
|
+
@shutdown_timeout = nil
|
202
|
+
msg = "Failed to decommission in less than #{SHUTDOWN_DELAY / 60} minutes, forcing shutdown"
|
203
|
+
audit.append_error(msg, :category => RightScale::EventCategories::CATEGORY_ERROR)
|
204
|
+
RightScale::InstanceState.value = 'decommissioned'
|
205
|
+
RightScale::InstanceState.shutdown(options[:user_id], options[:skip_db_update], decommission_type)
|
206
|
+
end
|
207
|
+
@bundle_queue_closed_callback = make_decommission_callback do
|
208
|
+
@shutdown_timeout.cancel if @shutdown_timeout
|
209
|
+
@shutdown_timeout = nil
|
210
|
+
RightScale::InstanceState.shutdown(options[:user_id], options[:skip_db_update], decommission_type)
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
@bundle_queue.clear # Cancel any pending bundle
|
215
|
+
unless bundle.executables.empty?
|
216
|
+
audit.update_status("Scheduling execution of #{bundle.to_s} for decommission")
|
217
|
+
@bundle_queue.push(context)
|
218
|
+
end
|
219
|
+
@bundle_queue.close
|
220
|
+
|
221
|
+
# transition state to 'decommissioning' (by setting decommissioning_type if given)
|
222
|
+
#
|
223
|
+
# note that decommission_type can be nil in case where a script or user
|
224
|
+
# shuts down the instance manually (without using rs_shutdown, etc.).
|
225
|
+
# more specifically, it happens when "rnac --decommission" is invoked
|
226
|
+
# either directly or indirectly (on Linux by runlevel 0|6 script).
|
227
|
+
if decommission_type
|
228
|
+
RightScale::InstanceState.decommission_type = decommission_type
|
229
|
+
else
|
230
|
+
RightScale::InstanceState.value = 'decommissioning'
|
231
|
+
end
|
232
|
+
success_result
|
233
|
+
end
|
234
|
+
|
235
|
+
# Schedule decommission and call given block back once decommission bundle has run
|
236
|
+
# Note: Overrides existing post decommission callback if there was one
|
237
|
+
# This is so that if the instance is being hard-terminated after soft-termination has started
|
238
|
+
# then we won't try to tell the core agent to terminate us again once decommission is done
|
239
|
+
#
|
240
|
+
# === Block
|
241
|
+
# Block to yield once decommission is done
|
242
|
+
#
|
243
|
+
# === Return
|
244
|
+
# true:: Aways return true
|
245
|
+
def run_decommission(&callback)
|
246
|
+
if RightScale::InstanceState.value == 'decommissioned'
|
247
|
+
# We are already decommissioned, just call the post decommission callback
|
248
|
+
callback.call if callback
|
249
|
+
else
|
250
|
+
# set (or override if already decommissioning) bundle queue closed callback.
|
251
|
+
@bundle_queue_closed_callback = make_decommission_callback(&callback)
|
252
|
+
if RightScale::InstanceState.value != 'decommissioning'
|
253
|
+
# Trigger decommission
|
254
|
+
send_retryable_request('/booter/get_decommission_bundle', {:agent_identity => @agent_identity}) do |r|
|
255
|
+
res = result_from(r)
|
256
|
+
if res.success?
|
257
|
+
schedule_decommission(:bundle => res.content)
|
258
|
+
else
|
259
|
+
RightScale::Log.debug("Failed to retrieve decommission bundle: #{res.content}")
|
260
|
+
end
|
261
|
+
end
|
262
|
+
end
|
263
|
+
end
|
264
|
+
true
|
265
|
+
end
|
266
|
+
|
267
|
+
# Terminate self immediately, abandoning any executing bundles.
|
268
|
+
# Note: Will *not* run the decommission scripts; call run_decommission (which
|
269
|
+
# yields when fully decommissioned) if you need to decommission before
|
270
|
+
# terminating agent.
|
271
|
+
#
|
272
|
+
# === Return
|
273
|
+
# true: always true
|
274
|
+
def terminate
|
275
|
+
# close must abandon any executing bundles and yield in timely fashion.
|
276
|
+
if @bundle_queue.active?
|
277
|
+
# set (or override if already decommissioning) bundle queue closed
|
278
|
+
# callback. we intentionally abandon any decommission bundle if an
|
279
|
+
# explicit terminate request is received (so calling code should wait for
|
280
|
+
# decommission to finish before calling terminate).
|
281
|
+
@bundle_queue_closed_callback = lambda { inner_terminate }
|
282
|
+
@bundle_queue.clear
|
283
|
+
@bundle_queue.close
|
284
|
+
else
|
285
|
+
inner_terminate
|
286
|
+
end
|
287
|
+
true
|
288
|
+
end
|
289
|
+
|
290
|
+
protected
|
291
|
+
|
292
|
+
# Factory method for a new bundles queue.
|
293
|
+
def self.create_bundle_queue(&block)
|
294
|
+
return RightScale::MultiThreadBundleQueue.new(&block)
|
295
|
+
end
|
296
|
+
|
297
|
+
# Prefixes the transition to 'decommissioned' state before callback.
|
298
|
+
#
|
299
|
+
# === Block
|
300
|
+
# yielded after state change
|
301
|
+
def make_decommission_callback
|
302
|
+
return lambda do
|
303
|
+
RightScale::InstanceState.value = 'decommissioned'
|
304
|
+
yield
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
# Called internally when it is safe to terminate agent.
|
309
|
+
#
|
310
|
+
# === Return
|
311
|
+
# true: always true
|
312
|
+
def inner_terminate
|
313
|
+
# stop listening.
|
314
|
+
RightScale::CommandRunner.stop
|
315
|
+
|
316
|
+
# Delay terminate a bit to give reply a chance to be sent
|
317
|
+
EM.next_tick { @agent.terminate }
|
318
|
+
true
|
319
|
+
end
|
320
|
+
|
321
|
+
end # InstanceScheduler
|
@@ -0,0 +1,64 @@
|
|
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
|
+
class InstanceServices
|
24
|
+
|
25
|
+
include RightScale::Actor
|
26
|
+
include RightScale::OperationResultHelper
|
27
|
+
|
28
|
+
expose :update_login_policy
|
29
|
+
|
30
|
+
def initialize(agent_identity)
|
31
|
+
@agent_identity = agent_identity
|
32
|
+
end
|
33
|
+
|
34
|
+
# Always return success, used for troubleshooting
|
35
|
+
#
|
36
|
+
# == Parameters:
|
37
|
+
# @param [RightScale::LoginPolicy] new login policy to update the instance with
|
38
|
+
#
|
39
|
+
# == Returns:
|
40
|
+
# @return [RightScale::OperationResult] Always returns success
|
41
|
+
#
|
42
|
+
def update_login_policy(new_policy)
|
43
|
+
status = nil
|
44
|
+
|
45
|
+
RightScale::AuditProxy.create(@agent_identity, 'Updating managed login policy') do |audit|
|
46
|
+
begin
|
47
|
+
RightScale::LoginManager.instance.update_policy(new_policy, @agent_identity) do |audit_content|
|
48
|
+
if audit_content
|
49
|
+
audit.create_new_section('Managed login policy updated', :category => RightScale::EventCategories::CATEGORY_SECURITY)
|
50
|
+
audit.append_info(audit_content)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
status = success_result
|
54
|
+
rescue Exception => e
|
55
|
+
audit.create_new_section('Failed to update managed login policy', :category => RightScale::EventCategories::CATEGORY_SECURITY)
|
56
|
+
audit.append_error("Error applying login policy: #{e.message}", :category => RightScale::EventCategories::CATEGORY_ERROR)
|
57
|
+
RightScale::Log.error('Failed to update managed login policy', e, :trace)
|
58
|
+
status = error_result("#{e.class.name}: #{e.message}")
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
status
|
63
|
+
end
|
64
|
+
end
|