~awstools-dev/ubuntu/maverick/ec2-ami-tools/maverick

« back to all changes in this revision

Viewing changes to lib/ec2/amitools/bundleparameters.rb

  • Committer: Bazaar Package Importer
  • Author(s): Chuck Short
  • Date: 2008-10-14 08:35:25 UTC
  • Revision ID: james.westby@ubuntu.com-20081014083525-c0n69wr7r7aqfb8w
Tags: 1.3-26357-0ubuntu2
* New upstream version.
* Update the debian copyright file.
* Added quilt patch system to make it easier to maintain. 

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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.
 
10
 
 
11
require 'optparse'
 
12
require 'timeout'
 
13
require 'ec2/platform/current'
 
14
require 'ec2/amitools/syschecks'
 
15
require 'ec2/amitools/version'
 
16
 
 
17
# The Bundle command line parameters.
 
18
class BundleParameters < OptionParser
 
19
  include EC2::Platform::Current::Constants
 
20
 
 
21
  SUPPORTED_ARCHITECTURES = ['i386', 'x86_64']
 
22
  
 
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."
 
37
 
 
38
  attr_accessor :user_pk_path,
 
39
                :user_cert_path,
 
40
                :user,
 
41
                :destination,
 
42
                :ec2_cert_path,
 
43
                :debug,
 
44
                :show_help,
 
45
                :manual,
 
46
                :arch,
 
47
                :batch_mode,
 
48
                :product_codes
 
49
                
 
50
  PROMPT_TIMEOUT = 30
 
51
 
 
52
  class Error < RuntimeError
 
53
    class MissingMandatory < Error
 
54
      def initialize(name)
 
55
        super("missing mandatory parameter: #{name}")
 
56
      end
 
57
    end
 
58
    
 
59
    class InvalidParameterCombination < Error
 
60
      def initialize(message)
 
61
        super("invalid parameter combination: #{message}")
 
62
      end
 
63
    end
 
64
    
 
65
    class PromptTimeout < Error
 
66
      def initialize(name)
 
67
        super("Timed out waiting for user input: #{name}")
 
68
      end
 
69
    end
 
70
    
 
71
    class InvalidValue < Error
 
72
      def initialize(name, value)
 
73
        super("#{name} value invalid: #{value.to_s}")
 
74
      end
 
75
    end
 
76
    
 
77
    class InvalidExcludedDirectory < Error
 
78
      def initialize(dir)
 
79
        super("--exclude directory invalid: #{dir}")
 
80
      end
 
81
    end
 
82
  end
 
83
 
 
84
  def user_override(name, value)
 
85
    if interactive?
 
86
      begin
 
87
        STDOUT.print "Please specify a value for #{name} [#{value}]: "
 
88
        STDOUT.flush
 
89
        Timeout::timeout(PROMPT_TIMEOUT) do
 
90
          instr = gets
 
91
          return instr.strip unless instr.strip.empty?
 
92
        end
 
93
      rescue Timeout::Error
 
94
        raise Error::PromptTimeout.new(name)
 
95
      end
 
96
    end
 
97
    value
 
98
  end
 
99
 
 
100
  def notify(msg)
 
101
    STDOUT.puts msg
 
102
    if interactive?
 
103
      print "Hit enter to continue anyway or Control-C to quit."
 
104
      gets
 
105
    end
 
106
  end
 
107
 
 
108
  def interactive?()
 
109
    not (@batch_mode or @show_help or @manual)
 
110
  end
 
111
 
 
112
  def initialize( argv,
 
113
                  name,
 
114
                  add_mandatory_parameters_proc = nil,
 
115
                  add_optional_parameters_proc = nil )
 
116
    super( argv )
 
117
    
 
118
    self.banner = "Usage: #{name} PARAMETERS"
 
119
    
 
120
    #
 
121
    # Mandatory parameters.
 
122
    #
 
123
    separator( "" )
 
124
    separator( "MANDATORY PARAMETERS" )
 
125
    
 
126
    # Allow the child class to add specialised parameters.
 
127
    add_mandatory_parameters_proc.call() if add_mandatory_parameters_proc
 
128
    
 
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"
 
132
      end
 
133
      @user_cert_path = p
 
134
    end
 
135
    
 
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"
 
139
      end
 
140
      @user_pk_path = p
 
141
    end
 
142
    
 
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"
 
149
      end
 
150
    end
 
151
    
 
152
    #
 
153
    # Optional parameters.
 
154
    #
 
155
    self.separator( "" )
 
156
    self.separator( "OPTIONAL PARAMETERS" )
 
157
    
 
158
    # Allow the child class to add specialized parameters.
 
159
    add_optional_parameters_proc.call() if add_optional_parameters_proc
 
160
    
 
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 ) 
 
164
      end
 
165
      @destination = p
 
166
    end
 
167
    
 
168
    on( '--ec2cert PATH', String, *BundleParameters::EC2_CERT_PATH_DESCRIPTION ) do |p|
 
169
      @ec2_cert_path = p
 
170
    end
 
171
    
 
172
    on( '--debug', DEBUG_DESCRIPTION ) do
 
173
      @debug = true
 
174
    end
 
175
    
 
176
    on( '-h', '--help', HELP_DESCRIPTION ) do
 
177
      @show_help = true
 
178
    end
 
179
    
 
180
    on( '-m', '--manual', MANUAL_DESCRIPTION ) do
 
181
      @manual = true
 
182
    end
 
183
    
 
184
    on( '-r', '--arch ARCHITECTURE', String, ARCHITECTURE_DESCRIPTION ) do |a|
 
185
      @arch = a
 
186
    end
 
187
    
 
188
    on( '-b', '--batch', BATCH_DESCRIPTION ) do
 
189
      @batch_mode = true
 
190
    end
 
191
 
 
192
    on( '--version', VERSION_DESCRIPTION ) do
 
193
      puts version_copyright_string()
 
194
      exit
 
195
    end
 
196
 
 
197
    #
 
198
    # Parse the command line parameters.
 
199
    #
 
200
    parse!(argv)
 
201
 
 
202
    #
 
203
    # Check that we have a working tar of an appropriate version
 
204
    #
 
205
    tarcheck = SysChecks::good_tar_version?
 
206
    raise "missing or bad tar" if tarcheck.nil?
 
207
    if not tarcheck
 
208
      warn("Possibly broken tar version found. Please use tar version 1.15 or later.")
 
209
    end
 
210
 
 
211
    verify_mandatory_parameters
 
212
 
 
213
    if @arch.nil?
 
214
      @arch = SysChecks::get_system_arch()
 
215
      raise "missing or bad uname" if @arch.nil?
 
216
      @arch = user_override("arch", @arch)
 
217
    end
 
218
 
 
219
    if not SUPPORTED_ARCHITECTURES.include?(@arch)
 
220
      notify("Unsupported architecture [#{@arch}].")
 
221
    end
 
222
 
 
223
    #
 
224
    # Set defaults for optional parameters.
 
225
    #
 
226
    @destination = Bundling::DESTINATION unless @destination
 
227
    @ec2_cert_path = Bundling::EC2_X509_CERT unless @ec2_cert_path
 
228
    @exclude = [] unless @exclude
 
229
    
 
230
  end
 
231
  
 
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
 
237
    end
 
238
  end
 
239
end