right_link 5.9.0
Sign up to get free protection for your applications and to get access to all the features.
- 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,144 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2010-11 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.normalize_path(File.join(File.dirname(__FILE__), 'metadata_tree_climber'))
|
24
|
+
|
25
|
+
module RightScale
|
26
|
+
|
27
|
+
# Provides rules for building a standard metadata tree from raw data and
|
28
|
+
# expanding multi-line leaf values into arrays. Details of querying raw
|
29
|
+
# metadata are external to this class.
|
30
|
+
class MetadataTreeClimber
|
31
|
+
|
32
|
+
attr_accessor :root_path, :tree_class, :child_name_delimiter
|
33
|
+
|
34
|
+
# Initializer.
|
35
|
+
#
|
36
|
+
# === Parameters
|
37
|
+
# options[:tree_class](Class):: Hash-like class to use when building
|
38
|
+
# metadata tree (defaults to Hash)
|
39
|
+
def initialize(options = {})
|
40
|
+
# parameters
|
41
|
+
raise ArgumentError.new("options[:root_path] is required") unless @root_path = options[:root_path]
|
42
|
+
raise ArgumentError.new("options[:user_metadata_root_path] is required") unless @user_metadata_root_path = options[:user_metadata_root_path]
|
43
|
+
@tree_class = options[:tree_class] || Hash
|
44
|
+
@child_name_delimiter = options[:child_name_delimiter] || "\n"
|
45
|
+
|
46
|
+
# callbacks (optional)
|
47
|
+
@branch_key_override = options[:branch_key_override]
|
48
|
+
@child_names_override = options[:child_names_override]
|
49
|
+
@create_leaf_override = options[:create_leaf_override]
|
50
|
+
@has_children_override = options[:has_children_override]
|
51
|
+
@leaf_key_override = options[:leaf_key_override]
|
52
|
+
end
|
53
|
+
|
54
|
+
# Determines if the given path represents a parent branch. This information
|
55
|
+
# can be empirically determined from the path by the appearance of a
|
56
|
+
# trailing forward slash using the HTTP convention (even if metadata source
|
57
|
+
# is not an HTTP connection) except for the root which must be tested
|
58
|
+
# specially.
|
59
|
+
#
|
60
|
+
# === Parameters
|
61
|
+
# path(String):: path to metadata
|
62
|
+
# query_result(String):: raw data queried using path
|
63
|
+
#
|
64
|
+
# === Return
|
65
|
+
# result(Boolean):: true if branch, false if leaf
|
66
|
+
def has_children?(path, query_result)
|
67
|
+
return @has_children_override.call(self, path, query_result) if @has_children_override
|
68
|
+
# default behavior for user metadata is flat; currently no known use cases of hierarchical user metadata.
|
69
|
+
return (@user_metadata_root_path != @root_path) && ('/' == path[-1..-1] || path == @root_path)
|
70
|
+
end
|
71
|
+
|
72
|
+
# Determines if the given raw value contains branch/leaf names and returns
|
73
|
+
# them as pair of Hash-like objects of keys with nil values.
|
74
|
+
#
|
75
|
+
# === Parameters
|
76
|
+
# path(String):: path to metadata
|
77
|
+
# query_result(String):: raw data queried using path
|
78
|
+
#
|
79
|
+
# === Returns
|
80
|
+
# result(Array):: array of child (leaf or branch) names or empty
|
81
|
+
def child_names(path, query_result)
|
82
|
+
return @child_names_override.call(self, path, query_result) if @child_names_override
|
83
|
+
child_names = []
|
84
|
+
sub_values = query_result.gsub("\r\n", "\n").split(@child_name_delimiter)
|
85
|
+
sub_values.each do |sub_value|
|
86
|
+
sub_value.strip!
|
87
|
+
(child_names << sub_value) unless sub_value.empty?
|
88
|
+
end
|
89
|
+
return child_names
|
90
|
+
end
|
91
|
+
|
92
|
+
# Creates a new empty tree node based on the class specified in options.
|
93
|
+
#
|
94
|
+
# === Returns
|
95
|
+
# result(Hash):: new Hash-like node
|
96
|
+
def create_branch
|
97
|
+
@tree_class.new
|
98
|
+
end
|
99
|
+
|
100
|
+
# Creates a new leaf using the given information (from which leaf type can
|
101
|
+
# be inferred, etc.).
|
102
|
+
#
|
103
|
+
# === Parameters
|
104
|
+
# path(String):: path to metadata
|
105
|
+
# data(String):: raw data queried using path
|
106
|
+
#
|
107
|
+
def create_leaf(path, data)
|
108
|
+
return @create_leaf_override.call(self, data) if @create_leaf_override
|
109
|
+
return data.to_s.strip
|
110
|
+
end
|
111
|
+
|
112
|
+
# Looks for equals anywhere in the sub-value or trailing forward slash at
|
113
|
+
# the end of the sub-value.
|
114
|
+
#
|
115
|
+
# === Parameters
|
116
|
+
# branch_name(String):: branch name
|
117
|
+
#
|
118
|
+
# === Returns
|
119
|
+
# key(String):: branch key or nil
|
120
|
+
def branch_key(branch_name)
|
121
|
+
return @branch_key_override.call(self, branch_name) if (branch_name && @branch_key_override)
|
122
|
+
|
123
|
+
# replace any equals and subsequent text with forward slash and chomp any
|
124
|
+
# trailing slash. note that chomp! returns nil if character (i.e. slash)
|
125
|
+
# is not found at end.
|
126
|
+
return branch_name.gsub(/=.*$/, '/').gsub('-', '_').chomp!('/')
|
127
|
+
end
|
128
|
+
|
129
|
+
# Leaf name is used as key by default.
|
130
|
+
#
|
131
|
+
# === Parameters
|
132
|
+
# leaf_name(String):: leaf name
|
133
|
+
#
|
134
|
+
# === Returns
|
135
|
+
# key(String):: leaf key or nil
|
136
|
+
def leaf_key(leaf_name)
|
137
|
+
return @leaf_key_override.call(self, leaf_name) if @leaf_key_override
|
138
|
+
# replace '-' and '/' with '_' so that metadata keys are Mash friendly
|
139
|
+
return leaf_name.gsub('-', '_')
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
@@ -0,0 +1,155 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2010 by RightScale Inc., all rights reserved
|
3
|
+
#
|
4
|
+
# Write given user data to files in /var/spool/ec2 in text, shell and ruby
|
5
|
+
# script formats
|
6
|
+
|
7
|
+
module RightScale
|
8
|
+
|
9
|
+
# Base implementation for a metadata writer. By default writes a raw
|
10
|
+
# metadata format.
|
11
|
+
class MetadataWriter
|
12
|
+
DEFAULT_FILE_MODE = 0640
|
13
|
+
|
14
|
+
attr_accessor :file_extension, :file_name_prefix, :output_dir_path
|
15
|
+
|
16
|
+
# Initializer
|
17
|
+
#
|
18
|
+
# === Parameters
|
19
|
+
# options[:file_extension](String):: output file extension
|
20
|
+
# options[:file_name_prefix](String):: output file name sans extension
|
21
|
+
# options[:output_dir_path](String):: output directory, defaults to RS spool dir
|
22
|
+
# options[:read_override](Proc(reader, subpath):: read override or nil
|
23
|
+
# options[:write_override](Proc(writer, metadata subpath):: write override or nil
|
24
|
+
#
|
25
|
+
# === Return
|
26
|
+
# always true
|
27
|
+
def initialize(options)
|
28
|
+
raise ArgumentError.new("options[:file_name_prefix] is required") unless @file_name_prefix = options[:file_name_prefix]
|
29
|
+
raise ArgumentError.new("options[:output_dir_path] is required") unless @output_dir_path = options[:output_dir_path]
|
30
|
+
@file_extension = options[:file_extension] || '.raw'
|
31
|
+
@read_override = options[:read_override]
|
32
|
+
@write_override = options[:write_override]
|
33
|
+
end
|
34
|
+
|
35
|
+
# Reads metadata from file.
|
36
|
+
#
|
37
|
+
# === Parameters
|
38
|
+
# subpath(Array|String):: subpath or nil
|
39
|
+
#
|
40
|
+
# === Return
|
41
|
+
# result(String):: contents of generated file
|
42
|
+
def read(subpath = nil)
|
43
|
+
return @read_override.call(self, subpath) if @read_override
|
44
|
+
return read_file(subpath)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Writes given metadata to file.
|
48
|
+
#
|
49
|
+
# === Parameters
|
50
|
+
# metadata(Hash):: Hash-like metadata
|
51
|
+
# subpath(Array|String):: subpath if deeper than root or nil
|
52
|
+
#
|
53
|
+
# === Return
|
54
|
+
# always true
|
55
|
+
def write(metadata, subpath = nil)
|
56
|
+
return @write_override.call(self, metadata, subpath) if @write_override
|
57
|
+
return write_file(metadata, subpath)
|
58
|
+
end
|
59
|
+
|
60
|
+
# Escapes double-quotes (and literal backslashes since they are escape
|
61
|
+
# characters) in the given string.
|
62
|
+
def self.escape_double_quotes(value)
|
63
|
+
return value.gsub(/\\|"/) { |c| "\\#{c}" }
|
64
|
+
end
|
65
|
+
|
66
|
+
# Escapes single-quotes (and literal backslashes since they are escape
|
67
|
+
# characters) in the given string.
|
68
|
+
def self.escape_single_quotes(value)
|
69
|
+
return value.gsub(/\\|'/) { |c| "\\#{c}" }
|
70
|
+
end
|
71
|
+
|
72
|
+
# Determines the first line of text (or the only line) for the given value.
|
73
|
+
#
|
74
|
+
# === Parameters
|
75
|
+
# value(Object):: any value
|
76
|
+
#
|
77
|
+
# === Return
|
78
|
+
# result(String):: first line or empty
|
79
|
+
def self.first_line_of(value)
|
80
|
+
# flatten any value which supports it
|
81
|
+
value = value.flatten if value.respond_to?(:flatten)
|
82
|
+
|
83
|
+
# note that the active_support gem redefines String.first from being the
|
84
|
+
# same as .lines.first to returning the .first(n=1) characters.
|
85
|
+
if value.respond_to?(:lines)
|
86
|
+
value = value.lines.first
|
87
|
+
elsif value.respond_to?(:first)
|
88
|
+
value = value.first
|
89
|
+
end
|
90
|
+
return value.to_s.strip
|
91
|
+
end
|
92
|
+
|
93
|
+
protected
|
94
|
+
|
95
|
+
# Full path of generated file.
|
96
|
+
#
|
97
|
+
# === Parameters
|
98
|
+
# file_name(String):: output file name without extension
|
99
|
+
# subpath(Array|String):: subpath if deeper than root or nil
|
100
|
+
#
|
101
|
+
# === Return
|
102
|
+
# result(String):: full path of generated file
|
103
|
+
def full_path(file_name, subpath = nil)
|
104
|
+
if subpath
|
105
|
+
# legacy ec2 support omits file extension and creates a parent dir
|
106
|
+
# using file name prefix; this is the default behavior.
|
107
|
+
subpath = subpath.join('-') if subpath.kind_of?(Array)
|
108
|
+
subpath = subpath.gsub(/[\/\\]+/, '-').gsub(/^-+|-+$/, '')
|
109
|
+
return File.normalize_path(File.join(@output_dir_path, file_name, subpath)) unless subpath.empty?
|
110
|
+
end
|
111
|
+
|
112
|
+
return File.normalize_path(File.join(@output_dir_path, "#{file_name}#{@file_extension}"))
|
113
|
+
end
|
114
|
+
|
115
|
+
# Creates the parent directory for the full path of generated file.
|
116
|
+
#
|
117
|
+
# === Parameters
|
118
|
+
# file_name(String):: output file name without extension
|
119
|
+
# subpath(Array|String):: subpath if deeper than root or nil
|
120
|
+
#
|
121
|
+
# === Return
|
122
|
+
# result(String):: full path of generated file
|
123
|
+
def create_full_path(file_name, subpath = nil)
|
124
|
+
path = full_path(file_name, subpath)
|
125
|
+
FileUtils.mkdir_p(File.dirname(path))
|
126
|
+
path
|
127
|
+
end
|
128
|
+
|
129
|
+
# Reads metadata from file.
|
130
|
+
#
|
131
|
+
# === Parameters
|
132
|
+
# subpath(Array|String):: subpath if deeper than root or nil
|
133
|
+
#
|
134
|
+
# === Return
|
135
|
+
# result(String):: contents of generated file or empty
|
136
|
+
def read_file(subpath)
|
137
|
+
path = full_path(@file_name_prefix, subpath)
|
138
|
+
return File.file?(path) ? File.read(path) : ''
|
139
|
+
end
|
140
|
+
|
141
|
+
# Writes given metadata to file.
|
142
|
+
#
|
143
|
+
# === Parameters
|
144
|
+
# metadata(Hash):: Hash-like metadata to write
|
145
|
+
# subpath(Array|String):: subpath if deeper than root or nil
|
146
|
+
#
|
147
|
+
# === Return
|
148
|
+
# always true
|
149
|
+
def write_file(metadata, subpath)
|
150
|
+
File.open(create_full_path(@file_name_prefix, subpath), "w", DEFAULT_FILE_MODE) { |f| f.write(metadata.to_s) }
|
151
|
+
end
|
152
|
+
|
153
|
+
end # MetadataWriter
|
154
|
+
|
155
|
+
end # RightScale
|
@@ -0,0 +1,72 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2010 by RightScale Inc., all rights reserved
|
3
|
+
#
|
4
|
+
# Write given user data to files in /var/spool/ec2 in text, shell and ruby
|
5
|
+
# script formats
|
6
|
+
|
7
|
+
module RightScale
|
8
|
+
|
9
|
+
module MetadataWriters
|
10
|
+
|
11
|
+
# Dictionary (key=value pairs) writer.
|
12
|
+
class DictionaryMetadataWriter < MetadataWriter
|
13
|
+
|
14
|
+
# Initializer.
|
15
|
+
#
|
16
|
+
# === Parameters
|
17
|
+
# options[:file_extension](String):: dotted extension for dictionary files or nil
|
18
|
+
def initialize(options)
|
19
|
+
# defaults
|
20
|
+
options = options.dup
|
21
|
+
options[:file_extension] ||= '.dict'
|
22
|
+
|
23
|
+
# super
|
24
|
+
super(options)
|
25
|
+
end
|
26
|
+
|
27
|
+
protected
|
28
|
+
|
29
|
+
# Read a dictionary file on disk and parse into key/value pairs.
|
30
|
+
#
|
31
|
+
# === Parameters
|
32
|
+
# subpath(Array|String):: subpath or nil
|
33
|
+
#
|
34
|
+
# === Return
|
35
|
+
# result(Hash):: dictionary of metadata
|
36
|
+
def read_file(subpath = nil)
|
37
|
+
result = {}
|
38
|
+
path = full_path(@file_name_prefix, subpath)
|
39
|
+
contents = File.file?(path) ? File.read(path) : ''
|
40
|
+
contents.each do |line|
|
41
|
+
match = line.chomp.match(/^(.+)=(.*)$/)
|
42
|
+
result[match[1]] = match[2]
|
43
|
+
end
|
44
|
+
result
|
45
|
+
end
|
46
|
+
|
47
|
+
# Write given metadata to a dictionary file.
|
48
|
+
#
|
49
|
+
# === Parameters
|
50
|
+
# metadata(Hash):: Hash-like metadata to write
|
51
|
+
# subpath(Array|String):: subpath or nil
|
52
|
+
#
|
53
|
+
# === Return
|
54
|
+
# always true
|
55
|
+
def write_file(metadata, subpath = nil)
|
56
|
+
return super(metadata, subpath) unless metadata.respond_to?(:has_key?)
|
57
|
+
File.open(create_full_path(@file_name_prefix, subpath), "w", DEFAULT_FILE_MODE) do |f|
|
58
|
+
metadata.each do |k, v|
|
59
|
+
# ensure value is a single line by truncation since most
|
60
|
+
# dictionary format parsers expect literal chars on a single line.
|
61
|
+
v = self.class.first_line_of(v)
|
62
|
+
f.puts "#{k}=#{v}"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
true
|
66
|
+
end
|
67
|
+
|
68
|
+
end # DictionaryMetadataWriter
|
69
|
+
|
70
|
+
end # MetadataWriters
|
71
|
+
|
72
|
+
end # RightScale
|
@@ -0,0 +1,76 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2010 by RightScale Inc., all rights reserved
|
3
|
+
#
|
4
|
+
# Write given user data to files in /var/spool/ec2 in text, shell and ruby
|
5
|
+
# script formats
|
6
|
+
|
7
|
+
module RightScale
|
8
|
+
|
9
|
+
module MetadataWriters
|
10
|
+
|
11
|
+
# Ruby script writer
|
12
|
+
class RubyMetadataWriter < MetadataWriter
|
13
|
+
|
14
|
+
attr_accessor :generation_command
|
15
|
+
|
16
|
+
# Initializer.
|
17
|
+
#
|
18
|
+
# === Parameters
|
19
|
+
# options[:file_extension](String):: dotted extension for ruby files or nil
|
20
|
+
def initialize(options)
|
21
|
+
# defaults
|
22
|
+
options = options.dup
|
23
|
+
options[:file_extension] ||= '.rb'
|
24
|
+
|
25
|
+
# super
|
26
|
+
super(options)
|
27
|
+
|
28
|
+
# local options.
|
29
|
+
@generation_command = options[:generation_command]
|
30
|
+
end
|
31
|
+
|
32
|
+
protected
|
33
|
+
|
34
|
+
RUBY_HEADER = ['# Warning: this file has been auto-generated',
|
35
|
+
'# any modifications can be overwritten']
|
36
|
+
|
37
|
+
# Write given metadata to a ruby file.
|
38
|
+
#
|
39
|
+
# === Parameters
|
40
|
+
# file_name_prefix(String):: name prefix for generated file
|
41
|
+
# metadata(Hash):: Hash-like metadata to write
|
42
|
+
# subpath(Array|String):: subpath or nil
|
43
|
+
#
|
44
|
+
# === Return
|
45
|
+
# always true
|
46
|
+
def write_file(metadata, subpath)
|
47
|
+
return super(metadata, subpath) unless metadata.respond_to?(:has_key?)
|
48
|
+
|
49
|
+
# write the cached file variant if the code-generation command line was passed.
|
50
|
+
env_file_name = @generation_command ? "#{@file_name_prefix}-cache" : @file_name_prefix
|
51
|
+
env_file_path = create_full_path(env_file_name, subpath)
|
52
|
+
File.open(env_file_path, "w", DEFAULT_FILE_MODE) do |f|
|
53
|
+
f.puts RUBY_HEADER
|
54
|
+
metadata.each do |k, v|
|
55
|
+
# escape backslashes and single quotes.
|
56
|
+
v = self.class.escape_single_quotes(v)
|
57
|
+
f.puts "ENV['#{k}']='#{v}'"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# write the generation command, if given.
|
62
|
+
if @generation_command
|
63
|
+
File.open(create_full_path(@file_name_prefix, subpath), "w", DEFAULT_FILE_MODE) do |f|
|
64
|
+
f.puts RUBY_HEADER
|
65
|
+
f.puts "raise 'ERROR: unable to fetch metadata' unless system(\"#{@generation_command}\")"
|
66
|
+
f.puts "require '#{env_file_path}'"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
true
|
70
|
+
end
|
71
|
+
|
72
|
+
end # RubyMetadataWriter
|
73
|
+
|
74
|
+
end # MetadataWriters
|
75
|
+
|
76
|
+
end # RightScale
|
@@ -0,0 +1,121 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2010 by RightScale Inc., all rights reserved
|
3
|
+
#
|
4
|
+
# Write given user data to files in /var/spool/ec2 in text, shell and ruby
|
5
|
+
# script formats
|
6
|
+
|
7
|
+
module RightScale
|
8
|
+
|
9
|
+
module MetadataWriters
|
10
|
+
|
11
|
+
# Shell script writer.
|
12
|
+
class ShellMetadataWriter < MetadataWriter
|
13
|
+
|
14
|
+
attr_accessor :generation_command
|
15
|
+
|
16
|
+
# Initializer.
|
17
|
+
#
|
18
|
+
# === Parameters
|
19
|
+
# options[:file_extension](String):: dotted extension for shell files or nil
|
20
|
+
def initialize(options)
|
21
|
+
# defaults
|
22
|
+
options = options.dup
|
23
|
+
default_file_extension = RightScale::Platform.windows? ? '.bat' : '.sh'
|
24
|
+
options[:file_extension] ||= default_file_extension
|
25
|
+
@generation_command = options[:generation_command]
|
26
|
+
|
27
|
+
# super
|
28
|
+
super(options)
|
29
|
+
end
|
30
|
+
|
31
|
+
protected
|
32
|
+
|
33
|
+
if RightScale::Platform.windows?
|
34
|
+
|
35
|
+
WINDOWS_SHELL_HEADER = ['@echo off',
|
36
|
+
'rem # Warning: this file has been auto-generated',
|
37
|
+
'rem # any modifications can be overwritten']
|
38
|
+
|
39
|
+
# Write given metadata to a bash file.
|
40
|
+
#
|
41
|
+
# === Parameters
|
42
|
+
# metadata(Hash):: Hash-like metadata to write
|
43
|
+
# subpath(Array|String):: subpath or nil
|
44
|
+
#
|
45
|
+
# === Return
|
46
|
+
# always true
|
47
|
+
def write_file(metadata, subpath)
|
48
|
+
return super(metadata, subpath) unless metadata.respond_to?(:has_key?)
|
49
|
+
|
50
|
+
# write the cached file variant if the code-generation command line was passed.
|
51
|
+
env_file_name = @generation_command ? "#{@file_name_prefix}-cache" : @file_name_prefix
|
52
|
+
env_file_path = create_full_path(env_file_name, subpath)
|
53
|
+
File.open(env_file_path, "w", DEFAULT_FILE_MODE) do |f|
|
54
|
+
f.puts(WINDOWS_SHELL_HEADER)
|
55
|
+
metadata.each do |k, v|
|
56
|
+
# ensure value is a single line (multiple lines could be interpreted
|
57
|
+
# as subsequent commands) by truncation since windows shell doesn't
|
58
|
+
# have escape characters.
|
59
|
+
v = self.class.first_line_of(v)
|
60
|
+
f.puts "set #{k}=#{v}"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# write the generation command, if given.
|
65
|
+
if @generation_command
|
66
|
+
File.open(create_full_path(@file_name_prefix, subpath), "w", DEFAULT_FILE_MODE) do |f|
|
67
|
+
f.puts(WINDOWS_SHELL_HEADER)
|
68
|
+
f.puts(@generation_command)
|
69
|
+
f.puts("call \"#{env_file_path}\"")
|
70
|
+
end
|
71
|
+
end
|
72
|
+
true
|
73
|
+
end
|
74
|
+
|
75
|
+
else # not windows
|
76
|
+
|
77
|
+
LINUX_SHELL_HEADER = ['#!/bin/bash',
|
78
|
+
'# Warning: this file has been auto-generated',
|
79
|
+
'# any modifications can be overwritten']
|
80
|
+
|
81
|
+
# Write given metadata to a bash file.
|
82
|
+
#
|
83
|
+
# === Parameters
|
84
|
+
# metadata(Hash):: Hash-like metadata to write
|
85
|
+
# subpath(Array|String):: subpath or nil
|
86
|
+
#
|
87
|
+
# === Return
|
88
|
+
# always true
|
89
|
+
def write_file( metadata, subpath)
|
90
|
+
return super(metadata, subpath) unless metadata.respond_to?(:has_key?)
|
91
|
+
|
92
|
+
# write the cached file variant if the code-generation command line was passed.
|
93
|
+
env_file_name = @generation_command ? "#{@file_name_prefix}-cache" : @file_name_prefix
|
94
|
+
env_file_path = create_full_path(env_file_name, subpath)
|
95
|
+
File.open(env_file_path, "w", DEFAULT_FILE_MODE) do |f|
|
96
|
+
f.puts(LINUX_SHELL_HEADER)
|
97
|
+
metadata.each do |k, v|
|
98
|
+
# escape backslashes and double quotes.
|
99
|
+
v = self.class.escape_double_quotes(v)
|
100
|
+
f.puts "export #{k}=\"#{v}\""
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# write the generation command, if given.
|
105
|
+
if @generation_command
|
106
|
+
File.open(create_full_path(@file_name_prefix, subpath), "w", DEFAULT_FILE_MODE) do |f|
|
107
|
+
f.puts(LINUX_SHELL_HEADER)
|
108
|
+
f.puts(@generation_command)
|
109
|
+
f.puts(". #{env_file_path}")
|
110
|
+
end
|
111
|
+
end
|
112
|
+
true
|
113
|
+
end
|
114
|
+
|
115
|
+
end # if windows
|
116
|
+
|
117
|
+
end # ShellMetadataWriter
|
118
|
+
|
119
|
+
end # MetadataWriters
|
120
|
+
|
121
|
+
end # RightScale
|
@@ -0,0 +1,34 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 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 File.normalize_path(File.join(File.dirname(__FILE__), '..', 'clouds'))
|
24
|
+
|
25
|
+
begin
|
26
|
+
base_clouds_dir_path = File.join(File.dirname(__FILE__), 'clouds')
|
27
|
+
|
28
|
+
# dynamically register all clouds using the script name as cloud name.
|
29
|
+
pattern = File.join(base_clouds_dir_path, '*.rb')
|
30
|
+
Dir[pattern].each do |cloud_script_path|
|
31
|
+
cloud_name = File.basename(cloud_script_path, '.rb')
|
32
|
+
RightScale::CloudFactory.instance.register(cloud_name, cloud_script_path)
|
33
|
+
end
|
34
|
+
end
|
data/lib/clouds.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 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
|
+
CLOUDS_BASE_DIR = File.join(File.dirname(__FILE__), 'clouds')
|
24
|
+
|
25
|
+
require File.normalize_path(File.join(CLOUDS_BASE_DIR, 'cloud'))
|
26
|
+
require File.normalize_path(File.join(CLOUDS_BASE_DIR, 'cloud_factory'))
|
27
|
+
require File.normalize_path(File.join(CLOUDS_BASE_DIR, 'cloud_utilities'))
|
28
|
+
require File.normalize_path(File.join(CLOUDS_BASE_DIR, 'metadata_formatter'))
|
29
|
+
require File.normalize_path(File.join(CLOUDS_BASE_DIR, 'metadata_provider'))
|
30
|
+
require File.normalize_path(File.join(CLOUDS_BASE_DIR, 'metadata_source'))
|
31
|
+
require File.normalize_path(File.join(CLOUDS_BASE_DIR, 'metadata_tree_climber'))
|
32
|
+
require File.normalize_path(File.join(CLOUDS_BASE_DIR, 'metadata_writer'))
|