1# Copyright 2010 United States Government as represented by the 2# Administrator of the National Aeronautics and Space Administration. 3# All Rights Reserved. 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); you may 6# not use this file except in compliance with the License. You may obtain 7# a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14# License for the specific language governing permissions and limitations 15# under the License. 16 17"""Cinder base exception handling. 18 19Includes decorator for re-raising Cinder-type exceptions. 20 21SHOULD include dedicated exception logging. 22 23""" 24 25from oslo_config import cfg 26from oslo_log import log as logging 27from oslo_versionedobjects import exception as obj_exc 28import six 29import webob.exc 30from webob.util import status_generic_reasons 31from webob.util import status_reasons 32 33from cinder.i18n import _ 34 35 36LOG = logging.getLogger(__name__) 37 38# TODO(smcginnis) Remove in Rocky 39exc_log_opts = [ 40 cfg.BoolOpt('fatal_exception_format_errors', 41 default=False, 42 help='Make exception message format errors fatal.', 43 deprecated_for_removal=True, 44 deprecated_since='12.0.0', 45 deprecated_reason='This is only used for internal testing.'), 46] 47 48CONF = cfg.CONF 49CONF.register_opts(exc_log_opts) 50 51 52class ConvertedException(webob.exc.WSGIHTTPException): 53 def __init__(self, code=500, title="", explanation=""): 54 self.code = code 55 # There is a strict rule about constructing status line for HTTP: 56 # '...Status-Line, consisting of the protocol version followed by a 57 # numeric status code and its associated textual phrase, with each 58 # element separated by SP characters' 59 # (http://www.faqs.org/rfcs/rfc2616.html) 60 # 'code' and 'title' can not be empty because they correspond 61 # to numeric status code and its associated text 62 if title: 63 self.title = title 64 else: 65 try: 66 self.title = status_reasons[self.code] 67 except KeyError: 68 generic_code = self.code // 100 69 self.title = status_generic_reasons[generic_code] 70 self.explanation = explanation 71 super(ConvertedException, self).__init__() 72 73 74class Error(Exception): 75 pass 76 77 78class CinderException(Exception): 79 """Base Cinder Exception 80 81 To correctly use this class, inherit from it and define 82 a 'message' property. That message will get printf'd 83 with the keyword arguments provided to the constructor. 84 85 """ 86 message = _("An unknown exception occurred.") 87 code = 500 88 headers = {} 89 safe = False 90 91 def __init__(self, message=None, **kwargs): 92 self.kwargs = kwargs 93 self.kwargs['message'] = message 94 95 if 'code' not in self.kwargs: 96 try: 97 self.kwargs['code'] = self.code 98 except AttributeError: 99 pass 100 101 for k, v in self.kwargs.items(): 102 if isinstance(v, Exception): 103 # NOTE(tommylikehu): If this is a cinder exception it will 104 # return the msg object, so we won't be preventing 105 # translations. 106 self.kwargs[k] = six.text_type(v) 107 108 if self._should_format(): 109 try: 110 message = self.message % kwargs 111 112 except Exception: 113 # NOTE(melwitt): This is done in a separate method so it can be 114 # monkey-patched during testing to make it a hard failure. 115 self._log_exception() 116 message = self.message 117 elif isinstance(message, Exception): 118 # NOTE(tommylikehu): If this is a cinder exception it will 119 # return the msg object, so we won't be preventing 120 # translations. 121 message = six.text_type(message) 122 123 # NOTE(luisg): We put the actual message in 'msg' so that we can access 124 # it, because if we try to access the message via 'message' it will be 125 # overshadowed by the class' message attribute 126 self.msg = message 127 super(CinderException, self).__init__(message) 128 # Oslo.messaging use the argument 'message' to rebuild exception 129 # directly at the rpc client side, therefore we should not use it 130 # in our keyword arguments, otherwise, the rebuild process will fail 131 # with duplicate keyword exception. 132 self.kwargs.pop('message', None) 133 134 def _log_exception(self): 135 # kwargs doesn't match a variable in the message 136 # log the issue and the kwargs 137 LOG.exception('Exception in string format operation:') 138 for name, value in self.kwargs.items(): 139 LOG.error("%(name)s: %(value)s", 140 {'name': name, 'value': value}) 141 142 def _should_format(self): 143 return self.kwargs['message'] is None or '%(message)' in self.message 144 145 # NOTE(tommylikehu): self.msg is already an unicode compatible object 146 # as the __init__ method ensures of it, and we should not be modifying 147 # it in any way with str(), unicode(), or six.text_type() as we would 148 # be preventing translations from happening. 149 def __unicode__(self): 150 return self.msg 151 152 153class VolumeBackendAPIException(CinderException): 154 message = _("Bad or unexpected response from the storage volume " 155 "backend API: %(data)s") 156 157 158class VolumeDriverException(CinderException): 159 message = _("Volume driver reported an error: %(message)s") 160 161 162class BackupDriverException(CinderException): 163 message = _("Backup driver reported an error: %(message)s") 164 165 166class GlanceConnectionFailed(CinderException): 167 message = _("Connection to glance failed: %(reason)s") 168 169 170class ProgrammingError(CinderException): 171 message = _('Programming error in Cinder: %(reason)s') 172 173 174class NotAuthorized(CinderException): 175 message = _("Not authorized.") 176 code = 403 177 178 179class AdminRequired(NotAuthorized): 180 message = _("User does not have admin privileges") 181 182 183class PolicyNotAuthorized(NotAuthorized): 184 message = _("Policy doesn't allow %(action)s to be performed.") 185 186 187class ImageNotAuthorized(CinderException): 188 message = _("Not authorized for image %(image_id)s.") 189 190 191class DriverNotInitialized(CinderException): 192 message = _("Volume driver not ready.") 193 194 195class Invalid(CinderException): 196 message = _("Unacceptable parameters.") 197 code = 400 198 199 200class InvalidSnapshot(Invalid): 201 message = _("Invalid snapshot: %(reason)s") 202 203 204class InvalidVolumeAttachMode(Invalid): 205 message = _("Invalid attaching mode '%(mode)s' for " 206 "volume %(volume_id)s.") 207 208 209class VolumeAttached(Invalid): 210 message = _("Volume %(volume_id)s is still attached, detach volume first.") 211 212 213class InvalidResults(Invalid): 214 message = _("The results are invalid.") 215 216 217class InvalidInput(Invalid): 218 message = _("Invalid input received: %(reason)s") 219 220 221class InvalidAvailabilityZone(Invalid): 222 message = _("Availability zone '%(az)s' is invalid.") 223 224 225class InvalidVolumeType(Invalid): 226 message = _("Invalid volume type: %(reason)s") 227 228 229class InvalidGroupType(Invalid): 230 message = _("Invalid group type: %(reason)s") 231 232 233class InvalidVolume(Invalid): 234 message = _("Invalid volume: %(reason)s") 235 236 237class InvalidContentType(Invalid): 238 message = _("Invalid content type %(content_type)s.") 239 240 241class InvalidHost(Invalid): 242 message = _("Invalid host: %(reason)s") 243 244 245# Cannot be templated as the error syntax varies. 246# msg needs to be constructed when raised. 247class InvalidParameterValue(Invalid): 248 message = "%(err)s" 249 250 251class InvalidAuthKey(Invalid): 252 message = _("Invalid auth key: %(reason)s") 253 254 255class InvalidConfigurationValue(Invalid): 256 message = _('Value "%(value)s" is not valid for ' 257 'configuration option "%(option)s"') 258 259 260class ServiceUnavailable(Invalid): 261 message = _("Service is unavailable at this time.") 262 263 264class UnavailableDuringUpgrade(Invalid): 265 message = _('Cannot perform %(action)s during system upgrade.') 266 267 268class ImageUnacceptable(Invalid): 269 message = _("Image %(image_id)s is unacceptable: %(reason)s") 270 271 272class ImageTooBig(Invalid): 273 message = _("Image %(image_id)s size exceeded available " 274 "disk space: %(reason)s") 275 276 277class DeviceUnavailable(Invalid): 278 message = _("The device in the path %(path)s is unavailable: %(reason)s") 279 280 281class SnapshotUnavailable(VolumeBackendAPIException): 282 message = _("The snapshot is unavailable: %(data)s") 283 284 285class InvalidUUID(Invalid): 286 message = _("Expected a UUID but received %(uuid)s.") 287 288 289class InvalidAPIVersionString(Invalid): 290 message = _("API Version String %(version)s is of invalid format. Must " 291 "be of format MajorNum.MinorNum.") 292 293 294class VersionNotFoundForAPIMethod(Invalid): 295 message = _("API version %(version)s is not supported on this method.") 296 297 298class InvalidGlobalAPIVersion(Invalid): 299 message = _("Version %(req_ver)s is not supported by the API. Minimum " 300 "is %(min_ver)s and maximum is %(max_ver)s.") 301 302 303class MissingRequired(Invalid): 304 message = _("Missing required element '%(element)s' in request body.") 305 306 307class ValidationError(Invalid): 308 message = "%(detail)s" 309 310 311class APIException(CinderException): 312 message = _("Error while requesting %(service)s API.") 313 314 def __init__(self, message=None, **kwargs): 315 if 'service' not in kwargs: 316 kwargs['service'] = 'unknown' 317 super(APIException, self).__init__(message, **kwargs) 318 319 320class APITimeout(APIException): 321 message = _("Timeout while requesting %(service)s API.") 322 323 324class RPCTimeout(CinderException): 325 message = _("Timeout while requesting capabilities from backend " 326 "%(service)s.") 327 code = 502 328 329 330class Duplicate(CinderException): 331 pass 332 333 334class NotFound(CinderException): 335 message = _("Resource could not be found.") 336 code = 404 337 safe = True 338 339 340class VolumeNotFound(NotFound): 341 message = _("Volume %(volume_id)s could not be found.") 342 343 344class MessageNotFound(NotFound): 345 message = _("Message %(message_id)s could not be found.") 346 347 348class VolumeAttachmentNotFound(NotFound): 349 message = _("Volume attachment could not be found with " 350 "filter: %(filter)s.") 351 352 353class VolumeMetadataNotFound(NotFound): 354 message = _("Volume %(volume_id)s has no metadata with " 355 "key %(metadata_key)s.") 356 357 358class VolumeAdminMetadataNotFound(NotFound): 359 message = _("Volume %(volume_id)s has no administration metadata with " 360 "key %(metadata_key)s.") 361 362 363class InvalidVolumeMetadata(Invalid): 364 message = _("Invalid metadata: %(reason)s") 365 366 367class InvalidVolumeMetadataSize(Invalid): 368 message = _("Invalid metadata size: %(reason)s") 369 370 371class SnapshotMetadataNotFound(NotFound): 372 message = _("Snapshot %(snapshot_id)s has no metadata with " 373 "key %(metadata_key)s.") 374 375 376class VolumeTypeNotFound(NotFound): 377 message = _("Volume type %(volume_type_id)s could not be found.") 378 379 380class VolumeTypeNotFoundByName(VolumeTypeNotFound): 381 message = _("Volume type with name %(volume_type_name)s " 382 "could not be found.") 383 384 385class VolumeTypeAccessNotFound(NotFound): 386 message = _("Volume type access not found for %(volume_type_id)s / " 387 "%(project_id)s combination.") 388 389 390class VolumeTypeExtraSpecsNotFound(NotFound): 391 message = _("Volume Type %(volume_type_id)s has no extra specs with " 392 "key %(extra_specs_key)s.") 393 394 395class VolumeTypeInUse(CinderException): 396 message = _("Volume Type %(volume_type_id)s deletion is not allowed with " 397 "volumes present with the type.") 398 399 400class GroupTypeNotFound(NotFound): 401 message = _("Group type %(group_type_id)s could not be found.") 402 403 404class GroupTypeNotFoundByName(GroupTypeNotFound): 405 message = _("Group type with name %(group_type_name)s " 406 "could not be found.") 407 408 409class GroupTypeAccessNotFound(NotFound): 410 message = _("Group type access not found for %(group_type_id)s / " 411 "%(project_id)s combination.") 412 413 414class GroupTypeSpecsNotFound(NotFound): 415 message = _("Group Type %(group_type_id)s has no specs with " 416 "key %(group_specs_key)s.") 417 418 419class GroupTypeInUse(CinderException): 420 message = _("Group Type %(group_type_id)s deletion is not allowed with " 421 "groups present with the type.") 422 423 424class SnapshotNotFound(NotFound): 425 message = _("Snapshot %(snapshot_id)s could not be found.") 426 427 428class ServerNotFound(NotFound): 429 message = _("Instance %(uuid)s could not be found.") 430 431 432class VolumeSnapshotNotFound(NotFound): 433 message = _("No snapshots found for volume %(volume_id)s.") 434 435 436class VolumeIsBusy(CinderException): 437 message = _("deleting volume %(volume_name)s that has snapshot") 438 439 440class SnapshotIsBusy(CinderException): 441 message = _("deleting snapshot %(snapshot_name)s that has " 442 "dependent volumes") 443 444 445class ISCSITargetNotFoundForVolume(NotFound): 446 message = _("No target id found for volume %(volume_id)s.") 447 448 449class InvalidImageRef(Invalid): 450 message = _("Invalid image href %(image_href)s.") 451 452 453class ImageNotFound(NotFound): 454 message = _("Image %(image_id)s could not be found.") 455 456 457class ServiceNotFound(NotFound): 458 459 def __init__(self, message=None, **kwargs): 460 if not message: 461 if kwargs.get('host', None): 462 self.message = _("Service %(service_id)s could not be " 463 "found on host %(host)s.") 464 else: 465 self.message = _("Service %(service_id)s could not be found.") 466 super(ServiceNotFound, self).__init__(message, **kwargs) 467 468 469class ServiceTooOld(Invalid): 470 message = _("Service is too old to fulfil this request.") 471 472 473class WorkerNotFound(NotFound): 474 message = _("Worker with %s could not be found.") 475 476 def __init__(self, message=None, **kwargs): 477 keys_list = ('{0}=%({0})s'.format(key) for key in kwargs) 478 placeholder = ', '.join(keys_list) 479 self.message = self.message % placeholder 480 super(WorkerNotFound, self).__init__(message, **kwargs) 481 482 483class WorkerExists(Duplicate): 484 message = _("Worker for %(type)s %(id)s already exists.") 485 486 487class CleanableInUse(Invalid): 488 message = _('%(type)s with id %(id)s is already being cleaned up or ' 489 'another host has taken over it.') 490 491 492class ClusterNotFound(NotFound): 493 message = _('Cluster %(id)s could not be found.') 494 495 496class ClusterHasHosts(Invalid): 497 message = _("Cluster %(id)s still has hosts.") 498 499 500class ClusterExists(Duplicate): 501 message = _("Cluster %(name)s already exists.") 502 503 504class HostNotFound(NotFound): 505 message = _("Host %(host)s could not be found.") 506 507 508class SchedulerHostFilterNotFound(NotFound): 509 message = _("Scheduler Host Filter %(filter_name)s could not be found.") 510 511 512class SchedulerHostWeigherNotFound(NotFound): 513 message = _("Scheduler Host Weigher %(weigher_name)s could not be found.") 514 515 516class InvalidReservationExpiration(Invalid): 517 message = _("Invalid reservation expiration %(expire)s.") 518 519 520class InvalidQuotaValue(Invalid): 521 message = _("Change would make usage less than 0 for the following " 522 "resources: %(unders)s") 523 524 525class InvalidNestedQuotaSetup(CinderException): 526 message = _("Project quotas are not properly setup for nested quotas: " 527 "%(reason)s.") 528 529 530class QuotaNotFound(NotFound): 531 message = _("Quota could not be found") 532 533 534class QuotaResourceUnknown(QuotaNotFound): 535 message = _("Unknown quota resources %(unknown)s.") 536 537 538class ProjectQuotaNotFound(QuotaNotFound): 539 message = _("Quota for project %(project_id)s could not be found.") 540 541 542class QuotaClassNotFound(QuotaNotFound): 543 message = _("Quota class %(class_name)s could not be found.") 544 545 546class QuotaUsageNotFound(QuotaNotFound): 547 message = _("Quota usage for project %(project_id)s could not be found.") 548 549 550class ReservationNotFound(QuotaNotFound): 551 message = _("Quota reservation %(uuid)s could not be found.") 552 553 554class OverQuota(CinderException): 555 message = _("Quota exceeded for resources: %(overs)s") 556 557 558class FileNotFound(NotFound): 559 message = _("File %(file_path)s could not be found.") 560 561 562class VolumeTypeExists(Duplicate): 563 message = _("Volume Type %(id)s already exists.") 564 565 566class VolumeTypeAccessExists(Duplicate): 567 message = _("Volume type access for %(volume_type_id)s / " 568 "%(project_id)s combination already exists.") 569 570 571class VolumeTypeEncryptionExists(Invalid): 572 message = _("Volume type encryption for type %(type_id)s already exists.") 573 574 575class VolumeTypeEncryptionNotFound(NotFound): 576 message = _("Volume type encryption for type %(type_id)s does not exist.") 577 578 579class GroupTypeExists(Duplicate): 580 message = _("Group Type %(id)s already exists.") 581 582 583class GroupTypeAccessExists(Duplicate): 584 message = _("Group type access for %(group_type_id)s / " 585 "%(project_id)s combination already exists.") 586 587 588class GroupVolumeTypeMappingExists(Duplicate): 589 message = _("Group volume type mapping for %(group_id)s / " 590 "%(volume_type_id)s combination already exists.") 591 592 593class GroupTypeEncryptionExists(Invalid): 594 message = _("Group type encryption for type %(type_id)s already exists.") 595 596 597class GroupTypeEncryptionNotFound(NotFound): 598 message = _("Group type encryption for type %(type_id)s does not exist.") 599 600 601class MalformedRequestBody(CinderException): 602 message = _("Malformed message body: %(reason)s") 603 604 605class ConfigNotFound(NotFound): 606 message = _("Could not find config at %(path)s") 607 608 609class ParameterNotFound(NotFound): 610 message = _("Could not find parameter %(param)s") 611 612 613class NoValidBackend(CinderException): 614 message = _("No valid backend was found. %(reason)s") 615 616 617class NoMoreTargets(CinderException): 618 """No more available targets.""" 619 pass 620 621 622class QuotaError(CinderException): 623 message = _("Quota exceeded: code=%(code)s") 624 code = 413 625 headers = {'Retry-After': '0'} 626 safe = True 627 628 629class VolumeSizeExceedsAvailableQuota(QuotaError): 630 message = _("Requested volume or snapshot exceeds allowed %(name)s " 631 "quota. Requested %(requested)sG, quota is %(quota)sG and " 632 "%(consumed)sG has been consumed.") 633 634 def __init__(self, message=None, **kwargs): 635 kwargs.setdefault('name', 'gigabytes') 636 super(VolumeSizeExceedsAvailableQuota, self).__init__( 637 message, **kwargs) 638 639 640class VolumeSizeExceedsLimit(QuotaError): 641 message = _("Requested volume size %(size)dG is larger than " 642 "maximum allowed limit %(limit)dG.") 643 644 645class VolumeBackupSizeExceedsAvailableQuota(QuotaError): 646 message = _("Requested backup exceeds allowed Backup gigabytes " 647 "quota. Requested %(requested)sG, quota is %(quota)sG and " 648 "%(consumed)sG has been consumed.") 649 650 651class VolumeLimitExceeded(QuotaError): 652 message = _("Maximum number of volumes allowed (%(allowed)d) exceeded for " 653 "quota '%(name)s'.") 654 655 def __init__(self, message=None, **kwargs): 656 kwargs.setdefault('name', 'volumes') 657 super(VolumeLimitExceeded, self).__init__(message, **kwargs) 658 659 660class SnapshotLimitExceeded(QuotaError): 661 message = _("Maximum number of snapshots allowed (%(allowed)d) exceeded") 662 663 664class UnexpectedOverQuota(QuotaError): 665 message = _("Unexpected over quota on %(name)s.") 666 667 668class BackupLimitExceeded(QuotaError): 669 message = _("Maximum number of backups allowed (%(allowed)d) exceeded") 670 671 672class ImageLimitExceeded(QuotaError): 673 message = _("Image quota exceeded") 674 675 676class DuplicateSfVolumeNames(Duplicate): 677 message = _("Detected more than one volume with name %(vol_name)s") 678 679 680class VolumeTypeCreateFailed(CinderException): 681 message = _("Cannot create volume_type with " 682 "name %(name)s and specs %(extra_specs)s") 683 684 685class VolumeTypeUpdateFailed(CinderException): 686 message = _("Cannot update volume_type %(id)s") 687 688 689class GroupTypeCreateFailed(CinderException): 690 message = _("Cannot create group_type with " 691 "name %(name)s and specs %(group_specs)s") 692 693 694class GroupTypeUpdateFailed(CinderException): 695 message = _("Cannot update group_type %(id)s") 696 697 698class GroupLimitExceeded(QuotaError): 699 message = _("Maximum number of groups allowed (%(allowed)d) exceeded") 700 701 702class UnknownCmd(VolumeDriverException): 703 message = _("Unknown or unsupported command %(cmd)s") 704 705 706class MalformedResponse(VolumeDriverException): 707 message = _("Malformed response to command %(cmd)s: %(reason)s") 708 709 710class FailedCmdWithDump(VolumeDriverException): 711 message = _("Operation failed with status=%(status)s. Full dump: %(data)s") 712 713 714class InvalidConnectorException(VolumeDriverException): 715 message = _("Connector doesn't have required information: %(missing)s") 716 717 718class GlanceMetadataExists(Invalid): 719 message = _("Glance metadata cannot be updated, key %(key)s" 720 " exists for volume id %(volume_id)s") 721 722 723class GlanceMetadataNotFound(NotFound): 724 message = _("Glance metadata for volume/snapshot %(id)s cannot be found.") 725 726 727class ImageDownloadFailed(CinderException): 728 message = _("Failed to download image %(image_href)s, reason: %(reason)s") 729 730 731class ExportFailure(Invalid): 732 message = _("Failed to export for volume: %(reason)s") 733 734 735class RemoveExportException(VolumeDriverException): 736 message = _("Failed to remove export for volume %(volume)s: %(reason)s") 737 738 739class MetadataCreateFailure(Invalid): 740 message = _("Failed to create metadata for volume: %(reason)s") 741 742 743class MetadataUpdateFailure(Invalid): 744 message = _("Failed to update metadata for volume: %(reason)s") 745 746 747class MetadataCopyFailure(Invalid): 748 message = _("Failed to copy metadata to volume: %(reason)s") 749 750 751class InvalidMetadataType(Invalid): 752 message = _("The type of metadata: %(metadata_type)s for volume/snapshot " 753 "%(id)s is invalid.") 754 755 756class ImageCopyFailure(Invalid): 757 message = _("Failed to copy image to volume: %(reason)s") 758 759 760class BackupInvalidCephArgs(BackupDriverException): 761 message = _("Invalid Ceph args provided for backup rbd operation") 762 763 764class BackupOperationError(Invalid): 765 message = _("An error has occurred during backup operation") 766 767 768class BackupMetadataUnsupportedVersion(BackupDriverException): 769 message = _("Unsupported backup metadata version requested") 770 771 772class BackupMetadataNotFound(NotFound): 773 message = _("Backup %(backup_id)s has no metadata with " 774 "key %(metadata_key)s.") 775 776 777class BackupVerifyUnsupportedDriver(BackupDriverException): 778 message = _("Unsupported backup verify driver") 779 780 781class VolumeMetadataBackupExists(BackupDriverException): 782 message = _("Metadata backup already exists for this volume") 783 784 785class BackupRBDOperationFailed(BackupDriverException): 786 message = _("Backup RBD operation failed") 787 788 789class EncryptedBackupOperationFailed(BackupDriverException): 790 message = _("Backup operation of an encrypted volume failed.") 791 792 793class BackupNotFound(NotFound): 794 message = _("Backup %(backup_id)s could not be found.") 795 796 797class BackupFailedToGetVolumeBackend(NotFound): 798 message = _("Failed to identify volume backend.") 799 800 801class InvalidBackup(Invalid): 802 message = _("Invalid backup: %(reason)s") 803 804 805class SwiftConnectionFailed(BackupDriverException): 806 message = _("Connection to swift failed: %(reason)s") 807 808 809class TransferNotFound(NotFound): 810 message = _("Transfer %(transfer_id)s could not be found.") 811 812 813class VolumeMigrationFailed(CinderException): 814 message = _("Volume migration failed: %(reason)s") 815 816 817class SSHInjectionThreat(CinderException): 818 message = _("SSH command injection detected: %(command)s") 819 820 821class QoSSpecsExists(Duplicate): 822 message = _("QoS Specs %(specs_id)s already exists.") 823 824 825class QoSSpecsCreateFailed(CinderException): 826 message = _("Failed to create qos_specs: " 827 "%(name)s with specs %(qos_specs)s.") 828 829 830class QoSSpecsUpdateFailed(CinderException): 831 message = _("Failed to update qos_specs: " 832 "%(specs_id)s with specs %(qos_specs)s.") 833 834 835class QoSSpecsNotFound(NotFound): 836 message = _("No such QoS spec %(specs_id)s.") 837 838 839class QoSSpecsAssociateFailed(CinderException): 840 message = _("Failed to associate qos_specs: " 841 "%(specs_id)s with type %(type_id)s.") 842 843 844class QoSSpecsDisassociateFailed(CinderException): 845 message = _("Failed to disassociate qos_specs: " 846 "%(specs_id)s with type %(type_id)s.") 847 848 849class QoSSpecsKeyNotFound(NotFound): 850 message = _("QoS spec %(specs_id)s has no spec with " 851 "key %(specs_key)s.") 852 853 854class InvalidQoSSpecs(Invalid): 855 message = _("Invalid qos specs: %(reason)s") 856 857 858class QoSSpecsInUse(CinderException): 859 message = _("QoS Specs %(specs_id)s is still associated with entities.") 860 861 862class KeyManagerError(CinderException): 863 message = _("key manager error: %(reason)s") 864 865 866class ManageExistingInvalidReference(CinderException): 867 message = _("Manage existing volume failed due to invalid backend " 868 "reference %(existing_ref)s: %(reason)s") 869 870 871class ManageExistingAlreadyManaged(CinderException): 872 message = _("Unable to manage existing volume. " 873 "Volume %(volume_ref)s already managed.") 874 875 876class InvalidReplicationTarget(Invalid): 877 message = _("Invalid Replication Target: %(reason)s") 878 879 880class UnableToFailOver(CinderException): 881 message = _("Unable to failover to replication target: %(reason)s).") 882 883 884class ReplicationError(CinderException): 885 message = _("Volume %(volume_id)s replication " 886 "error: %(reason)s") 887 888 889class ReplicationGroupError(CinderException): 890 message = _("Group %(group_id)s replication " 891 "error: %(reason)s.") 892 893 894class ReplicationNotFound(NotFound): 895 message = _("Volume replication for %(volume_id)s " 896 "could not be found.") 897 898 899class ManageExistingVolumeTypeMismatch(CinderException): 900 message = _("Manage existing volume failed due to volume type mismatch: " 901 "%(reason)s") 902 903 904class ExtendVolumeError(CinderException): 905 message = _("Error extending volume: %(reason)s") 906 907 908class EvaluatorParseException(Exception): 909 message = _("Error during evaluator parsing: %(reason)s") 910 911 912class LockCreationFailed(CinderException): 913 message = _('Unable to create lock. Coordination backend not started.') 914 915 916class LockingFailed(CinderException): 917 message = _('Lock acquisition failed.') 918 919 920UnsupportedObjectError = obj_exc.UnsupportedObjectError 921OrphanedObjectError = obj_exc.OrphanedObjectError 922IncompatibleObjectVersion = obj_exc.IncompatibleObjectVersion 923ReadOnlyFieldError = obj_exc.ReadOnlyFieldError 924ObjectActionError = obj_exc.ObjectActionError 925ObjectFieldInvalid = obj_exc.ObjectFieldInvalid 926 927 928class CappedVersionUnknown(CinderException): 929 message = _("Unrecoverable Error: Versioned Objects in DB are capped to " 930 "unknown version %(version)s. Most likely your environment " 931 "contains only new services and you're trying to start an " 932 "older one. Use `cinder-manage service list` to check that " 933 "and upgrade this service.") 934 935 936class VolumeGroupNotFound(CinderException): 937 message = _('Unable to find Volume Group: %(vg_name)s') 938 939 940class VolumeGroupCreationFailed(CinderException): 941 message = _('Failed to create Volume Group: %(vg_name)s') 942 943 944class VolumeNotDeactivated(CinderException): 945 message = _('Volume %(name)s was not deactivated in time.') 946 947 948class VolumeDeviceNotFound(CinderException): 949 message = _('Volume device not found at %(device)s.') 950 951 952# Driver specific exceptions 953# Dell 954class DellDriverRetryableException(VolumeBackendAPIException): 955 message = _("Retryable Dell Exception encountered") 956 957 958class DellDriverUnknownSpec(VolumeDriverException): 959 message = _("Dell driver failure: %(reason)s") 960 961 962# Pure Storage 963class PureDriverException(VolumeDriverException): 964 message = _("Pure Storage Cinder driver failure: %(reason)s") 965 966 967class PureRetryableException(VolumeBackendAPIException): 968 message = _("Retryable Pure Storage Exception encountered") 969 970 971# SolidFire 972class SolidFireAPIException(VolumeBackendAPIException): 973 message = _("Bad response from SolidFire API") 974 975 976class SolidFireDriverException(VolumeDriverException): 977 message = _("SolidFire Cinder Driver exception") 978 979 980class SolidFireAPIDataException(SolidFireAPIException): 981 message = _("Error in SolidFire API response: data=%(data)s") 982 983 984class SolidFireAccountNotFound(SolidFireDriverException): 985 message = _("Unable to locate account %(account_name)s on " 986 "Solidfire device") 987 988 989class SolidFireRetryableException(VolumeBackendAPIException): 990 message = _("Retryable SolidFire Exception encountered") 991 992 993# HP 3Par 994class Invalid3PARDomain(VolumeDriverException): 995 message = _("Invalid 3PAR Domain: %(err)s") 996 997 998# RemoteFS drivers 999class RemoteFSException(VolumeDriverException): 1000 message = _("Unknown RemoteFS exception") 1001 1002 1003class RemoteFSConcurrentRequest(RemoteFSException): 1004 message = _("A concurrent, possibly contradictory, request " 1005 "has been made.") 1006 1007 1008class RemoteFSNoSharesMounted(RemoteFSException): 1009 message = _("No mounted shares found") 1010 1011 1012class RemoteFSNoSuitableShareFound(RemoteFSException): 1013 message = _("There is no share which can host %(volume_size)sG") 1014 1015 1016class RemoteFSInvalidBackingFile(VolumeDriverException): 1017 message = _("File %(path)s has invalid backing file %(backing_file)s.") 1018 1019 1020# NFS driver 1021class NfsException(RemoteFSException): 1022 message = _("Unknown NFS exception") 1023 1024 1025class NfsNoSharesMounted(RemoteFSNoSharesMounted): 1026 message = _("No mounted NFS shares found") 1027 1028 1029class NfsNoSuitableShareFound(RemoteFSNoSuitableShareFound): 1030 message = _("There is no share which can host %(volume_size)sG") 1031 1032 1033# Smbfs driver 1034class SmbfsException(RemoteFSException): 1035 message = _("Unknown SMBFS exception.") 1036 1037 1038class SmbfsNoSharesMounted(RemoteFSNoSharesMounted): 1039 message = _("No mounted SMBFS shares found.") 1040 1041 1042class SmbfsNoSuitableShareFound(RemoteFSNoSuitableShareFound): 1043 message = _("There is no share which can host %(volume_size)sG.") 1044 1045 1046# Virtuozzo Storage Driver 1047 1048class VzStorageException(RemoteFSException): 1049 message = _("Unknown Virtuozzo Storage exception") 1050 1051 1052class VzStorageNoSharesMounted(RemoteFSNoSharesMounted): 1053 message = _("No mounted Virtuozzo Storage shares found") 1054 1055 1056class VzStorageNoSuitableShareFound(RemoteFSNoSuitableShareFound): 1057 message = _("There is no share which can host %(volume_size)sG") 1058 1059 1060# Fibre Channel Zone Manager 1061class ZoneManagerException(CinderException): 1062 message = _("Fibre Channel connection control failure: %(reason)s") 1063 1064 1065class FCZoneDriverException(CinderException): 1066 message = _("Fibre Channel Zone operation failed: %(reason)s") 1067 1068 1069class FCSanLookupServiceException(CinderException): 1070 message = _("Fibre Channel SAN Lookup failure: %(reason)s") 1071 1072 1073class ZoneManagerNotInitialized(CinderException): 1074 message = _("Fibre Channel Zone Manager not initialized") 1075 1076 1077class BrocadeZoningCliException(CinderException): 1078 message = _("Brocade Fibre Channel Zoning CLI error: %(reason)s") 1079 1080 1081class BrocadeZoningHttpException(CinderException): 1082 message = _("Brocade Fibre Channel Zoning HTTP error: %(reason)s") 1083 1084 1085class CiscoZoningCliException(CinderException): 1086 message = _("Cisco Fibre Channel Zoning CLI error: %(reason)s") 1087 1088 1089class NetAppDriverException(VolumeDriverException): 1090 message = _("NetApp Cinder Driver exception.") 1091 1092 1093class EMCVnxCLICmdError(VolumeBackendAPIException): 1094 message = _("EMC VNX Cinder Driver CLI exception: %(cmd)s " 1095 "(Return Code: %(rc)s) (Output: %(out)s).") 1096 1097 1098class EMCSPUnavailableException(EMCVnxCLICmdError): 1099 message = _("EMC VNX Cinder Driver SPUnavailableException: %(cmd)s " 1100 "(Return Code: %(rc)s) (Output: %(out)s).") 1101 1102 1103# ConsistencyGroup 1104class ConsistencyGroupNotFound(NotFound): 1105 message = _("ConsistencyGroup %(consistencygroup_id)s could not be found.") 1106 1107 1108class InvalidConsistencyGroup(Invalid): 1109 message = _("Invalid ConsistencyGroup: %(reason)s") 1110 1111 1112# Group 1113class GroupNotFound(NotFound): 1114 message = _("Group %(group_id)s could not be found.") 1115 1116 1117class InvalidGroup(Invalid): 1118 message = _("Invalid Group: %(reason)s") 1119 1120 1121class InvalidGroupStatus(Invalid): 1122 message = _("Invalid Group Status: %(reason)s") 1123 1124 1125# CgSnapshot 1126class CgSnapshotNotFound(NotFound): 1127 message = _("CgSnapshot %(cgsnapshot_id)s could not be found.") 1128 1129 1130class InvalidCgSnapshot(Invalid): 1131 message = _("Invalid CgSnapshot: %(reason)s") 1132 1133 1134# GroupSnapshot 1135class GroupSnapshotNotFound(NotFound): 1136 message = _("GroupSnapshot %(group_snapshot_id)s could not be found.") 1137 1138 1139class InvalidGroupSnapshot(Invalid): 1140 message = _("Invalid GroupSnapshot: %(reason)s") 1141 1142 1143class InvalidGroupSnapshotStatus(Invalid): 1144 message = _("Invalid GroupSnapshot Status: %(reason)s") 1145 1146 1147# Datera driver 1148class DateraAPIException(VolumeBackendAPIException): 1149 message = _("Bad response from Datera API") 1150 1151 1152# Target drivers 1153class ISCSITargetCreateFailed(CinderException): 1154 message = _("Failed to create iscsi target for volume %(volume_id)s.") 1155 1156 1157class ISCSITargetRemoveFailed(CinderException): 1158 message = _("Failed to remove iscsi target for volume %(volume_id)s.") 1159 1160 1161class ISCSITargetAttachFailed(CinderException): 1162 message = _("Failed to attach iSCSI target for volume %(volume_id)s.") 1163 1164 1165class ISCSITargetDetachFailed(CinderException): 1166 message = _("Failed to detach iSCSI target for volume %(volume_id)s.") 1167 1168 1169class TargetUpdateFailed(CinderException): 1170 message = _("Failed to update target for volume %(volume_id)s.") 1171 1172 1173class ISCSITargetHelperCommandFailed(CinderException): 1174 message = "%(error_message)s" 1175 1176 1177class BadHTTPResponseStatus(VolumeDriverException): 1178 message = _("Bad HTTP response status %(status)s") 1179 1180 1181class BadResetResourceStatus(CinderException): 1182 message = _("Bad reset resource status : %(message)s") 1183 1184 1185# ZADARA STORAGE VPSA driver exception 1186class ZadaraServerCreateFailure(VolumeDriverException): 1187 message = _("Unable to create server object for initiator %(name)s") 1188 1189 1190class ZadaraServerNotFound(NotFound): 1191 message = _("Unable to find server object for initiator %(name)s") 1192 1193 1194class ZadaraVPSANoActiveController(VolumeDriverException): 1195 message = _("Unable to find any active VPSA controller") 1196 1197 1198class ZadaraAttachmentsNotFound(NotFound): 1199 message = _("Failed to retrieve attachments for volume %(name)s") 1200 1201 1202class ZadaraInvalidAttachmentInfo(Invalid): 1203 message = _("Invalid attachment info for volume %(name)s: %(reason)s") 1204 1205 1206class ZadaraVolumeNotFound(VolumeDriverException): 1207 message = "%(reason)s" 1208 1209 1210# ZFSSA NFS driver exception. 1211class WebDAVClientError(VolumeDriverException): 1212 message = _("The WebDAV request failed. Reason: %(msg)s, " 1213 "Return code/reason: %(code)s, Source Volume: %(src)s, " 1214 "Destination Volume: %(dst)s, Method: %(method)s.") 1215 1216 1217# XtremIO Drivers 1218class XtremIOAlreadyMappedError(VolumeDriverException): 1219 message = _("Volume to Initiator Group mapping already exists") 1220 1221 1222class XtremIOArrayBusy(VolumeDriverException): 1223 message = _("System is busy, retry operation.") 1224 1225 1226class XtremIOSnapshotsLimitExceeded(VolumeDriverException): 1227 message = _("Exceeded the limit of snapshots per volume") 1228 1229 1230# StorPool driver 1231class StorPoolConfigurationInvalid(CinderException): 1232 message = _("Invalid parameter %(param)s in the %(section)s section " 1233 "of the /etc/storpool.conf file: %(error)s") 1234 1235 1236# DOTHILL drivers 1237class DotHillInvalidBackend(VolumeDriverException): 1238 message = _("Backend doesn't exist (%(backend)s)") 1239 1240 1241class DotHillConnectionError(VolumeDriverException): 1242 message = "%(message)s" 1243 1244 1245class DotHillAuthenticationError(VolumeDriverException): 1246 message = "%(message)s" 1247 1248 1249class DotHillNotEnoughSpace(VolumeDriverException): 1250 message = _("Not enough space on backend (%(backend)s)") 1251 1252 1253class DotHillRequestError(VolumeDriverException): 1254 message = "%(message)s" 1255 1256 1257class DotHillNotTargetPortal(VolumeDriverException): 1258 message = _("No active iSCSI portals with supplied iSCSI IPs") 1259 1260 1261class DotHillDriverNotSupported(VolumeDriverException): 1262 message = _("The Dot Hill driver is no longer supported.") 1263 1264 1265# Sheepdog 1266class SheepdogError(VolumeBackendAPIException): 1267 message = _("An error has occurred in SheepdogDriver. " 1268 "(Reason: %(reason)s)") 1269 1270 1271class SheepdogCmdError(SheepdogError): 1272 message = _("(Command: %(cmd)s) " 1273 "(Return Code: %(exit_code)s) " 1274 "(Stdout: %(stdout)s) " 1275 "(Stderr: %(stderr)s)") 1276 1277 1278class MetadataAbsent(CinderException): 1279 message = _("There is no metadata in DB object.") 1280 1281 1282class NotSupportedOperation(Invalid): 1283 message = _("Operation not supported: %(operation)s.") 1284 code = 405 1285 1286 1287# NexentaStor driver exception 1288class NexentaException(VolumeDriverException): 1289 message = "%(message)s" 1290 1291 1292# Google Cloud Storage(GCS) backup driver 1293class GCSConnectionFailure(BackupDriverException): 1294 message = _("Google Cloud Storage connection failure: %(reason)s") 1295 1296 1297class GCSApiFailure(BackupDriverException): 1298 message = _("Google Cloud Storage api failure: %(reason)s") 1299 1300 1301class GCSOAuth2Failure(BackupDriverException): 1302 message = _("Google Cloud Storage oauth2 failure: %(reason)s") 1303 1304 1305# Kaminario K2 1306class KaminarioCinderDriverException(VolumeDriverException): 1307 message = _("KaminarioCinderDriver failure: %(reason)s") 1308 1309 1310class KaminarioRetryableException(VolumeDriverException): 1311 message = _("Kaminario retryable exception: %(reason)s") 1312 1313 1314# Synology driver 1315class SynoAPIHTTPError(VolumeDriverException): 1316 message = _("HTTP exit code: [%(code)s]") 1317 1318 1319class SynoAuthError(VolumeDriverException): 1320 message = _("Synology driver authentication failed: %(reason)s.") 1321 1322 1323class SynoLUNNotExist(VolumeDriverException): 1324 message = _("LUN not found by UUID: %(uuid)s.") 1325 1326 1327class AttachmentSpecsNotFound(NotFound): 1328 message = _("Attachment %(attachment_id)s has no " 1329 "key %(specs_key)s.") 1330 1331 1332class InvalidAttachment(Invalid): 1333 message = _("Invalid attachment: %(reason)s") 1334 1335 1336# Veritas driver 1337class UnableToExecuteHyperScaleCmd(VolumeDriverException): 1338 message = _("Failed HyperScale command for '%(message)s'") 1339 1340 1341class UnableToProcessHyperScaleCmdOutput(VolumeDriverException): 1342 message = _("Failed processing command output '%(cmd_out)s'" 1343 " for HyperScale command") 1344 1345 1346class ErrorInFetchingConfiguration(VolumeDriverException): 1347 message = _("Error in fetching configuration for '%(persona)s'") 1348 1349 1350class ErrorInSendingMsg(VolumeDriverException): 1351 message = _("Error in sending message '%(cmd_error)s'") 1352 1353 1354class ErrorInHyperScaleVersion(VolumeDriverException): 1355 message = _("Error in getting HyperScale version '%(cmd_error)s'") 1356 1357 1358class ErrorInParsingArguments(VolumeDriverException): 1359 message = _("Error in parsing message arguments : Invalid Payload") 1360 1361 1362# GPFS driver 1363class GPFSDriverUnsupportedOperation(VolumeBackendAPIException): 1364 message = _("GPFS driver unsupported operation: %(msg)s") 1365 1366 1367class InvalidName(Invalid): 1368 message = _("An invalid 'name' value was provided. %(reason)s") 1369 1370 1371class ServiceUserTokenNoAuth(CinderException): 1372 message = _("The [service_user] send_service_user_token option was " 1373 "requested, but no service auth could be loaded. Please check " 1374 "the [service_user] configuration section.") 1375