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 |
|