1
2 """
3 StarCluster Exception Classes
4 """
5
6 import os
7
8 from starcluster import static
9 from starcluster.logger import log
10 from starcluster.templates import config, user_msgs
11
12
15 self.args = args
16 self.msg = args[0]
17
20
22 return "%s: %s" % (self.__class__.__name__, self.msg)
23
24
26 """Raised when command is not found on the system's PATH """
28 self.msg = "command not found: '%s'" % cmd
29
30
32 """Raised when command is not found on a *remote* system's PATH """
34 self.msg = "command not found on remote system: '%s'" % cmd
35
36
38 """Base class for all SSH related errors"""
39
40
42 """Raised when ssh fails to to connect to a host (socket error)"""
44 self.msg = "failed to connect to host %s on port %s" % (host, port)
45
46
48 """Raised when an ssh connection fails to authenticate"""
50 self.msg = "failed to authenticate to host %s as user %s" % (host,
51 user)
52
53
56 self.msg = "No password or key specified"
57
58
60 """SCP exception class"""
61 pass
62
63
65 """Base exception for all AWS related errors"""
66
67
70 self.msg = "region %s does not exist" % region_name
71
72
75 self.msg = "AMI %s does not exist" % image_id
76
77
79 - def __init__(self, instance_id, label='instance'):
80 self.msg = "%s '%s' does not exist" % (label, instance_id)
81
82
84 - def __init__(self, instance_id, state, label='instance'):
85 self.msg = "%s %s is not running (%s)" % (label, instance_id, state)
86
87
90 self.msg = "security group %s does not exist" % sg_name
91
92
95 self.msg = "placement group %s does not exist" % pg_name
96
97
100 self.msg = "keypair %s does not exist" % keyname
101
102
105 self.msg = "zone %s does not exist in region %s" % (zone, region)
106
107
110 self.msg = "volume %s does not exist" % vol_id
111
112
115 self.msg = "snapshot %s does not exist" % snap_id
116
117
120 self.msg = "bucket with name '%s' already exists on S3\n" % bucket_name
121 self.msg += "(NOTE: S3's bucket namepsace is shared by all AWS users)"
122
123
126 self.msg = "bucket '%s' does not exist" % bucket_name
127
128
131
132
135 self.msg = "bucket name %s is not valid" % bucket_name
136
137
140 self.msg = "image name %s is not valid" % image_name
141
142
145 self.msg = "No Amazon user id specified in config (AWS_USER_ID)"
146
147
150 self.msg = "No certificate file (pem) specified in config (EC2_CERT)"
151
152
155 self.msg = "No private certificate file (pem) file specified in " + \
156 "config (EC2_PRIVATE_KEY)"
157
158
161 self.msg = "EC2 certificate file %s does not exist" % key
162
163
166 self.msg = "EC2 private key file %s does not exist" % key
167
168
169 -class SpotHistoryError(AWSError):
170 - def __init__(self, start, end):
171 self.msg = "no spot price history for the dates specified: " + \
172 "%s - %s" % (start, end)
173
174
177 self.msg = "Invalid date specified: %s" % date
178
179
181 """Base class for all config related errors"""
182
183
186
187
190 self.msg = "No valid sections defined in config file %s" % cfg_file
191
192
195 self.msg = 'Plugin "%s" not found in config' % plugin
196
197
200 msg = "No default cluster template specified.\n\n"
201 msg += "To set the default cluster template, set DEFAULT_TEMPLATE "
202 msg += "in the [global] section of the config to the name of one of "
203 msg += "your cluster templates"
204 optlist = ', '.join(options)
205 if options:
206 msg += '\n\nCurrent Templates:\n\n' + optlist
207 self.msg = msg
208 self.options = options
209 self.options_list = optlist
210
211
217
219 cfg_parent_dir = os.path.dirname(self.cfg)
220 if not os.path.exists(cfg_parent_dir):
221 os.makedirs(cfg_parent_dir)
222 cfg_file = open(self.cfg, 'w')
223 cfg_file.write(config.config_template)
224 cfg_file.close()
225 log.info("Config template written to %s" % self.cfg)
226 log.info("Please customize the config template")
227
229 print 'Options:'
230 print '--------'
231 print '[1] Show the StarCluster config template'
232 print '[2] Write config template to %s' % self.cfg
233 print '[q] Quit'
234 resp = raw_input('\nPlease enter your selection: ')
235 if resp == '1':
236 print self.template
237 elif resp == '2':
238 print
239 self.create_config()
240
241
244 self.msg = "key %s not found in config" % keyname
245
246
249 self.msg = "invalid device specified: %s" % device
250
251
254 self.msg = "invalid partition specified: %s" % part
255
256
258 """Base class for plugin errors"""
259
260
262 """Raised when an error is encountered while loading a plugin"""
263
264
266 """Raised when plugin contains syntax errors"""
267
268
270 """Base class for validation related errors"""
271
272
274 """Raised when creating/loading a cluster receipt fails"""
275
276
278 """Cluster validation related errors"""
279
280
282 """Raised if no cluster nodes are found"""
284 self.msg = "No active cluster nodes found!"
285 if not terminated:
286 return
287 self.msg += "\n\nBelow is a list of terminated instances:\n"
288 for tnode in terminated:
289 id = tnode.id
290 reason = tnode.reason or 'N/A'
291 state = tnode.state or 'N/A'
292 self.msg += "\n%s (state: %s, reason: %s)" % (id, state, reason)
293
294
296 """Raised if no spot requests belonging to a cluster are found"""
298 self.msg = "No cluster spot requests found!"
299
300
302 """Raised when no master node is available"""
304 self.msg = "No master node found!"
305
306
308 """Raised when two or more settings conflict with each other"""
309
310
312 """Raised when user specifies an invalid IP protocol for permission"""
314 self.msg = "protocol %s is not a valid ip protocol. options: %s" % \
315 (protocol, ', '.join(static.PROTOCOLS))
316
317
319 """Raised when user specifies an invalid port range for permission"""
320 - def __init__(self, from_port, to_port, reason=None):
321 self.msg = ''
322 if reason:
323 self.msg += "%s\n" % reason
324 self.msg += "port range is invalid: from %s to %s" % (from_port,
325 to_port)
326
327
329 """Raised when user specifies an invalid CIDR ip for permission"""
331 self.msg = "cidr_ip is invalid: %s" % cidr
332
333
335 """
336 Raised when a zone has been specified that does not match the common
337 zone of the volumes being attached
338 """
339 - def __init__(self, zone, common_vol_zone):
340 cvz = common_vol_zone
341 self.msg = ("availability_zone setting '%s' does not " +
342 "match the common volume zone '%s'") % (zone, cvz)
343
344
347 vlist = ', '.join(volumes)
348 self.msg = 'Volumes %s are not in the same availability zone' % vlist
349
350
352 """
353 Exception raised when user requests a cluster template that does not exist
354 """
356 self.msg = "cluster template %s does not exist" % cluster_name
357
358
360 """
361 Exception raised when user requests a running cluster that does not exist
362 """
364 self.msg = "cluster %s is not running" % cluster_name
365
366
368 """
369 Exception raised when user requests a running cluster that does not exist
370 """
372 self.msg = "cluster '%s' does not exist" % cluster_name
373
374
376 - def __init__(self, cluster_name, is_ebs=False, stopped_ebs=False):
384
385
388 self.msg = "Request to start cluster '%s' was cancelled!!!" % tag
389 self.msg += "\n\nPlease be aware that instances may still be running."
390 self.msg += "\nYou can check this from the output of:"
391 self.msg += "\n\n $ starcluster listclusters"
392 self.msg += "\n\nIf you wish to destroy these instances please run:"
393 self.msg += "\n\n $ starcluster terminate %s" % tag
394 self.msg += "\n\nYou can then use:\n\n $ starcluster listclusters"
395 self.msg += "\n\nto verify that the cluster has been terminated."
396 self.msg += "\n\nIf you would like to re-use these instances, rerun"
397 self.msg += "\nthe same start command with the -x (--no-create) option"
398
399
402 self.msg = "Request to create a new volume was cancelled!!!"
403 self.msg += "\n\nPlease be aware that volume host instances"
404 self.msg += " may still be running. "
405 self.msg += "\n\nTo destroy these instances:"
406 self.msg += "\n\n $ starcluster terminate %s" % \
407 static.VOLUME_GROUP_NAME
408 self.msg += "\n\nYou can then use\n\n $ starcluster listinstances"
409 self.msg += "\n\nto verify that the volume hosts have been terminated."
410
411
413 - def __init__(self, bucket, image_name):
414 self.msg = "Request to create an S3 AMI was cancelled"
415 self.msg += "\n\nDepending on how far along the process was before it "
416 self.msg += "was cancelled, \nsome intermediate files might still be "
417 self.msg += "around in /mnt on the instance."
418 self.msg += "\n\nAlso, some of these intermediate files might "
419 self.msg += "have been uploaded to \nS3 in the '%(bucket)s' bucket "
420 self.msg += "you specified. You can check this using:"
421 self.msg += "\n\n $ starcluster showbucket %(bucket)s\n\n"
422 self.msg += "Look for files like: "
423 self.msg += "'%(iname)s.manifest.xml' or '%(iname)s.part.*'"
424 self.msg += "\nRe-executing the same s3image command "
425 self.msg += "should clean up these \nintermediate files and "
426 self.msg += "also automatically override any\npartially uploaded "
427 self.msg += "files in S3."
428 self.msg = self.msg % {'bucket': bucket, 'iname': image_name}
429
430
431 CancelledS3ImageCreation = CancelledCreateImage
432
433
435 - def __init__(self, is_ebs_backed, image_name):
436 self.msg = "Request to create EBS image %s was cancelled" % image_name
437 if is_ebs_backed:
438 self.msg += "\n\nDepending on how far along the process was "
439 self.msg += "before it was cancelled, \na snapshot of the image "
440 self.msg += "host's root volume may have been created.\nPlease "
441 self.msg += "inspect the output of:\n\n"
442 self.msg += " $ starcluster listsnapshots\n\n"
443 self.msg += "and clean up any unwanted snapshots"
444 else:
445 self.msg += "\n\nDepending on how far along the process was "
446 self.msg += "before it was cancelled, \na new volume and a "
447 self.msg += "snapshot of that new volume may have been created.\n"
448 self.msg += "Please inspect the output of:\n\n"
449 self.msg += " $ starcluster listvolumes\n\n"
450 self.msg += " and\n\n"
451 self.msg += " $ starcluster listsnapshots\n\n"
452 self.msg += "and clean up any unwanted volumes or snapshots"
453
454
457 self.msg = "%s is an experimental feature for this " % feature_name
458 self.msg += "release. If you wish to test this feature, please set "
459 self.msg += "ENABLE_EXPERIMENTAL=True in the [global] section of the"
460 self.msg += " config. \n\nYou've officially been warned :D"
461
462
465 self.msg = msg
466 self.exceptions = exceptions
467
470
478
479
481 main_msg = """\
482 The cluster '%(tag)s' was either created by a previous stable or development \
483 version of StarCluster or you manually created the '%(group)s' group. In any \
484 case '%(tag)s' cannot be used with this version of StarCluster (%(version)s).
485
486 """
487
488 insts_msg = """\
489 The cluster '%(tag)s' currently has %(num_nodes)d active nodes.
490
491 """
492
493 no_insts_msg = """\
494 The cluster '%(tag)s' does not have any nodes and is safe to terminate.
495
496 """
497
498 terminate_msg = """\
499 Please terminate the cluster using:
500
501 $ starcluster terminate %(tag)s
502 """
503
517