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,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
|