components/openstack/cinder/patches/06-launchpad-1233763.patch
changeset 4063 12e03e5492b8
parent 4062 f45bb9cec48c
parent 4061 5ac5027dc3e3
equal deleted inserted replaced
4062:f45bb9cec48c 4063:12e03e5492b8
     1 Although the following patch has been addressed in Icehouse 2014.1, it
       
     2 still has not yet been released for Havana.
       
     3 
       
     4 From c1fca7affc22dc756f07f604f03c2343eeac9d15 Mon Sep 17 00:00:00 2001
       
     5 From: "Jay S. Bryant" <[email protected]>
       
     6 Date: Fri, 15 Nov 2013 19:01:58 -0600
       
     7 Subject: [PATCH] Add default quota class into DB during migration
       
     8 
       
     9 For some time now use_default_quota_class has been the
       
    10 default setting for Cinder.  Cinder, however, has not been putting
       
    11 any defaults for the default quota class into the database.  This
       
    12 resulted in any command that queried for the default quotas to cause
       
    13 the message "Deprecated: Default quota for resource: <resource> is set
       
    14 by the default quota flag: <quota flag>, it is now deprecated.  Please use
       
    15 the default quota class for default quota."
       
    16 
       
    17 This commit resolves this issue by setting the default value for volumes,
       
    18 snapshots and gigabytes in the quota_class table at migration time if there
       
    19 is not already a class_name of 'default' in the quota_classes table.
       
    20 
       
    21 Unit tests are included with this commit.
       
    22 
       
    23 Closes-bug 1233763
       
    24 Change-Id: I457ed8a9b78492eda22e31dfc198b2ee051d3ece
       
    25 (cherry picked from commit 7d2641688454d9064b691e4aab4b5d8b14d75305)
       
    26 ---
       
    27  .../versions/021_add_default_quota_class.py        |   85 ++++++++++++++++++++
       
    28  cinder/tests/test_migrations.py                    |   31 +++++++
       
    29  cinder/tests/test_quota.py                         |    5 ++
       
    30  3 files changed, 121 insertions(+)
       
    31  create mode 100644 cinder/db/sqlalchemy/migrate_repo/versions/021_add_default_quota_class.py
       
    32 
       
    33 diff --git a/cinder/db/sqlalchemy/migrate_repo/versions/021_add_default_quota_class.py b/cinder/db/sqlalchemy/migrate_repo/versions/021_add_default_quota_class.py
       
    34 new file mode 100644
       
    35 index 0000000..5c06e9c
       
    36 --- /dev/null
       
    37 +++ b/cinder/db/sqlalchemy/migrate_repo/versions/021_add_default_quota_class.py
       
    38 @@ -0,0 +1,85 @@
       
    39 +#    Copyright 2013 IBM Corp.
       
    40 +#
       
    41 +#    Licensed under the Apache License, Version 2.0 (the "License"); you may
       
    42 +#    not use this file except in compliance with the License. You may obtain
       
    43 +#    a copy of the License at
       
    44 +#
       
    45 +#         http://www.apache.org/licenses/LICENSE-2.0
       
    46 +#
       
    47 +#    Unless required by applicable law or agreed to in writing, software
       
    48 +#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
       
    49 +#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
       
    50 +#    License for the specific language governing permissions and limitations
       
    51 +#    under the License.
       
    52 +
       
    53 +import datetime
       
    54 +
       
    55 +from cinder.openstack.common import log as logging
       
    56 +from oslo.config import cfg
       
    57 +from sqlalchemy import MetaData, Table
       
    58 +
       
    59 +# Get default values via config.  The defaults will either
       
    60 +# come from the default values set in the quota option
       
    61 +# configuration or via cinder.conf if the user has configured
       
    62 +# default values for quotas there.
       
    63 +CONF = cfg.CONF
       
    64 +CONF.import_opt('quota_volumes', 'cinder.quota')
       
    65 +CONF.import_opt('quota_snapshots', 'cinder.quota')
       
    66 +CONF.import_opt('quota_gigabytes', 'cinder.quota')
       
    67 +LOG = logging.getLogger(__name__)
       
    68 +
       
    69 +CLASS_NAME = 'default'
       
    70 +CREATED_AT = datetime.datetime.now()
       
    71 +
       
    72 +
       
    73 +def upgrade(migrate_engine):
       
    74 +    """Add default quota class data into DB."""
       
    75 +    meta = MetaData()
       
    76 +    meta.bind = migrate_engine
       
    77 +
       
    78 +    quota_classes = Table('quota_classes', meta, autoload=True)
       
    79 +
       
    80 +    rows = quota_classes.count().\
       
    81 +        where(quota_classes.c.class_name == 'default').execute().scalar()
       
    82 +
       
    83 +    # Do not add entries if there are already 'default' entries.  We don't
       
    84 +    # want to write over something the user added.
       
    85 +    if rows:
       
    86 +        LOG.info(_("Found existing 'default' entries in the quota_classes "
       
    87 +                   "table.  Skipping insertion of default values."))
       
    88 +        return
       
    89 +
       
    90 +    try:
       
    91 +        #Set default volumes
       
    92 +        qci = quota_classes.insert()
       
    93 +        qci.execute({'created_at': CREATED_AT,
       
    94 +                     'class_name': CLASS_NAME,
       
    95 +                     'resource': 'volumes',
       
    96 +                     'hard_limit': CONF.quota_volumes,
       
    97 +                     'deleted': False, })
       
    98 +        #Set default snapshots
       
    99 +        qci.execute({'created_at': CREATED_AT,
       
   100 +                     'class_name': CLASS_NAME,
       
   101 +                     'resource': 'snapshots',
       
   102 +                     'hard_limit': CONF.quota_snapshots,
       
   103 +                     'deleted': False, })
       
   104 +        #Set default gigabytes
       
   105 +        qci.execute({'created_at': CREATED_AT,
       
   106 +                     'class_name': CLASS_NAME,
       
   107 +                     'resource': 'gigabytes',
       
   108 +                     'hard_limit': CONF.quota_gigabytes,
       
   109 +                     'deleted': False, })
       
   110 +        LOG.info(_("Added default quota class data into the DB."))
       
   111 +    except Exception:
       
   112 +        LOG.error(_("Default quota class data not inserted into the DB."))
       
   113 +        raise
       
   114 +
       
   115 +
       
   116 +def downgrade(migrate_engine):
       
   117 +    """Don't delete the 'default' entries at downgrade time.
       
   118 +
       
   119 +    We don't know if the user had default entries when we started.
       
   120 +    If they did, we wouldn't want to remove them.  So, the safest
       
   121 +    thing to do is just leave the 'default' entries at downgrade time.
       
   122 +    """
       
   123 +    pass
       
   124 diff --git a/cinder/tests/test_migrations.py b/cinder/tests/test_migrations.py
       
   125 index 257c3e8..2ef5bff 100644
       
   126 --- a/cinder/tests/test_migrations.py
       
   127 +++ b/cinder/tests/test_migrations.py
       
   128 @@ -1002,3 +1002,34 @@ class TestMigrations(test.TestCase):
       
   129  
       
   130              self.assertFalse(engine.dialect.has_table(engine.connect(),
       
   131                                                        "volume_admin_metadata"))
       
   132 +
       
   133 +    def test_migration_021(self):
       
   134 +        """Test adding default data for quota classes works correctly."""
       
   135 +        for (key, engine) in self.engines.items():
       
   136 +            migration_api.version_control(engine,
       
   137 +                                          TestMigrations.REPOSITORY,
       
   138 +                                          migration.INIT_VERSION)
       
   139 +            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 20)
       
   140 +            metadata = sqlalchemy.schema.MetaData()
       
   141 +            metadata.bind = engine
       
   142 +
       
   143 +            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 21)
       
   144 +
       
   145 +            quota_class_metadata = sqlalchemy.Table('quota_classes',
       
   146 +                                                    metadata,
       
   147 +                                                    autoload=True)
       
   148 +
       
   149 +            num_defaults = quota_class_metadata.count().\
       
   150 +                where(quota_class_metadata.c.class_name == 'default').\
       
   151 +                execute().scalar()
       
   152 +
       
   153 +            self.assertEqual(3, num_defaults)
       
   154 +
       
   155 +            migration_api.downgrade(engine, TestMigrations.REPOSITORY, 20)
       
   156 +
       
   157 +            # Defaults should not be deleted during downgrade
       
   158 +            num_defaults = quota_class_metadata.count().\
       
   159 +                where(quota_class_metadata.c.class_name == 'default').\
       
   160 +                execute().scalar()
       
   161 +
       
   162 +            self.assertEqual(3, num_defaults)
       
   163 diff --git a/cinder/tests/test_quota.py b/cinder/tests/test_quota.py
       
   164 index 99b2ed2..ae79b39 100644
       
   165 --- a/cinder/tests/test_quota.py
       
   166 +++ b/cinder/tests/test_quota.py
       
   167 @@ -62,6 +62,11 @@ class QuotaIntegrationTestCase(test.TestCase):
       
   168  
       
   169          self.stubs.Set(rpc, 'call', rpc_call_wrapper)
       
   170  
       
   171 +        # Destroy the 'default' quota_class in the database to avoid
       
   172 +        # conflicts with the test cases here that are setting up their own
       
   173 +        # defaults.
       
   174 +        db.quota_class_destroy_all_by_name(self.context, 'default')
       
   175 +
       
   176      def tearDown(self):
       
   177          db.volume_type_destroy(context.get_admin_context(),
       
   178                                 self.volume_type['id'])
       
   179 -- 
       
   180 1.7.9.2
       
   181