1
# Copyright 2008 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.
13
require 'ec2/platform/current'
14
require 'ec2/amitools/syschecks'
15
require 'ec2/amitools/version'
17
# The Bundle command line parameters.
18
class BundleParameters < OptionParser
19
include EC2::Platform::Current::Constants
21
SUPPORTED_ARCHITECTURES = ['i386', 'x86_64']
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
USER_DESCRIPTION = "The user's EC2 user ID (Note: AWS account number, NOT Access Key ID)."
26
HELP_DESCRIPTION = "Display this help message and exit."
27
MANUAL_DESCRIPTION = "Display the user manual and exit."
28
DESTINATION_DESCRIPTION = "The directory to create the bundle in. Defaults to '#{Bundling::DESTINATION}'."
29
DEBUG_DESCRIPTION = "Display debug messages."
30
EC2_CERT_PATH_DESCRIPTION = ['The path to the EC2 X509 public key certificate bundled into the AMI.',
31
"Defaults to '#{Bundling::EC2_X509_CERT}'."]
32
ARCHITECTURE_DESCRIPTION = "Specify target architecture. One of #{SUPPORTED_ARCHITECTURES.inspect}"
33
BATCH_DESCRIPTION = "Run in batch mode. No interactive prompts."
34
PRODUCT_CODES_DESCRIPTION = ['Default product codes attached to the image at registration time.',
35
'Comma separated list of product codes.']
36
VERSION_DESCRIPTION = "Display the version and copyright notice and then exit."
38
attr_accessor :user_pk_path,
52
class Error < RuntimeError
53
class MissingMandatory < Error
55
super("missing mandatory parameter: #{name}")
59
class InvalidParameterCombination < Error
60
def initialize(message)
61
super("invalid parameter combination: #{message}")
65
class PromptTimeout < Error
67
super("Timed out waiting for user input: #{name}")
71
class InvalidValue < Error
72
def initialize(name, value)
73
super("#{name} value invalid: #{value.to_s}")
77
class InvalidExcludedDirectory < Error
79
super("--exclude directory invalid: #{dir}")
84
def user_override(name, value)
87
STDOUT.print "Please specify a value for #{name} [#{value}]: "
89
Timeout::timeout(PROMPT_TIMEOUT) do
91
return instr.strip unless instr.strip.empty?
94
raise Error::PromptTimeout.new(name)
103
print "Hit enter to continue anyway or Control-C to quit."
109
not (@batch_mode or @show_help or @manual)
112
def initialize( argv,
114
add_mandatory_parameters_proc = nil,
115
add_optional_parameters_proc = nil )
118
self.banner = "Usage: #{name} PARAMETERS"
121
# Mandatory parameters.
124
separator( "MANDATORY PARAMETERS" )
126
# Allow the child class to add specialised parameters.
127
add_mandatory_parameters_proc.call() if add_mandatory_parameters_proc
129
on( '-c', '--cert PATH', String, USER_CERT_PATH_DESCRIPTION ) do |p|
130
unless File::exist?( p )
131
raise "the specified user certificate file #{p} does not exist"
136
on( '-k', '--privatekey PATH', String, USER_PK_PATH_DESCRIPTION ) do |p|
137
unless File::exist?( p )
138
raise "the specified private key file #{p} does not exist"
143
on( '-u', '--user USER', String, USER_DESCRIPTION) do |p|
144
# Remove hyphens from the Account ID as presented in AWS portal.
145
@user = p.gsub( "-", "" )
146
# Validate the account ID looks correct (users often provide us with their akid or secret key)
147
unless (@user =~ /\d{12}/)
148
raise "the user ID should consist of 12 digits (optionally hyphenated); this should not be your Access Key ID"
153
# Optional parameters.
156
self.separator( "OPTIONAL PARAMETERS" )
158
# Allow the child class to add specialized parameters.
159
add_optional_parameters_proc.call() if add_optional_parameters_proc
161
on( '-d', '--destination PATH', String, DESTINATION_DESCRIPTION ) do |p|
162
unless File::exist?( p ) and File::directory?( p )
163
raise Error::InvalidValue.new( '--destination', p )
168
on( '--ec2cert PATH', String, *BundleParameters::EC2_CERT_PATH_DESCRIPTION ) do |p|
172
on( '--debug', DEBUG_DESCRIPTION ) do
176
on( '-h', '--help', HELP_DESCRIPTION ) do
180
on( '-m', '--manual', MANUAL_DESCRIPTION ) do
184
on( '-r', '--arch ARCHITECTURE', String, ARCHITECTURE_DESCRIPTION ) do |a|
188
on( '-b', '--batch', BATCH_DESCRIPTION ) do
192
on( '--version', VERSION_DESCRIPTION ) do
193
puts version_copyright_string()
198
# Parse the command line parameters.
203
# Check that we have a working tar of an appropriate version
205
tarcheck = SysChecks::good_tar_version?
206
raise "missing or bad tar" if tarcheck.nil?
208
warn("Possibly broken tar version found. Please use tar version 1.15 or later.")
211
verify_mandatory_parameters
214
@arch = SysChecks::get_system_arch()
215
raise "missing or bad uname" if @arch.nil?
216
@arch = user_override("arch", @arch)
219
if not SUPPORTED_ARCHITECTURES.include?(@arch)
220
notify("Unsupported architecture [#{@arch}].")
224
# Set defaults for optional parameters.
226
@destination = Bundling::DESTINATION unless @destination
227
@ec2_cert_path = Bundling::EC2_X509_CERT unless @ec2_cert_path
228
@exclude = [] unless @exclude
232
def verify_mandatory_parameters
233
unless @show_help or @manual
234
raise Error::MissingMandatory.new( '--cert' ) unless @user_cert_path
235
raise Error::MissingMandatory.new( '--privatekey' ) unless @user_pk_path
236
raise Error::MissingMandatory.new( '--user' ) unless @user