ec2_amitools 1.0.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.
- checksums.yaml +7 -0
- data/README.md +54 -0
- data/bin/console +14 -0
- data/bin/ec2-ami-tools-version +6 -0
- data/bin/ec2-bundle-image +6 -0
- data/bin/ec2-bundle-vol +6 -0
- data/bin/ec2-delete-bundle +6 -0
- data/bin/ec2-download-bundle +6 -0
- data/bin/ec2-migrate-bundle +6 -0
- data/bin/ec2-migrate-manifest +6 -0
- data/bin/ec2-unbundle +6 -0
- data/bin/ec2-upload-bundle +6 -0
- data/bin/setup +8 -0
- data/etc/ec2/amitools/cert-ec2-cn-north-1.pem +28 -0
- data/etc/ec2/amitools/cert-ec2-gov.pem +17 -0
- data/etc/ec2/amitools/cert-ec2.pem +23 -0
- data/etc/ec2/amitools/mappings.csv +9 -0
- data/lib/ec2/amitools/bundle.rb +251 -0
- data/lib/ec2/amitools/bundle_base.rb +58 -0
- data/lib/ec2/amitools/bundleimage.rb +94 -0
- data/lib/ec2/amitools/bundleimageparameters.rb +42 -0
- data/lib/ec2/amitools/bundlemachineparameters.rb +60 -0
- data/lib/ec2/amitools/bundleparameters.rb +120 -0
- data/lib/ec2/amitools/bundlevol.rb +240 -0
- data/lib/ec2/amitools/bundlevolparameters.rb +164 -0
- data/lib/ec2/amitools/crypto.rb +379 -0
- data/lib/ec2/amitools/decryptmanifest.rb +20 -0
- data/lib/ec2/amitools/defaults.rb +12 -0
- data/lib/ec2/amitools/deletebundle.rb +212 -0
- data/lib/ec2/amitools/deletebundleparameters.rb +78 -0
- data/lib/ec2/amitools/downloadbundle.rb +161 -0
- data/lib/ec2/amitools/downloadbundleparameters.rb +84 -0
- data/lib/ec2/amitools/exception.rb +86 -0
- data/lib/ec2/amitools/fileutil.rb +219 -0
- data/lib/ec2/amitools/format.rb +127 -0
- data/lib/ec2/amitools/instance-data.rb +97 -0
- data/lib/ec2/amitools/manifest_wrapper.rb +132 -0
- data/lib/ec2/amitools/manifestv20070829.rb +361 -0
- data/lib/ec2/amitools/manifestv20071010.rb +403 -0
- data/lib/ec2/amitools/manifestv3.rb +331 -0
- data/lib/ec2/amitools/mapids.rb +148 -0
- data/lib/ec2/amitools/migratebundle.rb +222 -0
- data/lib/ec2/amitools/migratebundleparameters.rb +173 -0
- data/lib/ec2/amitools/migratemanifest.rb +225 -0
- data/lib/ec2/amitools/migratemanifestparameters.rb +118 -0
- data/lib/ec2/amitools/minimalec2.rb +116 -0
- data/lib/ec2/amitools/parameter_exceptions.rb +34 -0
- data/lib/ec2/amitools/parameters_base.rb +168 -0
- data/lib/ec2/amitools/region.rb +93 -0
- data/lib/ec2/amitools/s3toolparameters.rb +183 -0
- data/lib/ec2/amitools/showversion.rb +12 -0
- data/lib/ec2/amitools/syschecks.rb +27 -0
- data/lib/ec2/amitools/tool_base.rb +224 -0
- data/lib/ec2/amitools/unbundle.rb +107 -0
- data/lib/ec2/amitools/unbundleparameters.rb +65 -0
- data/lib/ec2/amitools/uploadbundle.rb +361 -0
- data/lib/ec2/amitools/uploadbundleparameters.rb +108 -0
- data/lib/ec2/amitools/util.rb +532 -0
- data/lib/ec2/amitools/version.rb +33 -0
- data/lib/ec2/amitools/xmlbuilder.rb +237 -0
- data/lib/ec2/amitools/xmlutil.rb +55 -0
- data/lib/ec2/common/constants.rb +16 -0
- data/lib/ec2/common/curl.rb +110 -0
- data/lib/ec2/common/headers.rb +95 -0
- data/lib/ec2/common/headersv4.rb +173 -0
- data/lib/ec2/common/http.rb +333 -0
- data/lib/ec2/common/s3support.rb +231 -0
- data/lib/ec2/common/signature.rb +68 -0
- data/lib/ec2/oem/LICENSE.txt +58 -0
- data/lib/ec2/oem/open4.rb +399 -0
- data/lib/ec2/platform/base/architecture.rb +26 -0
- data/lib/ec2/platform/base/constants.rb +54 -0
- data/lib/ec2/platform/base/pipeline.rb +181 -0
- data/lib/ec2/platform/base.rb +57 -0
- data/lib/ec2/platform/current.rb +55 -0
- data/lib/ec2/platform/linux/architecture.rb +35 -0
- data/lib/ec2/platform/linux/constants.rb +23 -0
- data/lib/ec2/platform/linux/fstab.rb +99 -0
- data/lib/ec2/platform/linux/identity.rb +16 -0
- data/lib/ec2/platform/linux/image.rb +811 -0
- data/lib/ec2/platform/linux/mtab.rb +74 -0
- data/lib/ec2/platform/linux/pipeline.rb +40 -0
- data/lib/ec2/platform/linux/rsync.rb +114 -0
- data/lib/ec2/platform/linux/tar.rb +124 -0
- data/lib/ec2/platform/linux/uname.rb +50 -0
- data/lib/ec2/platform/linux.rb +83 -0
- data/lib/ec2/platform/solaris/architecture.rb +28 -0
- data/lib/ec2/platform/solaris/constants.rb +30 -0
- data/lib/ec2/platform/solaris/fstab.rb +43 -0
- data/lib/ec2/platform/solaris/identity.rb +16 -0
- data/lib/ec2/platform/solaris/image.rb +327 -0
- data/lib/ec2/platform/solaris/mtab.rb +29 -0
- data/lib/ec2/platform/solaris/pipeline.rb +40 -0
- data/lib/ec2/platform/solaris/rsync.rb +24 -0
- data/lib/ec2/platform/solaris/tar.rb +36 -0
- data/lib/ec2/platform/solaris/uname.rb +21 -0
- data/lib/ec2/platform/solaris.rb +38 -0
- data/lib/ec2/platform.rb +69 -0
- data/lib/ec2/version.rb +8 -0
- data/lib/ec2_amitools +1 -0
- data/lib/ec2_amitools.rb +7 -0
- metadata +184 -0
@@ -0,0 +1,20 @@
|
|
1
|
+
# Copyright 2008-2014 Amazon.com, Inc. or its affiliates. All Rights
|
2
|
+
# Reserved. Licensed under the Amazon Software License (the
|
3
|
+
# "License"). You may not use this file except in compliance with the
|
4
|
+
# License. A copy of the License is located at
|
5
|
+
# http://aws.amazon.com/asl or in the "license" file accompanying this
|
6
|
+
# file. This file is distributed on an "AS IS" BASIS, WITHOUT
|
7
|
+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See
|
8
|
+
# the License for the specific language governing permissions and
|
9
|
+
# limitations under the License.
|
10
|
+
|
11
|
+
require 'ec2/amitools/crypto'
|
12
|
+
|
13
|
+
USAGE = "Usage: decryptmanifest private-key-path"
|
14
|
+
|
15
|
+
if ARGV.size < 1
|
16
|
+
puts USAGE
|
17
|
+
exit 1
|
18
|
+
end
|
19
|
+
|
20
|
+
puts Crypto::decryptasym( $stdin.read, ARGV[0] )
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# Copyright 2008-2014 Amazon.com, Inc. or its affiliates. All Rights
|
2
|
+
# Reserved. Licensed under the Amazon Software License (the
|
3
|
+
# "License"). You may not use this file except in compliance with the
|
4
|
+
# License. A copy of the License is located at
|
5
|
+
# http://aws.amazon.com/asl or in the "license" file accompanying this
|
6
|
+
# file. This file is distributed on an "AS IS" BASIS, WITHOUT
|
7
|
+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See
|
8
|
+
# the License for the specific language governing permissions and
|
9
|
+
# limitations under the License.
|
10
|
+
|
11
|
+
EC2_HOME = ENV['EC2_AMITOOL_HOME'] || ENV['EC2_HOME']
|
12
|
+
EC2_X509_CERT = '#{EC2_HOME}/etc/ec2/amitools/cert-ec2.pem'
|
@@ -0,0 +1,212 @@
|
|
1
|
+
# Copyright 2008-2014 Amazon.com, Inc. or its affiliates. All Rights
|
2
|
+
# Reserved. Licensed under the Amazon Software License (the
|
3
|
+
# "License"). You may not use this file except in compliance with the
|
4
|
+
# License. A copy of the License is located at
|
5
|
+
# http://aws.amazon.com/asl or in the "license" file accompanying this
|
6
|
+
# file. This file is distributed on an "AS IS" BASIS, WITHOUT
|
7
|
+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See
|
8
|
+
# the License for the specific language governing permissions and
|
9
|
+
# limitations under the License.
|
10
|
+
|
11
|
+
require 'ec2/amitools/crypto'
|
12
|
+
require 'ec2/amitools/exception'
|
13
|
+
require 'ec2/amitools/deletebundleparameters'
|
14
|
+
require 'net/https'
|
15
|
+
require 'rexml/document'
|
16
|
+
require 'tempfile'
|
17
|
+
require 'uri'
|
18
|
+
require 'ec2/common/s3support'
|
19
|
+
require 'ec2/amitools/tool_base'
|
20
|
+
|
21
|
+
DELETE_BUNDLE_NAME = 'ec2-delete-bundle'
|
22
|
+
|
23
|
+
#------------------------------------------------------------------------------#
|
24
|
+
|
25
|
+
DELETE_BUNDLE_MANUAL=<<TEXT
|
26
|
+
#{DELETE_BUNDLE_NAME} is a command line tool to delete a bundled Amazon Image from S3 storage.
|
27
|
+
An Amazon Image may be one of the following:
|
28
|
+
- Amazon Machine Image (AMI)
|
29
|
+
- Amazon Kernel Image (AKI)
|
30
|
+
- Amazon Ramdisk Image (ARI)
|
31
|
+
|
32
|
+
#{DELETE_BUNDLE_NAME} will delete a bundled AMI specified by either its manifest file or the
|
33
|
+
prefix of the bundled AMI filenames.
|
34
|
+
|
35
|
+
#{DELETE_BUNDLE_NAME} will:
|
36
|
+
- delete the manifest and parts from the s3 bucket
|
37
|
+
- remove the bucket if and only if it is empty and you request its deletion
|
38
|
+
TEXT
|
39
|
+
|
40
|
+
#------------------------------------------------------------------------------#
|
41
|
+
|
42
|
+
RETRY_WAIT_PERIOD = 5
|
43
|
+
|
44
|
+
#------------------------------------------------------------------------------#
|
45
|
+
|
46
|
+
class DeleteFileError < AMIToolExceptions::EC2FatalError
|
47
|
+
def initialize(file, reason)
|
48
|
+
super(5,"Could not delete file '#{file}': #{reason}")
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
class BundleDeleter < AMITool
|
53
|
+
#----------------------------------------------------------------------------#
|
54
|
+
|
55
|
+
# Delete the specified file.
|
56
|
+
def delete(bucket, key, retry_delete)
|
57
|
+
retry_s3(retry_delete) do
|
58
|
+
begin
|
59
|
+
response = @s3_conn.delete(bucket, key)
|
60
|
+
return if response.success?
|
61
|
+
raise "HTTP DELETE returned #{response.code}"
|
62
|
+
rescue => e
|
63
|
+
raise TryFailed.new("Failed to delete \"#{key}\": #{e.message}")
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
#----------------------------------------------------------------------------#
|
69
|
+
|
70
|
+
# Return a list of bundle part filenames from the manifest.
|
71
|
+
def get_part_filenames(manifest)
|
72
|
+
parts = []
|
73
|
+
manifest_doc = REXML::Document.new(manifest).root
|
74
|
+
REXML::XPath.each(manifest_doc, 'image/parts/part/filename/text()') do |part|
|
75
|
+
parts << part.to_s
|
76
|
+
end
|
77
|
+
return parts
|
78
|
+
end
|
79
|
+
|
80
|
+
#------------------------------------------------------------------------------#
|
81
|
+
|
82
|
+
def uri2string(uri)
|
83
|
+
s = "#{uri.scheme}://#{uri.host}:#{uri.port}#{uri.path}"
|
84
|
+
# Remove the trailing '/'.
|
85
|
+
return (s[-1..-1] == "/" ? s[0..-2] : s)
|
86
|
+
end
|
87
|
+
|
88
|
+
#------------------------------------------------------------------------------#
|
89
|
+
|
90
|
+
def get_file_list_from_s3(bucket, keyprefix, prefix)
|
91
|
+
s3prefix = keyprefix+prefix
|
92
|
+
files_to_delete = []
|
93
|
+
response = @s3_conn.list_bucket(bucket, s3prefix)
|
94
|
+
unless response.success?
|
95
|
+
raise "unable to list contents of bucket #{bucket}: HTTP #{response.code} response: #{response.body}"
|
96
|
+
end
|
97
|
+
REXML::XPath.each(REXML::Document.new(response.body), "//Key/text()") do |entry|
|
98
|
+
entry = entry.to_s
|
99
|
+
if entry[0,s3prefix.length] == s3prefix
|
100
|
+
test_str = entry[(s3prefix.length)..-1]
|
101
|
+
if (test_str =~ /^\.part\.[0-9]+$/ or
|
102
|
+
test_str =~ /^\.manifest(\.xml)?$/)
|
103
|
+
files_to_delete << entry[(keyprefix.length)..-1]
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
files_to_delete
|
108
|
+
end
|
109
|
+
|
110
|
+
#------------------------------------------------------------------------------#
|
111
|
+
|
112
|
+
def make_s3_connection(s3_url, user, pass, method, sigv, region)
|
113
|
+
EC2::Common::S3Support.new(s3_url, user, pass, method, @debug, sigv, region)
|
114
|
+
end
|
115
|
+
|
116
|
+
#------------------------------------------------------------------------------#
|
117
|
+
|
118
|
+
def delete_bundle(url, bucket, keyprefix, user, pass, manifest, prefix, yes, clear, retry_stuff, sigv, region)
|
119
|
+
begin
|
120
|
+
# Get the S3 URL.
|
121
|
+
s3_uri = URI.parse(url)
|
122
|
+
s3_url = uri2string(s3_uri)
|
123
|
+
retry_delete = retry_stuff
|
124
|
+
v2_bucket = EC2::Common::S3Support::bucket_name_s3_v2_safe?(bucket)
|
125
|
+
@s3_conn = make_s3_connection(s3_url, user, pass, (v2_bucket ? nil : :path), sigv, region)
|
126
|
+
|
127
|
+
files_to_delete = []
|
128
|
+
|
129
|
+
if manifest
|
130
|
+
# Get list of files to delete from the AMI manifest.
|
131
|
+
xml = String.new
|
132
|
+
manifest_path = manifest
|
133
|
+
File.open(manifest_path) { |f| xml << f.read }
|
134
|
+
files_to_delete << File::basename(manifest)
|
135
|
+
get_part_filenames( xml ).each do |part_info|
|
136
|
+
files_to_delete << part_info
|
137
|
+
end
|
138
|
+
else
|
139
|
+
files_to_delete = get_file_list_from_s3(bucket, keyprefix, prefix)
|
140
|
+
end
|
141
|
+
|
142
|
+
if files_to_delete.empty?
|
143
|
+
$stdout.puts "No files to delete."
|
144
|
+
else
|
145
|
+
$stdout.puts "Deleting files:"
|
146
|
+
files_to_delete.each { |file| $stdout.puts(" - #{file}") }
|
147
|
+
continue = yes
|
148
|
+
unless continue
|
149
|
+
begin
|
150
|
+
$stdout.print "Continue [y/N]: "
|
151
|
+
$stdout.flush
|
152
|
+
Timeout::timeout(PROMPT_TIMEOUT) do
|
153
|
+
continue = gets.strip =~ /^y/i
|
154
|
+
end
|
155
|
+
rescue Timeout::Error
|
156
|
+
$stdout.puts "\nNo response given, skipping the files."
|
157
|
+
continue = false
|
158
|
+
end
|
159
|
+
end
|
160
|
+
if continue
|
161
|
+
files_to_delete.each do |file|
|
162
|
+
delete(bucket, keyprefix+file, retry_delete)
|
163
|
+
$stdout.puts "Deleted #{file}"
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
if clear
|
169
|
+
$stdout.puts "Attempting to delete bucket #{bucket}..."
|
170
|
+
@s3_conn.delete(bucket)
|
171
|
+
end
|
172
|
+
rescue EC2::Common::HTTP::Error => e
|
173
|
+
$stderr.puts e.backtrace if @debug
|
174
|
+
raise S3Error.new(e.message)
|
175
|
+
end
|
176
|
+
$stdout.puts "#{DELETE_BUNDLE_NAME} complete."
|
177
|
+
end
|
178
|
+
|
179
|
+
#------------------------------------------------------------------------------#
|
180
|
+
# Overrides
|
181
|
+
#------------------------------------------------------------------------------#
|
182
|
+
|
183
|
+
def get_manual()
|
184
|
+
DELETE_BUNDLE_MANUAL
|
185
|
+
end
|
186
|
+
|
187
|
+
def get_name()
|
188
|
+
DELETE_BUNDLE_NAME
|
189
|
+
end
|
190
|
+
|
191
|
+
def main(p)
|
192
|
+
delete_bundle(p.url,
|
193
|
+
p.bucket,
|
194
|
+
p.keyprefix,
|
195
|
+
p.user,
|
196
|
+
p.pass,
|
197
|
+
p.manifest,
|
198
|
+
p.prefix,
|
199
|
+
p.yes,
|
200
|
+
p.clear,
|
201
|
+
p.retry,
|
202
|
+
p.sigv,
|
203
|
+
p.region)
|
204
|
+
end
|
205
|
+
|
206
|
+
end
|
207
|
+
|
208
|
+
#------------------------------------------------------------------------------#
|
209
|
+
# Script entry point. Execute only if this file is being executed.
|
210
|
+
if __FILE__ == $0 || $0.match(/bin\/ec2-delete-bundle/)
|
211
|
+
BundleDeleter.new().run(DeleteBundleParameters)
|
212
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# Copyright 2008-2014 Amazon.com, Inc. or its affiliates. All Rights
|
2
|
+
# Reserved. Licensed under the Amazon Software License (the
|
3
|
+
# "License"). You may not use this file except in compliance with the
|
4
|
+
# License. A copy of the License is located at
|
5
|
+
# http://aws.amazon.com/asl or in the "license" file accompanying this
|
6
|
+
# file. This file is distributed on an "AS IS" BASIS, WITHOUT
|
7
|
+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See
|
8
|
+
# the License for the specific language governing permissions and
|
9
|
+
# limitations under the License.
|
10
|
+
|
11
|
+
require 'ec2/amitools/s3toolparameters'
|
12
|
+
|
13
|
+
#------------------------------------------------------------------------------#
|
14
|
+
|
15
|
+
class DeleteBundleParameters < S3ToolParameters
|
16
|
+
|
17
|
+
MANIFEST_DESCRIPTION = "The path to the unencrypted manifest file."
|
18
|
+
PREFIX_DESCRIPTION = "The bundled AMI part filename prefix."
|
19
|
+
RETRY_DESCRIPTION = "Automatically retry failed deletes. Use with caution."
|
20
|
+
YES_DESCRIPTION = "Automatically answer 'y' without asking."
|
21
|
+
CLEAR_DESCRIPTION = "Delete the bucket if empty. Not done by default."
|
22
|
+
|
23
|
+
attr_accessor :manifest,
|
24
|
+
:prefix,
|
25
|
+
:retry,
|
26
|
+
:yes,
|
27
|
+
:clear
|
28
|
+
|
29
|
+
#----------------------------------------------------------------------------#
|
30
|
+
|
31
|
+
def mandatory_params()
|
32
|
+
super()
|
33
|
+
end
|
34
|
+
|
35
|
+
#----------------------------------------------------------------------------#
|
36
|
+
|
37
|
+
def optional_params()
|
38
|
+
super()
|
39
|
+
|
40
|
+
on('-m', '--manifest PATH', String, MANIFEST_DESCRIPTION) do |manifest|
|
41
|
+
assert_file_exists(manifest, '--manifest')
|
42
|
+
@manifest = manifest
|
43
|
+
end
|
44
|
+
|
45
|
+
on('-p', '--prefix PREFIX', String, PREFIX_DESCRIPTION) do |prefix|
|
46
|
+
assert_good_key(prefix, '--prefix')
|
47
|
+
@prefix = prefix
|
48
|
+
end
|
49
|
+
|
50
|
+
on('--clear', CLEAR_DESCRIPTION) do
|
51
|
+
@clear = true
|
52
|
+
end
|
53
|
+
|
54
|
+
on('--retry', RETRY_DESCRIPTION) do
|
55
|
+
@retry = true
|
56
|
+
end
|
57
|
+
|
58
|
+
on('-y', '--yes', YES_DESCRIPTION) do
|
59
|
+
@yes = true
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
#----------------------------------------------------------------------------#
|
64
|
+
|
65
|
+
def validate_params()
|
66
|
+
super()
|
67
|
+
raise MissingMandatory.new('--manifest or --prefix') unless @manifest or @prefix
|
68
|
+
raise InvalidCombination.new('--prefix', '--manifest') if (@prefix and @manifest)
|
69
|
+
end
|
70
|
+
|
71
|
+
#----------------------------------------------------------------------------#
|
72
|
+
|
73
|
+
def set_defaults()
|
74
|
+
super()
|
75
|
+
@clear ||= false
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
@@ -0,0 +1,161 @@
|
|
1
|
+
# Copyright 2008-2014 Amazon.com, Inc. or its affiliates. All Rights
|
2
|
+
# Reserved. Licensed under the Amazon Software License (the
|
3
|
+
# "License"). You may not use this file except in compliance with the
|
4
|
+
# License. A copy of the License is located at
|
5
|
+
# http://aws.amazon.com/asl or in the "license" file accompanying this
|
6
|
+
# file. This file is distributed on an "AS IS" BASIS, WITHOUT
|
7
|
+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See
|
8
|
+
# the License for the specific language governing permissions and
|
9
|
+
# limitations under the License.
|
10
|
+
|
11
|
+
require 'ec2/amitools/crypto'
|
12
|
+
require 'ec2/common/s3support'
|
13
|
+
require 'ec2/amitools/downloadbundleparameters'
|
14
|
+
require 'ec2/amitools/exception'
|
15
|
+
require 'ec2/amitools/manifestv20071010'
|
16
|
+
require 'getoptlong'
|
17
|
+
require 'net/http'
|
18
|
+
require 'rexml/document'
|
19
|
+
require 'ec2/amitools/tool_base'
|
20
|
+
|
21
|
+
# Download AMI downloads the specified AMI from S3.
|
22
|
+
|
23
|
+
#------------------------------------------------------------------------------#
|
24
|
+
|
25
|
+
DOWNLOAD_BUNDLE_NAME = 'ec2-download-bundle'
|
26
|
+
DOWNLOAD_BUNDLE_MANUAL =<<TEXT
|
27
|
+
#{DOWNLOAD_BUNDLE_NAME} is a command line tool to download a bundled Amazon Image from
|
28
|
+
S3 storage. An Amazon Image may be one of the following:
|
29
|
+
- Amazon Machine Image (AMI)
|
30
|
+
- Amazon Kernel Image (AKI)
|
31
|
+
- Amazon Ramdisk Image (ARI)
|
32
|
+
|
33
|
+
#{DOWNLOAD_BUNDLE_NAME} downloads and decrypts the manifest, then fetches all
|
34
|
+
the parts referenced in the manifest.
|
35
|
+
TEXT
|
36
|
+
|
37
|
+
class BundleDownloader < AMITool
|
38
|
+
|
39
|
+
def download_manifest(s3_conn, bucket, manifest_name, manifest_path, privatekey, retry_download=false)
|
40
|
+
$stdout.puts "Downloading manifest #{manifest_name} from #{bucket} to #{manifest_path} ..."
|
41
|
+
download_file(s3_conn, bucket, manifest_name, manifest_path, retry_download)
|
42
|
+
encrypted_manifest = File::open(manifest_path) { |f| f.read() }
|
43
|
+
plaintext_manifest = nil
|
44
|
+
if (encrypted_manifest !~ /^\s*<\?/)
|
45
|
+
$stdout.puts "Decrypting manifest ..."
|
46
|
+
plaintext_manifest = Crypto::decryptasym(encrypted_manifest, privatekey)
|
47
|
+
File::open(manifest_path+'.plaintext', 'w') { |f| f.write(plaintext_manifest) }
|
48
|
+
else
|
49
|
+
plaintext_manifest = encrypted_manifest
|
50
|
+
end
|
51
|
+
plaintext_manifest
|
52
|
+
end
|
53
|
+
|
54
|
+
#----------------------------------------------------------------------------#
|
55
|
+
|
56
|
+
def download_part(s3_conn, bucket, part, part_path, retry_download=false)
|
57
|
+
$stdout.puts "Downloading part #{part} to #{part_path} ..."
|
58
|
+
download_file(s3_conn, bucket, part, part_path, retry_download)
|
59
|
+
end
|
60
|
+
|
61
|
+
#----------------------------------------------------------------------------#
|
62
|
+
|
63
|
+
def download_file(s3_conn, bucket, file, file_path, retry_download=false)
|
64
|
+
retry_s3(retry_download) do
|
65
|
+
begin
|
66
|
+
s3_conn.get(bucket, file, file_path)
|
67
|
+
return
|
68
|
+
rescue => e
|
69
|
+
raise TryFailed.new("Failed to download \"#{file}\": #{e.message}")
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
#----------------------------------------------------------------------------#
|
75
|
+
|
76
|
+
def get_part_filenames(manifest_xml)
|
77
|
+
manifest = ManifestV20071010.new(manifest_xml)
|
78
|
+
manifest.parts.collect { |part| part.filename }.sort
|
79
|
+
end
|
80
|
+
|
81
|
+
#----------------------------------------------------------------------------#
|
82
|
+
|
83
|
+
def uri2string( uri )
|
84
|
+
s = "#{uri.scheme}://#{uri.host}:#{uri.port}#{uri.path}"
|
85
|
+
# Remove the trailing '/'.
|
86
|
+
return ( s[-1..-1] == "/" ? s[0..-2] : s )
|
87
|
+
end
|
88
|
+
|
89
|
+
#----------------------------------------------------------------------------#
|
90
|
+
|
91
|
+
def make_s3_connection(s3_url, user, pass, bucket, sigv, region)
|
92
|
+
s3_uri = URI.parse(s3_url)
|
93
|
+
s3_url = uri2string(s3_uri)
|
94
|
+
v2_bucket = EC2::Common::S3Support::bucket_name_s3_v2_safe?(bucket)
|
95
|
+
EC2::Common::S3Support.new(s3_url, user, pass, (v2_bucket ? nil : :path), @debug, sigv, region)
|
96
|
+
end
|
97
|
+
|
98
|
+
#----------------------------------------------------------------------------#
|
99
|
+
|
100
|
+
# Main method.
|
101
|
+
def download_bundle(url,
|
102
|
+
user,
|
103
|
+
pass,
|
104
|
+
bucket,
|
105
|
+
keyprefix,
|
106
|
+
directory,
|
107
|
+
manifest,
|
108
|
+
privatekey,
|
109
|
+
retry_stuff,
|
110
|
+
sigv,
|
111
|
+
region)
|
112
|
+
begin
|
113
|
+
s3_conn = make_s3_connection(url, user, pass, bucket, sigv, region)
|
114
|
+
# Download and decrypt manifest.
|
115
|
+
manifest_path = File.join(directory, manifest)
|
116
|
+
manifest_xml = download_manifest(s3_conn, bucket, keyprefix+manifest, manifest_path, privatekey, retry_stuff)
|
117
|
+
|
118
|
+
# Download AMI parts.
|
119
|
+
get_part_filenames(manifest_xml).each do |filename|
|
120
|
+
download_part(s3_conn, bucket, keyprefix+filename, File::join(directory, filename), retry_stuff)
|
121
|
+
$stdout.puts "Downloaded #{filename} from #{bucket}"
|
122
|
+
end
|
123
|
+
rescue EC2::Common::HTTP::Error => e
|
124
|
+
$stderr.puts e.backtrace if @debug
|
125
|
+
raise S3Error.new(e.message)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
#------------------------------------------------------------------------------#
|
130
|
+
# Overrides
|
131
|
+
#------------------------------------------------------------------------------#
|
132
|
+
|
133
|
+
def get_manual()
|
134
|
+
DOWNLOAD_BUNDLE_MANUAL
|
135
|
+
end
|
136
|
+
|
137
|
+
def get_name()
|
138
|
+
DOWNLOAD_BUNDLE_NAME
|
139
|
+
end
|
140
|
+
|
141
|
+
def main(p)
|
142
|
+
download_bundle(p.url,
|
143
|
+
p.user,
|
144
|
+
p.pass,
|
145
|
+
p.bucket,
|
146
|
+
p.keyprefix,
|
147
|
+
p.directory,
|
148
|
+
p.manifest,
|
149
|
+
p.privatekey,
|
150
|
+
p.retry,
|
151
|
+
p.sigv,
|
152
|
+
p.region)
|
153
|
+
end
|
154
|
+
|
155
|
+
end
|
156
|
+
|
157
|
+
#------------------------------------------------------------------------------#
|
158
|
+
# Script entry point. Execute only if this file is being executed.
|
159
|
+
if __FILE__ == $0 || $0.match(/bin\/ec2-download-bundle/)
|
160
|
+
BundleDownloader.new().run(DownloadBundleParameters)
|
161
|
+
end
|