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.
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,148 @@
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/minimalec2'
12
+
13
+ class KernelMappings
14
+ ENDPOINT = "http://ec2.amazonaws.com"
15
+
16
+ class MappingError < StandardError; end
17
+
18
+ attr_reader :source_image_info
19
+ attr_reader :target_image_info
20
+
21
+ #----------------------------------------------------------------------------#
22
+
23
+ def get_ec2_client(akid, secretkey, endpoint=nil)
24
+ EC2::EC2Client.new(akid, secretkey, endpoint)
25
+ end
26
+
27
+ #----------------------------------------------------------------------------#
28
+
29
+ def add_endpoint_from_env(endpoints)
30
+ str = ENV['AMITOOLS_EC2_REGION_ENDPOINT']
31
+ if not str
32
+ return
33
+ end
34
+
35
+ components = str.split('@').collect{|s| s.strip()}
36
+ if components.size != 2
37
+ return
38
+ end
39
+
40
+ endpoints[components[0]] = components[1]
41
+ end
42
+
43
+ def get_endpoints(akid, secretkey, endpoint=nil)
44
+ endpoint ||= ENDPOINT
45
+ endpoints = {}
46
+ ec2conn = get_ec2_client(akid, secretkey, endpoint)
47
+ resp_doc = ec2conn.describe_regions()
48
+ REXML::XPath.each(resp_doc.root, '/DescribeRegionsResponse/regionInfo/item') do |region|
49
+ region_name = REXML::XPath.first(region, 'regionName').text
50
+ region_url = REXML::XPath.first(region, 'regionEndpoint').text
51
+ region_url = 'https://'+region_url unless region_url =~ %r{^https?://}
52
+ endpoints[region_name] = region_url
53
+ end
54
+ add_endpoint_from_env(endpoints)
55
+ endpoints
56
+ end
57
+
58
+ #----------------------------------------------------------------------------#
59
+
60
+ def create_ec2_connections(akid, secretkey, endpoint=nil)
61
+ @ec2conn = {}
62
+ @endpoints = get_endpoints(akid, secretkey, endpoint)
63
+ @endpoints.each do |region, endpoint|
64
+ @ec2conn[region] = get_ec2_client(akid, secretkey, endpoint)
65
+ end
66
+ end
67
+
68
+ #----------------------------------------------------------------------------#
69
+
70
+ def get_source_images_info()
71
+ @ec2conn.each do |region, connection|
72
+ $stderr.puts "Getting source data from #{region} #{@source_images.inspect}..." if @verbose
73
+ resp_doc = connection.describe_images(@source_images)
74
+ @source_images_info = parse_imageset(resp_doc)
75
+ $stderr.puts "Found #{@source_images_info.size} images in #{region}." if @verbose
76
+ # We assume all the images we're trying to map are in the same region.
77
+ return if @source_images_info.size > 0
78
+ end
79
+ end
80
+
81
+ #----------------------------------------------------------------------------#
82
+
83
+ def get_target_candidates()
84
+ owners = @source_images_info.map { |ii| ii['imageOwnerId'] }
85
+ $stderr.puts "Getting target data from #{region} #{owners.inspect}..." if @verbose
86
+ resp_doc = @ec2conn[@target_region].describe_images([], :ownerIds => owners)
87
+ @target_images_info = parse_imageset(resp_doc)
88
+ $stderr.puts "Found #{@target_images_info.size} images in #{region}." if @verbose
89
+ end
90
+
91
+ #----------------------------------------------------------------------------#
92
+
93
+ def parse_imageset(resp_doc)
94
+ images_info = []
95
+ resp_doc.each_element('DescribeImagesResponse/imagesSet/item') do |image|
96
+ image_data = {}
97
+ image.each_element() { |elem| image_data[elem.name] = elem.text }
98
+ images_info << image_data
99
+ end
100
+ images_info
101
+ end
102
+
103
+ #----------------------------------------------------------------------------#
104
+
105
+ def initialize(akid, secretkey, source_images, target_region, endpoint=nil)
106
+ @target_region = target_region
107
+ @source_images = source_images
108
+ create_ec2_connections(akid, secretkey, endpoint)
109
+ unless @ec2conn.has_key?(target_region)
110
+ raise MappingError.new("Invalid region: #{target_region}")
111
+ end
112
+ end
113
+
114
+ #----------------------------------------------------------------------------#
115
+
116
+ def matchable_image(image)
117
+ summary = {}
118
+ ['imageOwnerId', 'imageType'].each { |key| summary[key] = image[key] }
119
+ summary[:s3key] = image['imageLocation'].sub(%r{^/*[^/]+/},'')
120
+ summary
121
+ end
122
+
123
+ #----------------------------------------------------------------------------#
124
+
125
+ def find_missing_targets(targets)
126
+ @target_images_info.each { |ii| targets.delete(ii['imageId']) } unless @target_images_info.nil?
127
+ return nil if targets.empty?
128
+ lookups = parse_imageset(@ec2conn[@target_region].describe_images(targets))
129
+ lookups.each { |ii| targets.delete(ii['imageId']) }
130
+ return nil if targets.empty?
131
+ targets
132
+ end
133
+
134
+ #----------------------------------------------------------------------------#
135
+
136
+ def [](identifier)
137
+ if @target_images_info.nil?
138
+ get_source_images_info()
139
+ get_target_candidates()
140
+ end
141
+ source_info = @source_images_info.find { |ii| ii['imageId'] == identifier }
142
+ raise MappingError.new("'#{identifier}' not found.") if source_info.nil?
143
+ source_match = matchable_image(source_info)
144
+ target_info = @target_images_info.find { |ii| source_match == matchable_image(ii) }
145
+ raise MappingError.new("Mapping for '#{identifier}' not found.") if target_info.nil?
146
+ target_info['imageId']
147
+ end
148
+ end
@@ -0,0 +1,222 @@
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/common/s3support'
12
+ require 'ec2/amitools/region'
13
+ require 'ec2/amitools/migratebundleparameters'
14
+ require 'ec2/amitools/migratemanifest'
15
+ require 'ec2/amitools/downloadbundle'
16
+ require 'ec2/amitools/uploadbundle'
17
+ require 'fileutils'
18
+ require 'ec2/amitools/tool_base'
19
+
20
+ MIGRATE_BUNDLE_NAME = 'ec2-migrate-bundle'
21
+
22
+ #------------------------------------------------------------------------------#
23
+
24
+ MIGRATE_BUNDLE_MANUAL =<<TEXT
25
+ #{MIGRATE_BUNDLE_NAME} is a command line tool to assist with migrating AMIs to new regions.
26
+
27
+ *** This tool is deprecated. ***
28
+ Please consider using ec2-migrate-image from the EC2 API tools.
29
+ You can download the EC2 API tools here:
30
+ http://aws.amazon.com/developertools/351
31
+
32
+ #{MIGRATE_BUNDLE_NAME} will:
33
+ - download the manifest of the specified AMI
34
+ - attempt to automatically find replacement kernels and ramdisks
35
+ - optionally replace kernels and ramdisks with user-specified replacements
36
+ - copy AMI into new bucket
37
+ - upload new migrated manifest into new bucket
38
+
39
+ This tool will not register the AMI in the new region.
40
+
41
+ TEXT
42
+
43
+ class BundleMigrator < AMITool
44
+
45
+ def with_temp_dir(manifest_name)
46
+ # Set up temporary dir
47
+ tempdir = File::join(Dir::tmpdir, "ami-migration-#{manifest_name}")
48
+ if File::exists?(tempdir)
49
+ raise EC2FatalError.new(2, "Temporary directory '#{tempdir}' already exists. Please delete or rename it and try again.")
50
+ end
51
+ Dir::mkdir(tempdir)
52
+
53
+ # Let the caller use it
54
+ begin
55
+ result = yield tempdir
56
+ rescue Exception => e
57
+ # Nuke it
58
+ FileUtils::rm_rf(tempdir)
59
+ raise e
60
+ end
61
+ # Nuke it
62
+ FileUtils::rm_rf(tempdir)
63
+ result
64
+ end
65
+
66
+ #------------------------------------------------------------------------------#
67
+
68
+ def uri2string(uri)
69
+ s = "#{uri.scheme}://#{uri.host}:#{uri.port}#{uri.path}"
70
+ # Remove the trailing '/'.
71
+ return (s[-1..-1] == "/" ? s[0..-2] : s)
72
+ end
73
+
74
+ #------------------------------------------------------------------------------#
75
+
76
+ def make_s3_connection(s3_url, user, pass, bucket)
77
+ s3_uri = URI.parse(s3_url)
78
+ s3_url = uri2string(s3_uri)
79
+ v2_bucket = EC2::Common::S3Support::bucket_name_s3_v2_safe?(bucket)
80
+ EC2::Common::S3Support.new(s3_url, user, pass, (v2_bucket ? nil : :path))
81
+ end
82
+
83
+ #------------------------------------------------------------------------------#
84
+
85
+ def download_manifest(s3_conn, bucket, manifest_name, manifest_path, user_pk_path, retry_stuff)
86
+ BundleDownloader.new().download_manifest(s3_conn,
87
+ bucket,
88
+ manifest_name,
89
+ manifest_path,
90
+ user_pk_path,
91
+ retry_stuff)
92
+ end
93
+
94
+ #------------------------------------------------------------------------------#
95
+
96
+ def get_part_filenames(manifest_path, user_cert_path)
97
+ manifest = ManifestMigrator.new().get_manifest(manifest_path, user_cert_path)
98
+ manifest.parts.collect { |part| part.filename }.sort
99
+ end
100
+
101
+ #------------------------------------------------------------------------------#
102
+
103
+ def copy_part(s3_conn, bucket, keyprefix, dest_bucket, dest_keyprefix, part, acl, retry_copy)
104
+ source = "/#{bucket}/#{keyprefix}#{part}"
105
+ retry_s3(retry_copy) do
106
+ begin
107
+ s3_conn.copy(dest_bucket, dest_keyprefix+part, source, {"x-amz-acl"=>acl})
108
+ return
109
+ rescue => e
110
+ raise TryFailed.new("Failed to copy \"#{part}\": #{e.message}")
111
+ end
112
+ end
113
+ end
114
+
115
+ #------------------------------------------------------------------------------#
116
+
117
+ def upload_manifest(s3_conn, key, manifest_path, bucket, tempdir, acl, retry_stuff)
118
+ BundleUploader.new().upload(s3_conn, bucket, key, manifest_path, acl, retry_stuff)
119
+ end
120
+
121
+ #------------------------------------------------------------------------------#
122
+
123
+ def migrate_bundle(s3_url,
124
+ bucket,
125
+ keyprefix,
126
+ dest_bucket,
127
+ dest_keyprefix,
128
+ manifest_name,
129
+ user_pk_path,
130
+ user_cert_path,
131
+ user,
132
+ pass,
133
+ location,
134
+ kernel_id=nil,
135
+ ramdisk_id=nil,
136
+ acl='aws-exec-read',
137
+ retry_stuff=nil,
138
+ use_mapping=true,
139
+ region=nil)
140
+
141
+ src_s3_conn = make_s3_connection(s3_url, user, pass, bucket)
142
+ dest_s3_conn = make_s3_connection(s3_url, user, pass, dest_bucket)
143
+
144
+ # Locate destination bucket and create it if necessary.
145
+ bu = BundleUploader.new()
146
+ bu.check_bucket_name(dest_bucket)
147
+ bucket_location = bu.get_bucket_location(dest_s3_conn, dest_bucket)
148
+ bu.create_bucket(dest_s3_conn, dest_bucket, bucket_location, location, retry_stuff)
149
+
150
+ # Region/location hack:
151
+ if region.nil?
152
+ location ||= bucket_location
153
+ region = AwsRegion.guess_region_from_s3_bucket(location)
154
+ puts "Region not provided, guessing from S3 location: #{region}"
155
+ end
156
+
157
+ with_temp_dir(manifest_name) do |tempdir|
158
+ manifest_path = File::join(tempdir, "temp-migration.manifest.xml")
159
+ download_manifest(src_s3_conn, bucket, keyprefix+manifest_name, manifest_path, user_pk_path, retry_stuff)
160
+
161
+ ManifestMigrator.new().migrate_manifest(manifest_path,
162
+ user_pk_path,
163
+ user_cert_path,
164
+ user,
165
+ pass,
166
+ use_mapping,
167
+ kernel_id,
168
+ ramdisk_id,
169
+ region,
170
+ true)
171
+
172
+ get_part_filenames(manifest_path, user_cert_path).each do |part|
173
+ $stdout.puts("Copying '#{part}'...")
174
+ copy_part(dest_s3_conn, bucket, keyprefix, dest_bucket, dest_keyprefix, part, acl, retry_stuff)
175
+ end
176
+ upload_manifest(dest_s3_conn, dest_keyprefix+manifest_name, manifest_path, dest_bucket, tempdir, acl, retry_stuff)
177
+ end
178
+ end
179
+
180
+ #------------------------------------------------------------------------------#
181
+ # Overrides
182
+ #------------------------------------------------------------------------------#
183
+
184
+ def get_manual()
185
+ MIGRATE_BUNDLE_MANUAL
186
+ end
187
+
188
+ def get_name()
189
+ MIGRATE_BUNDLE_NAME
190
+ end
191
+
192
+ def main(p)
193
+ migrate_bundle(p.s3_url,
194
+ p.bucket,
195
+ p.keyprefix,
196
+ p.dest_bucket,
197
+ p.dest_keyprefix,
198
+ p.manifest_name,
199
+ p.user_pk_path,
200
+ p.user_cert_path,
201
+ p.user,
202
+ p.pass,
203
+ p.location,
204
+ p.kernel_id,
205
+ p.ramdisk_id,
206
+ p.acl,
207
+ p.retry,
208
+ p.use_mapping,
209
+ p.region)
210
+
211
+ $stdout.puts("\nYour new bundle is in S3 at the following location:")
212
+ $stdout.puts("#{p.dest_bucket}/#{p.dest_keyprefix}#{p.manifest_name}")
213
+ $stdout.puts("Please register it using your favorite EC2 client.")
214
+ end
215
+
216
+ end
217
+
218
+ #------------------------------------------------------------------------------#
219
+ # Script entry point. Execute only if this file is being executed.
220
+ if __FILE__ == $0 || $0.match(/bin\/ec2-migrate-bundle/)
221
+ BundleMigrator.new().run(MigrateBundleParameters)
222
+ end
@@ -0,0 +1,173 @@
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/parameters_base'
12
+ require 'ec2/platform/current'
13
+ require 'ec2/amitools/region'
14
+
15
+ #------------------------------------------------------------------------------#
16
+
17
+ class MigrateBundleParameters < ParametersBase
18
+ include EC2::Platform::Current::Constants
19
+
20
+ MANIFEST_DESCRIPTION = "The name the manifest file."
21
+ DIRECTORY_DESCRIPTION = ["The directory containing the bundled AMI parts to upload.",
22
+ "Defaults to the directory containing the manifest."]
23
+ USER_CERT_PATH_DESCRIPTION = "The path to the user's PEM encoded RSA public key certificate file."
24
+ USER_PK_PATH_DESCRIPTION = "The path to the user's PEM encoded RSA private key file."
25
+ EC2_CERT_PATH_DESCRIPTION = ['The path to the EC2 X509 public key certificate bundled into the AMI.',
26
+ "Defaults to '#{Bundling::EC2_X509_CERT}'."]
27
+ KERNEL_DESCRIPTION = "Kernel id to bundle into the AMI."
28
+ RAMDISK_DESCRIPTION = "Ramdisk id to bundle into the AMI."
29
+ DEST_BUCKET_DESCRIPTION = "The bucket to copy bundle to. Created if nonexistent."
30
+ BUCKET_DESCRIPTION = "The bucket containing the AMI to be migrated."
31
+ USER_DESCRIPTION = "The user's AWS access key ID."
32
+ PASS_DESCRIPTION = "The user's AWS secret access key."
33
+ ACL_DESCRIPTION = ["The access control list policy [\"public-read\" | \"aws-exec-read\"].",
34
+ "Defaults to \"aws-exec-read\"."]
35
+ URL_DESCRIPTION = "The S3 service URL. Defaults to https://s3.amazonaws.com."
36
+ RETRY_DESCRIPTION = "Automatically retry failed uploads. Use with caution."
37
+ LOCATION_DESCRIPTION = "The location of the bucket to upload to [#{AwsRegion.regions.join(',')}]."
38
+ NO_MAPPING_DESCRIPTION = "Do not perform automatic mappings."
39
+ REGION_DESCRIPTION = "Region to look up in the mapping file."
40
+
41
+ attr_accessor :user_pk_path,
42
+ :user_cert_path,
43
+ :ec2_cert_path,
44
+ :user,
45
+ :pass,
46
+ :kernel_id,
47
+ :ramdisk_id,
48
+ :s3_url,
49
+ :bucket,
50
+ :keyprefix,
51
+ :dest_bucket,
52
+ :dest_keyprefix,
53
+ :manifest_name,
54
+ :location,
55
+ :acl,
56
+ :retry,
57
+ :use_mapping,
58
+ :region
59
+
60
+ def split_container(container)
61
+ splitbits = container.sub(%r{^/*},'').sub(%r{/*$},'').split("/")
62
+ bucket = splitbits.shift
63
+ keyprefix = splitbits.join("/")
64
+ keyprefix += "/" unless keyprefix.empty?
65
+ [bucket, keyprefix]
66
+ end
67
+
68
+ def mandatory_params()
69
+ on('-c', '--cert PATH', String, USER_CERT_PATH_DESCRIPTION) do |path|
70
+ assert_file_exists(path, '--cert')
71
+ @user_cert_path = path
72
+ end
73
+
74
+ on('-k', '--privatekey PATH', String, USER_PK_PATH_DESCRIPTION) do |path|
75
+ assert_file_exists(path, '--privatekey')
76
+ @user_pk_path = path
77
+ end
78
+
79
+ on('-m', '--manifest NAME', String, MANIFEST_DESCRIPTION) do |manifest|
80
+ raise InvalidValue.new("--manifest", manifest) unless manifest =~ /\.manifest\.xml$/
81
+ assert_good_key(manifest, '--manifest')
82
+ @manifest_name = manifest
83
+ end
84
+
85
+ on('-b', '--bucket BUCKET', String, BUCKET_DESCRIPTION) do |container|
86
+ @container = container
87
+ @bucket, @keyprefix = split_container(@container)
88
+ end
89
+
90
+ on('-d', '--destination-bucket BUCKET', String, DEST_BUCKET_DESCRIPTION) do |dest_container|
91
+ @dest_container = dest_container
92
+ @dest_bucket, @dest_keyprefix = split_container(@dest_container)
93
+ end
94
+
95
+ on('-a', '--access-key USER', String, USER_DESCRIPTION) do |user|
96
+ @user = user
97
+ end
98
+
99
+ on('-s', '--secret-key PASSWORD', String, PASS_DESCRIPTION) do |pass|
100
+ @pass = pass
101
+ end
102
+ end
103
+
104
+ def optional_params()
105
+ on('--ec2cert PATH', String, *EC2_CERT_PATH_DESCRIPTION) do |path|
106
+ assert_file_exists(path, '--ec2cert')
107
+ @ec2_cert_path = path
108
+ end
109
+
110
+ on('--acl ACL', String, *ACL_DESCRIPTION) do |acl|
111
+ raise InvalidValue.new('--acl', acl) unless ['public-read', 'aws-exec-read'].include?(acl)
112
+ @acl = acl
113
+ end
114
+
115
+ on('--url URL', String, URL_DESCRIPTION) do |url|
116
+ @s3_url = url
117
+ end
118
+
119
+ on('--retry', RETRY_DESCRIPTION) do
120
+ @retry = true
121
+ end
122
+
123
+ on('--location LOCATION', LOCATION_DESCRIPTION) do |location|
124
+ assert_option_in(location, AwsRegion.s3_locations, '--location')
125
+ @location = case location
126
+ when "eu-west-1" then "EU"
127
+ when "US" then :unconstrained
128
+ else location
129
+ end
130
+ end
131
+
132
+ on('--kernel KERNEL_ID', String, KERNEL_DESCRIPTION) do |kernel_id|
133
+ @kernel_id = kernel_id
134
+ end
135
+
136
+ on('--ramdisk RAMDISK_ID', String, RAMDISK_DESCRIPTION) do |ramdisk_id|
137
+ @ramdisk_id = ramdisk_id
138
+ end
139
+
140
+ on('--no-mapping', String, NO_MAPPING_DESCRIPTION) do
141
+ @use_mapping = false
142
+ end
143
+
144
+ on('--region REGION', String, REGION_DESCRIPTION) do |region|
145
+ @region = region
146
+ end
147
+ end
148
+
149
+ def validate_params()
150
+ raise MissingMandatory.new('--manifest') unless @manifest_name
151
+ raise MissingMandatory.new('--cert') unless @user_cert_path
152
+ raise MissingMandatory.new('--privatekey') unless @user_pk_path
153
+ raise MissingMandatory.new('--bucket') unless @container
154
+ raise MissingMandatory.new('--destination-bucket') unless @dest_container
155
+ raise MissingMandatory.new('--access-key') unless @user
156
+ raise MissingMandatory.new('--secret-key') unless @pass
157
+ end
158
+
159
+ def set_defaults()
160
+ @acl ||= 'aws-exec-read'
161
+ @s3_url ||= 'https://s3.amazonaws.com'
162
+ @ec2_cert_path ||= Bundling::EC2_X509_CERT
163
+ @use_mapping = true if @use_mapping.nil? # False is different.
164
+ end
165
+
166
+ def help()
167
+ s = "*** This tool is deprecated. ***\n"
168
+ s += "Please consider using ec2-migrate-image from the EC2 API tools.\n"
169
+ s += "You can download the EC2 API tools here:\n"
170
+ s += "http://aws.amazon.com/developertools/351\n"
171
+ s += super()
172
+ end
173
+ end