1 """
2 StarCluster Exception Classes
3 """
4
5 import os
6
7 from starcluster import static
8 from starcluster.logger import log
9 from starcluster.templates import config, user_msgs
10
11
14 self.args = args
15 self.msg = args[0]
16
19
21 return "%s: %s" % (self.__class__.__name__, self.msg)
22
23
25 """Raised when command is not found on the system's PATH """
27 self.msg = "command not found: '%s'" % cmd
28
29
31 """Raised when command is not found on a *remote* system's PATH """
33 self.msg = "command not found on remote system: '%s'" % cmd
34
35
37 """Base class for all SSH related errors"""
38
39
41 """Raised when ssh fails to to connect to a host (socket error)"""
43 self.msg = "failed to connect to host %s on port %s" % (host, port)
44
45
47 """Raised when an ssh connection fails to authenticate"""
49 self.msg = "failed to authenticate to host %s as user %s" % (host,
50 user)
51
52
55 self.msg = "No password or key specified"
56
57
59 """SCP exception class"""
60 pass
61
62
64 """Base exception for all AWS related errors"""
65
66
69 self.msg = "region %s does not exist" % region_name
70
71
74 self.msg = "AMI %s does not exist" % image_id
75
76
78 - def __init__(self, instance_id, label='instance'):
79 self.msg = "%s '%s' does not exist" % (label, instance_id)
80
81
83 - def __init__(self, instance_id, state, label='instance'):
84 self.msg = "%s %s is not running (%s)" % (label, instance_id, state)
85
86
89 self.msg = "security group %s does not exist" % sg_name
90
91
94 self.msg = "placement group %s does not exist" % pg_name
95
96
99 self.msg = "keypair %s does not exist" % keyname
100
101
104 self.msg = "zone %s does not exist in region %s" % (zone, region)
105
106
109 self.msg = "volume %s does not exist" % vol_id
110
111
114 self.msg = "snapshot %s does not exist" % snap_id
115
116
119 self.msg = "bucket with name '%s' already exists on S3\n" % bucket_name
120 self.msg += "(NOTE: S3's bucket namespace is shared by all AWS users)"
121
122
125 self.msg = "bucket '%s' does not exist" % bucket_name
126
127
130
131
134 self.msg = "bucket name %s is not valid" % bucket_name
135
136
139 self.msg = "image name %s is not valid" % image_name
140
141
144 self.msg = "No Amazon user id specified in config (AWS_USER_ID)"
145
146
149 self.msg = "No certificate file (pem) specified in config (EC2_CERT)"
150
151
154 self.msg = "No private certificate file (pem) file specified in "
155 self.msg += "config (EC2_PRIVATE_KEY)"
156
157
160 self.msg = "EC2 certificate file %s does not exist" % key
161
162
165 self.msg = "EC2 private key file %s does not exist" % key
166
167
168 -class SpotHistoryError(AWSError):
169 - def __init__(self, start, end):
170 self.msg = "no spot price history for the dates specified: "
171 self.msg += "%s - %s" % (start, end)
172
173
176 self.msg = "Invalid date specified: %s" % date
177
178
180 """Base class for all config related errors"""
181
182
185
186
189 self.msg = "No valid sections defined in config file %s" % cfg_file
190
191
194 self.msg = 'Plugin "%s" not found in config' % plugin
195
196
199 msg = "No default cluster template specified.\n\n"
200 msg += "To set the default cluster template, set DEFAULT_TEMPLATE "
201 msg += "in the [global] section of the config to the name of one of "
202 msg += "your cluster templates"
203 optlist = ', '.join(options)
204 if options:
205 msg += '\n\nCurrent Templates:\n\n' + optlist
206 self.msg = msg
207 self.options = options
208 self.options_list = optlist
209
210
216
218 cfg_parent_dir = os.path.dirname(self.cfg)
219 if not os.path.exists(cfg_parent_dir):
220 os.makedirs(cfg_parent_dir)
221 cfg_file = open(self.cfg, 'w')
222 cfg_file.write(config.config_template)
223 cfg_file.close()
224 log.info("Config template written to %s" % self.cfg)
225 log.info("Please customize the config template")
226
228 print 'Options:'
229 print '--------'
230 print '[1] Show the StarCluster config template'
231 print '[2] Write config template to %s' % self.cfg
232 print '[q] Quit'
233 resp = raw_input('\nPlease enter your selection: ')
234 if resp == '1':
235 print self.template
236 elif resp == '2':
237 print
238 self.create_config()
239
240
243 self.msg = "key %s not found in config" % keyname
244
245
248 self.msg = "invalid device specified: %s" % device
249
250
253 self.msg = "invalid partition specified: %s" % part
254
255
257 """Base class for plugin errors"""
258
259
261 """Raised when an error is encountered while loading a plugin"""
262
263
265 """Raised when plugin contains syntax errors"""
266
267
269 """Base class for validation related errors"""
270
271
273 """Raised when creating/loading a cluster receipt fails"""
274
275
277 """Cluster validation related errors"""
278
279
281 """Raised if no cluster nodes are found"""
283 self.msg = "No active cluster nodes found!"
284 if not terminated:
285 return
286 self.msg += "\n\nBelow is a list of terminated instances:\n"
287 for tnode in terminated:
288 id = tnode.id
289 reason = tnode.reason or 'N/A'
290 state = tnode.state or 'N/A'
291 self.msg += "\n%s (state: %s, reason: %s)" % (id, state, reason)
292
293
295 """Raised if no spot requests belonging to a cluster are found"""
297 self.msg = "No cluster spot requests found!"
298
299
301 """Raised when no master node is available"""
303 self.msg = "No master node found!"
304
305
307 """Raised when two or more settings conflict with each other"""
308
309
311 """Raised when user specifies an invalid IP protocol for permission"""
313 self.msg = "protocol %s is not a valid ip protocol. options: %s"
314 self.msg %= (protocol, ', '.join(static.PROTOCOLS))
315
316
318 """Raised when user specifies an invalid port range for permission"""
319 - def __init__(self, from_port, to_port, reason=None):
320 self.msg = ''
321 if reason:
322 self.msg += "%s\n" % reason
323 self.msg += "port range is invalid: from %s to %s" % (from_port,
324 to_port)
325
326
328 """Raised when user specifies an invalid CIDR ip for permission"""
330 self.msg = "cidr_ip is invalid: %s" % cidr
331
332
334 """
335 Raised when a zone has been specified that does not match the common
336 zone of the volumes being attached
337 """
338 - def __init__(self, zone, common_vol_zone):
339 cvz = common_vol_zone
340 self.msg = ("availability_zone setting '%s' does not "
341 "match the common volume zone '%s'") % (zone, cvz)
342
343
346 vlist = ', '.join(volumes)
347 self.msg = 'Volumes %s are not in the same availability zone' % vlist
348
349
351 """
352 Exception raised when user requests a cluster template that does not exist
353 """
355 self.msg = "cluster template %s does not exist" % cluster_name
356
357
359 """
360 Exception raised when user requests a running cluster that does not exist
361 """
363 self.msg = "cluster %s is not running" % cluster_name
364
365
367 """
368 Exception raised when user requests a running cluster that does not exist
369 """
371 self.msg = "cluster '%s' does not exist" % cluster_name
372
373
375 - def __init__(self, cluster_name, is_ebs=False, stopped_ebs=False):
383
384
387 self.msg = "Request to start cluster '%s' was cancelled!!!" % tag
388 self.msg += "\n\nPlease be aware that instances may still be running."
389 self.msg += "\nYou can check this from the output of:"
390 self.msg += "\n\n $ starcluster listclusters"
391 self.msg += "\n\nIf you wish to destroy these instances please run:"
392 self.msg += "\n\n $ starcluster terminate %s" % tag
393 self.msg += "\n\nYou can then use:\n\n $ starcluster listclusters"
394 self.msg += "\n\nto verify that the cluster has been terminated."
395 self.msg += "\n\nIf you would like to re-use these instances, rerun"
396 self.msg += "\nthe same start command with the -x (--no-create) option"
397
398
401 self.msg = "Request to create a new volume was cancelled!!!"
402 self.msg += "\n\nPlease be aware that volume host instances"
403 self.msg += " may still be running. "
404 self.msg += "\n\nTo destroy these instances:"
405 self.msg += "\n\n $ starcluster terminate %s"
406 self.msg += "\n\nYou can then use\n\n $ starcluster listinstances"
407 self.msg += "\n\nto verify that the volume hosts have been terminated."
408 self.msg %= static.VOLUME_GROUP_NAME
409
410
412 - def __init__(self, bucket, image_name):
413 self.msg = "Request to create an S3 AMI was cancelled"
414 self.msg += "\n\nDepending on how far along the process was before it "
415 self.msg += "was cancelled, \nsome intermediate files might still be "
416 self.msg += "around in /mnt on the instance."
417 self.msg += "\n\nAlso, some of these intermediate files might "
418 self.msg += "have been uploaded to \nS3 in the '%(bucket)s' bucket "
419 self.msg += "you specified. You can check this using:"
420 self.msg += "\n\n $ starcluster showbucket %(bucket)s\n\n"
421 self.msg += "Look for files like: "
422 self.msg += "'%(iname)s.manifest.xml' or '%(iname)s.part.*'"
423 self.msg += "\nRe-executing the same s3image command "
424 self.msg += "should clean up these \nintermediate files and "
425 self.msg += "also automatically override any\npartially uploaded "
426 self.msg += "files in S3."
427 self.msg = self.msg % {'bucket': bucket, 'iname': image_name}
428
429
430 CancelledS3ImageCreation = CancelledCreateImage
431
432
434 - def __init__(self, is_ebs_backed, image_name):
435 self.msg = "Request to create EBS image %s was cancelled" % image_name
436 if is_ebs_backed:
437 self.msg += "\n\nDepending on how far along the process was "
438 self.msg += "before it was cancelled, \na snapshot of the image "
439 self.msg += "host's root volume may have been created.\nPlease "
440 self.msg += "inspect the output of:\n\n"
441 self.msg += " $ starcluster listsnapshots\n\n"
442 self.msg += "and clean up any unwanted snapshots"
443 else:
444 self.msg += "\n\nDepending on how far along the process was "
445 self.msg += "before it was cancelled, \na new volume and a "
446 self.msg += "snapshot of that new volume may have been created.\n"
447 self.msg += "Please inspect the output of:\n\n"
448 self.msg += " $ starcluster listvolumes\n\n"
449 self.msg += " and\n\n"
450 self.msg += " $ starcluster listsnapshots\n\n"
451 self.msg += "and clean up any unwanted volumes or snapshots"
452
453
456 self.msg = "%s is an experimental feature for this " % feature_name
457 self.msg += "release. If you wish to test this feature, please set "
458 self.msg += "ENABLE_EXPERIMENTAL=True in the [global] section of the"
459 self.msg += " config. \n\nYou've officially been warned :D"
460
461
464 self.msg = msg
465 self.exceptions = exceptions
466
469
477
478
480 main_msg = """\
481 The cluster '%(tag)s' was either created by a previous stable or development \
482 version of StarCluster or you manually created the '%(group)s' group. In any \
483 case '%(tag)s' cannot be used with this version of StarCluster (%(version)s).
484
485 """
486
487 insts_msg = """\
488 The cluster '%(tag)s' currently has %(num_nodes)d active nodes.
489
490 """
491
492 no_insts_msg = """\
493 The cluster '%(tag)s' does not have any nodes and is safe to terminate.
494
495 """
496
497 terminate_msg = """\
498 Please terminate the cluster using:
499
500 $ starcluster terminate %(tag)s
501 """
502
516