| OLD | NEW |
| 1 # Copyright (c) 2006-2010 Mitch Garnaat http://garnaat.org/ | 1 # Copyright (c) 2006-2010 Mitch Garnaat http://garnaat.org/ |
| 2 # Copyright (c) 2010, Eucalyptus Systems, Inc. | 2 # Copyright (c) 2010, Eucalyptus Systems, Inc. |
| 3 # All rights reserved. | 3 # All rights reserved. |
| 4 # | 4 # |
| 5 # Permission is hereby granted, free of charge, to any person obtaining a | 5 # Permission is hereby granted, free of charge, to any person obtaining a |
| 6 # copy of this software and associated documentation files (the | 6 # copy of this software and associated documentation files (the |
| 7 # "Software"), to deal in the Software without restriction, including | 7 # "Software"), to deal in the Software without restriction, including |
| 8 # without limitation the rights to use, copy, modify, merge, publish, dis- | 8 # without limitation the rights to use, copy, modify, merge, publish, dis- |
| 9 # tribute, sublicense, and/or sell copies of the Software, and to permit | 9 # tribute, sublicense, and/or sell copies of the Software, and to permit |
| 10 # persons to whom the Software is furnished to do so, subject to the fol- | 10 # persons to whom the Software is furnished to do so, subject to the fol- |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 import xml.sax | 28 import xml.sax |
| 29 from boto import handler | 29 from boto import handler |
| 30 from boto.resultset import ResultSet | 30 from boto.resultset import ResultSet |
| 31 | 31 |
| 32 | 32 |
| 33 class BotoClientError(StandardError): | 33 class BotoClientError(StandardError): |
| 34 """ | 34 """ |
| 35 General Boto Client error (error accessing AWS) | 35 General Boto Client error (error accessing AWS) |
| 36 """ | 36 """ |
| 37 | 37 |
| 38 def __init__(self, reason): | 38 def __init__(self, reason, *args): |
| 39 StandardError.__init__(self) | 39 StandardError.__init__(self, reason, *args) |
| 40 self.reason = reason | 40 self.reason = reason |
| 41 | 41 |
| 42 def __repr__(self): | 42 def __repr__(self): |
| 43 return 'BotoClientError: %s' % self.reason | 43 return 'BotoClientError: %s' % self.reason |
| 44 | 44 |
| 45 def __str__(self): | 45 def __str__(self): |
| 46 return 'BotoClientError: %s' % self.reason | 46 return 'BotoClientError: %s' % self.reason |
| 47 | 47 |
| 48 class SDBPersistenceError(StandardError): | 48 class SDBPersistenceError(StandardError): |
| 49 | 49 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 62 pass | 62 pass |
| 63 | 63 |
| 64 class GSPermissionsError(StoragePermissionsError): | 64 class GSPermissionsError(StoragePermissionsError): |
| 65 """ | 65 """ |
| 66 Permissions error when accessing a bucket or key on GS. | 66 Permissions error when accessing a bucket or key on GS. |
| 67 """ | 67 """ |
| 68 pass | 68 pass |
| 69 | 69 |
| 70 class BotoServerError(StandardError): | 70 class BotoServerError(StandardError): |
| 71 | 71 |
| 72 def __init__(self, status, reason, body=None): | 72 def __init__(self, status, reason, body=None, *args): |
| 73 StandardError.__init__(self) | 73 StandardError.__init__(self, status, reason, body, *args) |
| 74 self.status = status | 74 self.status = status |
| 75 self.reason = reason | 75 self.reason = reason |
| 76 self.body = body or '' | 76 self.body = body or '' |
| 77 self.request_id = None | 77 self.request_id = None |
| 78 self.error_code = None | 78 self.error_code = None |
| 79 self.error_message = None | 79 self.error_message = None |
| 80 self.box_usage = None | 80 self.box_usage = None |
| 81 | 81 |
| 82 # Attempt to parse the error response. If body isn't present, | 82 # Attempt to parse the error response. If body isn't present, |
| 83 # then just ignore the error response. | 83 # then just ignore the error response. |
| 84 if self.body: | 84 if self.body: |
| 85 try: | 85 try: |
| 86 h = handler.XmlHandler(self, self) | 86 h = handler.XmlHandler(self, self) |
| 87 xml.sax.parseString(self.body, h) | 87 xml.sax.parseString(self.body, h) |
| 88 except xml.sax.SAXParseException, pe: | 88 except xml.sax.SAXParseException, pe: |
| 89 # Go ahead and clean up anything that may have | 89 # Remove unparsable message body so we don't include garbage |
| 90 # managed to get into the error data so we | 90 # in exception. But first, save self.body in self.error_message |
| 91 # don't get partial garbage. | 91 # because occasionally we get error messages from Eucalyptus |
| 92 print "Warning: failed to parse error message from AWS: %s" % pe | 92 # that are just text strings that we want to preserve. |
| 93 self._cleanupParsedProperties() | 93 self.error_message = self.body |
| 94 self.body = None |
| 94 | 95 |
| 95 def __getattr__(self, name): | 96 def __getattr__(self, name): |
| 96 if name == 'message': | 97 if name == 'message': |
| 97 return self.error_message | 98 return self.error_message |
| 98 if name == 'code': | 99 if name == 'code': |
| 99 return self.error_code | 100 return self.error_code |
| 100 raise AttributeError | 101 raise AttributeError |
| 101 | 102 |
| 102 def __repr__(self): | 103 def __repr__(self): |
| 103 return '%s: %s %s\n%s' % (self.__class__.__name__, | 104 return '%s: %s %s\n%s' % (self.__class__.__name__, |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 214 def _cleanupParsedProperties(self): | 215 def _cleanupParsedProperties(self): |
| 215 BotoServerError._cleanupParsedProperties(self) | 216 BotoServerError._cleanupParsedProperties(self) |
| 216 for p in ('detail', 'type'): | 217 for p in ('detail', 'type'): |
| 217 setattr(self, p, None) | 218 setattr(self, p, None) |
| 218 | 219 |
| 219 class SQSDecodeError(BotoClientError): | 220 class SQSDecodeError(BotoClientError): |
| 220 """ | 221 """ |
| 221 Error when decoding an SQS message. | 222 Error when decoding an SQS message. |
| 222 """ | 223 """ |
| 223 def __init__(self, reason, message): | 224 def __init__(self, reason, message): |
| 224 BotoClientError.__init__(self, reason) | 225 BotoClientError.__init__(self, reason, message) |
| 225 self.message = message | 226 self.message = message |
| 226 | 227 |
| 227 def __repr__(self): | 228 def __repr__(self): |
| 228 return 'SQSDecodeError: %s' % self.reason | 229 return 'SQSDecodeError: %s' % self.reason |
| 229 | 230 |
| 230 def __str__(self): | 231 def __str__(self): |
| 231 return 'SQSDecodeError: %s' % self.reason | 232 return 'SQSDecodeError: %s' % self.reason |
| 232 | 233 |
| 233 class StorageResponseError(BotoServerError): | 234 class StorageResponseError(BotoServerError): |
| 234 """ | 235 """ |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 351 """ | 352 """ |
| 352 pass | 353 pass |
| 353 | 354 |
| 354 class FPSResponseError(BotoServerError): | 355 class FPSResponseError(BotoServerError): |
| 355 pass | 356 pass |
| 356 | 357 |
| 357 class InvalidUriError(Exception): | 358 class InvalidUriError(Exception): |
| 358 """Exception raised when URI is invalid.""" | 359 """Exception raised when URI is invalid.""" |
| 359 | 360 |
| 360 def __init__(self, message): | 361 def __init__(self, message): |
| 361 Exception.__init__(self) | 362 Exception.__init__(self, message) |
| 362 self.message = message | 363 self.message = message |
| 363 | 364 |
| 364 class InvalidAclError(Exception): | 365 class InvalidAclError(Exception): |
| 365 """Exception raised when ACL XML is invalid.""" | 366 """Exception raised when ACL XML is invalid.""" |
| 366 | 367 |
| 367 def __init__(self, message): | 368 def __init__(self, message): |
| 368 Exception.__init__(self) | 369 Exception.__init__(self, message) |
| 369 self.message = message | 370 self.message = message |
| 370 | 371 |
| 371 class NoAuthHandlerFound(Exception): | 372 class NoAuthHandlerFound(Exception): |
| 372 """Is raised when no auth handlers were found ready to authenticate.""" | 373 """Is raised when no auth handlers were found ready to authenticate.""" |
| 373 pass | 374 pass |
| 374 | 375 |
| 375 class TooManyAuthHandlerReadyToAuthenticate(Exception): | 376 class TooManyAuthHandlerReadyToAuthenticate(Exception): |
| 376 """Is raised when there are more than one auth handler ready. | 377 """Is raised when there are more than one auth handler ready. |
| 377 | 378 |
| 378 In normal situation there should only be one auth handler that is ready to | 379 In normal situation there should only be one auth handler that is ready to |
| 379 authenticate. In case where more than one auth handler is ready to | 380 authenticate. In case where more than one auth handler is ready to |
| 380 authenticate, we raise this exception, to prevent unpredictable behavior | 381 authenticate, we raise this exception, to prevent unpredictable behavior |
| 381 when multiple auth handlers can handle a particular case and the one chosen | 382 when multiple auth handlers can handle a particular case and the one chosen |
| 382 depends on the order they were checked. | 383 depends on the order they were checked. |
| 383 """ | 384 """ |
| 384 pass | 385 pass |
| 385 | 386 |
| 386 # Enum class for resumable upload failure disposition. | 387 # Enum class for resumable upload failure disposition. |
| 387 class ResumableTransferDisposition(object): | 388 class ResumableTransferDisposition(object): |
| 388 # START_OVER means an attempt to resume an existing transfer failed, | 389 # START_OVER means an attempt to resume an existing transfer failed, |
| 389 # and a new resumable upload should be attempted (without delay). | 390 # and a new resumable upload should be attempted (without delay). |
| 390 START_OVER = 'START_OVER' | 391 START_OVER = 'START_OVER' |
| 391 | 392 |
| 392 # WAIT_BEFORE_RETRY means the resumable transfer failed but that it can | 393 # WAIT_BEFORE_RETRY means the resumable transfer failed but that it can |
| 393 # be retried after a time delay. | 394 # be retried after a time delay within the current process. |
| 394 WAIT_BEFORE_RETRY = 'WAIT_BEFORE_RETRY' | 395 WAIT_BEFORE_RETRY = 'WAIT_BEFORE_RETRY' |
| 395 | 396 |
| 396 # ABORT means the resumable transfer failed and that delaying/retrying | 397 # ABORT_CUR_PROCESS means the resumable transfer failed and that |
| 397 # within the current process will not help. | 398 # delaying/retrying within the current process will not help. If |
| 399 # resumable transfer included a state tracker file the upload can be |
| 400 # retried again later, in another process (e.g., a later run of gsutil). |
| 401 ABORT_CUR_PROCESS = 'ABORT_CUR_PROCESS' |
| 402 |
| 403 # ABORT means the resumable transfer failed in a way that it does not |
| 404 # make sense to continue in the current process, and further that the |
| 405 # current tracker ID should not be preserved (in a tracker file if one |
| 406 # was specified at resumable upload start time). If the user tries again |
| 407 # later (e.g., a separate run of gsutil) it will get a new resumable |
| 408 # upload ID. |
| 398 ABORT = 'ABORT' | 409 ABORT = 'ABORT' |
| 399 | 410 |
| 400 class ResumableUploadException(Exception): | 411 class ResumableUploadException(Exception): |
| 401 """ | 412 """ |
| 402 Exception raised for various resumable upload problems. | 413 Exception raised for various resumable upload problems. |
| 403 | 414 |
| 404 self.disposition is of type ResumableTransferDisposition. | 415 self.disposition is of type ResumableTransferDisposition. |
| 405 """ | 416 """ |
| 406 | 417 |
| 407 def __init__(self, message, disposition): | 418 def __init__(self, message, disposition): |
| 408 Exception.__init__(self) | 419 Exception.__init__(self, message, disposition) |
| 409 self.message = message | 420 self.message = message |
| 410 self.disposition = disposition | 421 self.disposition = disposition |
| 411 | 422 |
| 412 def __repr__(self): | 423 def __repr__(self): |
| 413 return 'ResumableUploadException("%s", %s)' % ( | 424 return 'ResumableUploadException("%s", %s)' % ( |
| 414 self.message, self.disposition) | 425 self.message, self.disposition) |
| 415 | 426 |
| 416 class ResumableDownloadException(Exception): | 427 class ResumableDownloadException(Exception): |
| 417 """ | 428 """ |
| 418 Exception raised for various resumable download problems. | 429 Exception raised for various resumable download problems. |
| 419 | 430 |
| 420 self.disposition is of type ResumableTransferDisposition. | 431 self.disposition is of type ResumableTransferDisposition. |
| 421 """ | 432 """ |
| 422 | 433 |
| 423 def __init__(self, message, disposition): | 434 def __init__(self, message, disposition): |
| 424 Exception.__init__(self) | 435 Exception.__init__(self, message, disposition) |
| 425 self.message = message | 436 self.message = message |
| 426 self.disposition = disposition | 437 self.disposition = disposition |
| 427 | 438 |
| 428 def __repr__(self): | 439 def __repr__(self): |
| 429 return 'ResumableDownloadException("%s", %s)' % ( | 440 return 'ResumableDownloadException("%s", %s)' % ( |
| 430 self.message, self.disposition) | 441 self.message, self.disposition) |
| OLD | NEW |