ec2_amitools 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +54 -0
  3. data/bin/console +14 -0
  4. data/bin/ec2-ami-tools-version +6 -0
  5. data/bin/ec2-bundle-image +6 -0
  6. data/bin/ec2-bundle-vol +6 -0
  7. data/bin/ec2-delete-bundle +6 -0
  8. data/bin/ec2-download-bundle +6 -0
  9. data/bin/ec2-migrate-bundle +6 -0
  10. data/bin/ec2-migrate-manifest +6 -0
  11. data/bin/ec2-unbundle +6 -0
  12. data/bin/ec2-upload-bundle +6 -0
  13. data/bin/setup +8 -0
  14. data/etc/ec2/amitools/cert-ec2-cn-north-1.pem +28 -0
  15. data/etc/ec2/amitools/cert-ec2-gov.pem +17 -0
  16. data/etc/ec2/amitools/cert-ec2.pem +23 -0
  17. data/etc/ec2/amitools/mappings.csv +9 -0
  18. data/lib/ec2/amitools/bundle.rb +251 -0
  19. data/lib/ec2/amitools/bundle_base.rb +58 -0
  20. data/lib/ec2/amitools/bundleimage.rb +94 -0
  21. data/lib/ec2/amitools/bundleimageparameters.rb +42 -0
  22. data/lib/ec2/amitools/bundlemachineparameters.rb +60 -0
  23. data/lib/ec2/amitools/bundleparameters.rb +120 -0
  24. data/lib/ec2/amitools/bundlevol.rb +240 -0
  25. data/lib/ec2/amitools/bundlevolparameters.rb +164 -0
  26. data/lib/ec2/amitools/crypto.rb +379 -0
  27. data/lib/ec2/amitools/decryptmanifest.rb +20 -0
  28. data/lib/ec2/amitools/defaults.rb +12 -0
  29. data/lib/ec2/amitools/deletebundle.rb +212 -0
  30. data/lib/ec2/amitools/deletebundleparameters.rb +78 -0
  31. data/lib/ec2/amitools/downloadbundle.rb +161 -0
  32. data/lib/ec2/amitools/downloadbundleparameters.rb +84 -0
  33. data/lib/ec2/amitools/exception.rb +86 -0
  34. data/lib/ec2/amitools/fileutil.rb +219 -0
  35. data/lib/ec2/amitools/format.rb +127 -0
  36. data/lib/ec2/amitools/instance-data.rb +97 -0
  37. data/lib/ec2/amitools/manifest_wrapper.rb +132 -0
  38. data/lib/ec2/amitools/manifestv20070829.rb +361 -0
  39. data/lib/ec2/amitools/manifestv20071010.rb +403 -0
  40. data/lib/ec2/amitools/manifestv3.rb +331 -0
  41. data/lib/ec2/amitools/mapids.rb +148 -0
  42. data/lib/ec2/amitools/migratebundle.rb +222 -0
  43. data/lib/ec2/amitools/migratebundleparameters.rb +173 -0
  44. data/lib/ec2/amitools/migratemanifest.rb +225 -0
  45. data/lib/ec2/amitools/migratemanifestparameters.rb +118 -0
  46. data/lib/ec2/amitools/minimalec2.rb +116 -0
  47. data/lib/ec2/amitools/parameter_exceptions.rb +34 -0
  48. data/lib/ec2/amitools/parameters_base.rb +168 -0
  49. data/lib/ec2/amitools/region.rb +93 -0
  50. data/lib/ec2/amitools/s3toolparameters.rb +183 -0
  51. data/lib/ec2/amitools/showversion.rb +12 -0
  52. data/lib/ec2/amitools/syschecks.rb +27 -0
  53. data/lib/ec2/amitools/tool_base.rb +224 -0
  54. data/lib/ec2/amitools/unbundle.rb +107 -0
  55. data/lib/ec2/amitools/unbundleparameters.rb +65 -0
  56. data/lib/ec2/amitools/uploadbundle.rb +361 -0
  57. data/lib/ec2/amitools/uploadbundleparameters.rb +108 -0
  58. data/lib/ec2/amitools/util.rb +532 -0
  59. data/lib/ec2/amitools/version.rb +33 -0
  60. data/lib/ec2/amitools/xmlbuilder.rb +237 -0
  61. data/lib/ec2/amitools/xmlutil.rb +55 -0
  62. data/lib/ec2/common/constants.rb +16 -0
  63. data/lib/ec2/common/curl.rb +110 -0
  64. data/lib/ec2/common/headers.rb +95 -0
  65. data/lib/ec2/common/headersv4.rb +173 -0
  66. data/lib/ec2/common/http.rb +333 -0
  67. data/lib/ec2/common/s3support.rb +231 -0
  68. data/lib/ec2/common/signature.rb +68 -0
  69. data/lib/ec2/oem/LICENSE.txt +58 -0
  70. data/lib/ec2/oem/open4.rb +399 -0
  71. data/lib/ec2/platform/base/architecture.rb +26 -0
  72. data/lib/ec2/platform/base/constants.rb +54 -0
  73. data/lib/ec2/platform/base/pipeline.rb +181 -0
  74. data/lib/ec2/platform/base.rb +57 -0
  75. data/lib/ec2/platform/current.rb +55 -0
  76. data/lib/ec2/platform/linux/architecture.rb +35 -0
  77. data/lib/ec2/platform/linux/constants.rb +23 -0
  78. data/lib/ec2/platform/linux/fstab.rb +99 -0
  79. data/lib/ec2/platform/linux/identity.rb +16 -0
  80. data/lib/ec2/platform/linux/image.rb +811 -0
  81. data/lib/ec2/platform/linux/mtab.rb +74 -0
  82. data/lib/ec2/platform/linux/pipeline.rb +40 -0
  83. data/lib/ec2/platform/linux/rsync.rb +114 -0
  84. data/lib/ec2/platform/linux/tar.rb +124 -0
  85. data/lib/ec2/platform/linux/uname.rb +50 -0
  86. data/lib/ec2/platform/linux.rb +83 -0
  87. data/lib/ec2/platform/solaris/architecture.rb +28 -0
  88. data/lib/ec2/platform/solaris/constants.rb +30 -0
  89. data/lib/ec2/platform/solaris/fstab.rb +43 -0
  90. data/lib/ec2/platform/solaris/identity.rb +16 -0
  91. data/lib/ec2/platform/solaris/image.rb +327 -0
  92. data/lib/ec2/platform/solaris/mtab.rb +29 -0
  93. data/lib/ec2/platform/solaris/pipeline.rb +40 -0
  94. data/lib/ec2/platform/solaris/rsync.rb +24 -0
  95. data/lib/ec2/platform/solaris/tar.rb +36 -0
  96. data/lib/ec2/platform/solaris/uname.rb +21 -0
  97. data/lib/ec2/platform/solaris.rb +38 -0
  98. data/lib/ec2/platform.rb +69 -0
  99. data/lib/ec2/version.rb +8 -0
  100. data/lib/ec2_amitools +1 -0
  101. data/lib/ec2_amitools.rb +7 -0
  102. 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