Merge lp:~jaypipes/glance/bug726685 into lp:~glance-coresec/glance/cactus-trunk

Proposed by Jay Pipes
Status: Merged
Approved by: Rick Harris
Approved revision: 99
Merged at revision: 107
Proposed branch: lp:~jaypipes/glance/bug726685
Merge into: lp:~glance-coresec/glance/cactus-trunk
Diff against target: 319 lines (+218/-13)
9 files modified
glance/registry/db/api.py (+5/-5)
glance/registry/db/migrate_repo/versions/006_key_to_name.py (+93/-0)
glance/registry/db/migrate_repo/versions/006_mysql_downgrade.sql (+11/-0)
glance/registry/db/migrate_repo/versions/006_mysql_upgrade.sql (+11/-0)
glance/registry/db/migrate_repo/versions/006_sqlite_downgrade.sql (+46/-0)
glance/registry/db/migrate_repo/versions/006_sqlite_upgrade.sql (+46/-0)
glance/registry/db/models.py (+2/-4)
glance/registry/server.py (+1/-1)
tests/stubs.py (+3/-3)
To merge this branch: bzr merge lp:~jaypipes/glance/bug726685
Reviewer Review Type Date Requested Status
Rick Harris (community) Approve
Glance Core security contacts Pending
Review via email: mp+56252@code.launchpad.net

Commit message

Changes "key" column in image_properties to "name".

Description of the change

Changes "key" column in image_properties to "name".

As with all things migration, this was a pain in the ass.

MySQL doesn't support RENAME INDEX, so a custom SQL migration
file for it was needed.

Likewise, SQLite doesn't support either RENAME INDEX or
ALTER TABLE CHANGE COLUMN, so it also needed a custom migration
script.

To post a comment you must log in.
Revision history for this message
Rick Harris (rconradharris) wrote :

Impressive work with the migrations to make this work out. Really nice job.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'glance/registry/db/api.py'
--- glance/registry/db/api.py 2011-04-06 15:17:34 +0000
+++ glance/registry/db/api.py 2011-04-07 19:09:30 +0000
@@ -251,14 +251,14 @@
251 """251 """
252 orig_properties = {}252 orig_properties = {}
253 for prop_ref in image_ref.properties:253 for prop_ref in image_ref.properties:
254 orig_properties[prop_ref.key] = prop_ref254 orig_properties[prop_ref.name] = prop_ref
255255
256 for key, value in properties.iteritems():256 for name, value in properties.iteritems():
257 prop_values = {'image_id': image_ref.id,257 prop_values = {'image_id': image_ref.id,
258 'key': key,258 'name': name,
259 'value': value}259 'value': value}
260 if key in orig_properties:260 if name in orig_properties:
261 prop_ref = orig_properties[key]261 prop_ref = orig_properties[name]
262 image_property_update(context, prop_ref, prop_values,262 image_property_update(context, prop_ref, prop_values,
263 session=session)263 session=session)
264 else:264 else:
265265
=== added file 'glance/registry/db/migrate_repo/versions/006_key_to_name.py'
--- glance/registry/db/migrate_repo/versions/006_key_to_name.py 1970-01-01 00:00:00 +0000
+++ glance/registry/db/migrate_repo/versions/006_key_to_name.py 2011-04-07 19:09:30 +0000
@@ -0,0 +1,93 @@
1# vim: tabstop=4 shiftwidth=4 softtabstop=4
2
3# Copyright 2011 OpenStack LLC.
4# All Rights Reserved.
5#
6# Licensed under the Apache License, Version 2.0 (the "License"); you may
7# not use this file except in compliance with the License. You may obtain
8# a copy of the License at
9#
10# http://www.apache.org/licenses/LICENSE-2.0
11#
12# Unless required by applicable law or agreed to in writing, software
13# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15# License for the specific language governing permissions and limitations
16# under the License.
17
18from migrate.changeset import *
19from sqlalchemy import *
20from sqlalchemy.sql import and_, not_
21
22from glance.registry.db.migrate_repo.schema import (
23 Boolean, DateTime, Integer, String, Text, from_migration_import)
24
25
26def get_images_table(meta):
27 """
28 No changes to the image properties table from 002...
29 """
30 (get_images_table,) = from_migration_import(
31 '004_add_checksum', ['get_images_table'])
32
33 images = get_images_table(meta)
34 return images
35
36
37def get_image_properties_table(meta):
38 """
39 Returns the Table object for the image_properties table that
40 corresponds to the image_properties table definition of this version.
41 """
42 (get_images_table,) = from_migration_import(
43 '004_add_checksum', ['get_images_table'])
44
45 images = get_images_table(meta)
46
47 image_properties = Table('image_properties', meta,
48 Column('id', Integer(), primary_key=True, nullable=False),
49 Column('image_id', Integer(), ForeignKey('images.id'), nullable=False,
50 index=True),
51 Column('name', String(255), nullable=False),
52 Column('value', Text()),
53 Column('created_at', DateTime(), nullable=False),
54 Column('updated_at', DateTime()),
55 Column('deleted_at', DateTime()),
56 Column('deleted', Boolean(), nullable=False, default=False,
57 index=True),
58 UniqueConstraint('image_id', 'name'),
59 mysql_engine='InnoDB',
60 useexisting=True)
61
62 return image_properties
63
64
65def upgrade(migrate_engine):
66 meta = MetaData()
67 meta.bind = migrate_engine
68
69 (get_image_properties_table,) = from_migration_import(
70 '004_add_checksum', ['get_image_properties_table'])
71 image_properties = get_image_properties_table(meta)
72
73 index = Index('ix_image_properties_image_id_get',
74 image_properties.c.image_id,
75 image_properties.c.key)
76 index.rename('ix_image_properties_image_id_name')
77
78 image_properties = get_image_properties_table(meta)
79 image_properties.columns['key'].alter(name="name")
80
81
82def downgrade(migrate_engine):
83 meta = MetaData()
84 meta.bind = migrate_engine
85
86 image_properties = get_image_properties_table(meta)
87
88 index = Index('ix_image_properties_image_id_name',
89 image_properties.c.image_id,
90 image_properties.c.name)
91 index.rename('ix_image_properties_image_id_key')
92
93 image_properties.columns['name'].alter(name="key")
094
=== added file 'glance/registry/db/migrate_repo/versions/006_mysql_downgrade.sql'
--- glance/registry/db/migrate_repo/versions/006_mysql_downgrade.sql 1970-01-01 00:00:00 +0000
+++ glance/registry/db/migrate_repo/versions/006_mysql_downgrade.sql 2011-04-07 19:09:30 +0000
@@ -0,0 +1,11 @@
1/*
2 * This file is necessary because MySQL does not support
3 * renaming indexes.
4 */
5DROP INDEX ix_image_properties_image_id_name ON image_properties;
6
7/* Rename the `key` column to `name` */
8ALTER TABLE image_properties
9CHANGE COLUMN name `key` VARCHAR(255) NOT NULL;
10
11CREATE UNIQUE INDEX ix_image_properties_image_id_key ON image_properties (image_id, key);
012
=== added file 'glance/registry/db/migrate_repo/versions/006_mysql_upgrade.sql'
--- glance/registry/db/migrate_repo/versions/006_mysql_upgrade.sql 1970-01-01 00:00:00 +0000
+++ glance/registry/db/migrate_repo/versions/006_mysql_upgrade.sql 2011-04-07 19:09:30 +0000
@@ -0,0 +1,11 @@
1/*
2 * This file is necessary because MySQL does not support
3 * renaming indexes.
4 */
5DROP INDEX ix_image_properties_image_id_key ON image_properties;
6
7/* Rename the `key` column to `name` */
8ALTER TABLE image_properties
9CHANGE COLUMN `key` name VARCHAR(255) NOT NULL;
10
11CREATE UNIQUE INDEX ix_image_properties_image_id_name ON image_properties (image_id, name);
012
=== added file 'glance/registry/db/migrate_repo/versions/006_sqlite_downgrade.sql'
--- glance/registry/db/migrate_repo/versions/006_sqlite_downgrade.sql 1970-01-01 00:00:00 +0000
+++ glance/registry/db/migrate_repo/versions/006_sqlite_downgrade.sql 2011-04-07 19:09:30 +0000
@@ -0,0 +1,46 @@
1/*
2 * This is necessary because SQLite does not support
3 * RENAME INDEX or ALTER TABLE CHANGE COLUMN.
4 */
5BEGIN TRANSACTION;
6
7CREATE TEMPORARY TABLE image_properties_backup (
8 id INTEGER NOT NULL,
9 image_id INTEGER NOT NULL,
10 key VARCHAR(255) NOT NULL,
11 value TEXT,
12 created_at DATETIME NOT NULL,
13 updated_at DATETIME,
14 deleted_at DATETIME,
15 deleted BOOLEAN NOT NULL,
16 PRIMARY KEY (id)
17);
18
19INSERT INTO image_properties_backup
20SELECT id, image_id, name, value, created_at, updated_at, deleted_at, deleted
21FROM image_properties;
22
23DROP TABLE image_properties;
24
25CREATE TABLE image_properties (
26 id INTEGER NOT NULL,
27 image_id INTEGER NOT NULL,
28 key VARCHAR(255) NOT NULL,
29 value TEXT,
30 created_at DATETIME NOT NULL,
31 updated_at DATETIME,
32 deleted_at DATETIME,
33 deleted BOOLEAN NOT NULL,
34 PRIMARY KEY (id),
35 CHECK (deleted IN (0, 1)),
36 UNIQUE (image_id, key),
37 FOREIGN KEY(image_id) REFERENCES images (id)
38);
39CREATE INDEX ix_image_properties_key ON image_properties (key);
40
41INSERT INTO image_properties (id, image_id, key, value, created_at, updated_at, deleted_at, deleted)
42SELECT id, image_id, key, value, created_at, updated_at, deleted_at, deleted
43FROM image_properties_backup;
44
45DROP TABLE image_properties_backup;
46COMMIT;
047
=== added file 'glance/registry/db/migrate_repo/versions/006_sqlite_upgrade.sql'
--- glance/registry/db/migrate_repo/versions/006_sqlite_upgrade.sql 1970-01-01 00:00:00 +0000
+++ glance/registry/db/migrate_repo/versions/006_sqlite_upgrade.sql 2011-04-07 19:09:30 +0000
@@ -0,0 +1,46 @@
1/*
2 * This is necessary because SQLite does not support
3 * RENAME INDEX or ALTER TABLE CHANGE COLUMN.
4 */
5BEGIN TRANSACTION;
6
7CREATE TEMPORARY TABLE image_properties_backup (
8 id INTEGER NOT NULL,
9 image_id INTEGER NOT NULL,
10 name VARCHAR(255) NOT NULL,
11 value TEXT,
12 created_at DATETIME NOT NULL,
13 updated_at DATETIME,
14 deleted_at DATETIME,
15 deleted BOOLEAN NOT NULL,
16 PRIMARY KEY (id)
17);
18
19INSERT INTO image_properties_backup
20SELECT id, image_id, key, value, created_at, updated_at, deleted_at, deleted
21FROM image_properties;
22
23DROP TABLE image_properties;
24
25CREATE TABLE image_properties (
26 id INTEGER NOT NULL,
27 image_id INTEGER NOT NULL,
28 name VARCHAR(255) NOT NULL,
29 value TEXT,
30 created_at DATETIME NOT NULL,
31 updated_at DATETIME,
32 deleted_at DATETIME,
33 deleted BOOLEAN NOT NULL,
34 PRIMARY KEY (id),
35 CHECK (deleted IN (0, 1)),
36 UNIQUE (image_id, name),
37 FOREIGN KEY(image_id) REFERENCES images (id)
38);
39CREATE INDEX ix_image_properties_name ON image_properties (name);
40
41INSERT INTO image_properties (id, image_id, name, value, created_at, updated_at, deleted_at, deleted)
42SELECT id, image_id, name, value, created_at, updated_at, deleted_at, deleted
43FROM image_properties_backup;
44
45DROP TABLE image_properties_backup;
46COMMIT;
047
=== modified file 'glance/registry/db/models.py'
--- glance/registry/db/models.py 2011-03-31 14:43:28 +0000
+++ glance/registry/db/models.py 2011-04-07 19:09:30 +0000
@@ -110,13 +110,11 @@
110class ImageProperty(BASE, ModelBase):110class ImageProperty(BASE, ModelBase):
111 """Represents an image properties in the datastore"""111 """Represents an image properties in the datastore"""
112 __tablename__ = 'image_properties'112 __tablename__ = 'image_properties'
113 __table_args__ = (UniqueConstraint('image_id', 'key'), {})113 __table_args__ = (UniqueConstraint('image_id', 'name'), {})
114114
115 id = Column(Integer, primary_key=True)115 id = Column(Integer, primary_key=True)
116 image_id = Column(Integer, ForeignKey('images.id'), nullable=False)116 image_id = Column(Integer, ForeignKey('images.id'), nullable=False)
117 image = relationship(Image, backref=backref('properties'))117 image = relationship(Image, backref=backref('properties'))
118118
119 # FIXME(sirp): KEY is a reserved word in SQL, might be a good idea to119 name = Column(String(255), index=True, nullable=False)
120 # rename this column
121 key = Column(String(255), index=True, nullable=False)
122 value = Column(Text)120 value = Column(Text)
123121
=== modified file 'glance/registry/server.py'
--- glance/registry/server.py 2011-03-29 14:27:24 +0000
+++ glance/registry/server.py 2011-04-07 19:09:30 +0000
@@ -204,7 +204,7 @@
204 # TODO(sirp): should this be a dict, or a list of dicts?204 # TODO(sirp): should this be a dict, or a list of dicts?
205 # A plain dict is more convenient, but list of dicts would provide205 # A plain dict is more convenient, but list of dicts would provide
206 # access to created_at, etc206 # access to created_at, etc
207 properties = dict((p['key'], p['value'])207 properties = dict((p['name'], p['value'])
208 for p in image['properties'] if not p['deleted'])208 for p in image['properties'] if not p['deleted'])
209209
210 image_dict = _fetch_attrs(image, db_api.IMAGE_ATTRS)210 image_dict = _fetch_attrs(image, db_api.IMAGE_ATTRS)
211211
=== modified file 'tests/stubs.py'
--- tests/stubs.py 2011-04-04 14:32:14 +0000
+++ tests/stubs.py 2011-04-07 19:09:30 +0000
@@ -285,7 +285,7 @@
285 'checksum': None,285 'checksum': None,
286 'size': 13,286 'size': 13,
287 'location': "swift://user:passwd@acct/container/obj.tar.0",287 'location': "swift://user:passwd@acct/container/obj.tar.0",
288 'properties': [{'key': 'type',288 'properties': [{'name': 'type',
289 'value': 'kernel',289 'value': 'kernel',
290 'deleted': False}]},290 'deleted': False}]},
291 {'id': 2,291 {'id': 2,
@@ -331,7 +331,7 @@
331 if 'properties' in values.keys():331 if 'properties' in values.keys():
332 for k, v in values['properties'].items():332 for k, v in values['properties'].items():
333 p = {}333 p = {}
334 p['key'] = k334 p['name'] = k
335 p['value'] = v335 p['value'] = v
336 p['deleted'] = False336 p['deleted'] = False
337 p['created_at'] = datetime.datetime.utcnow()337 p['created_at'] = datetime.datetime.utcnow()
@@ -358,7 +358,7 @@
358 if 'properties' in values.keys():358 if 'properties' in values.keys():
359 for k, v in values['properties'].items():359 for k, v in values['properties'].items():
360 p = {}360 p = {}
361 p['key'] = k361 p['name'] = k
362 p['value'] = v362 p['value'] = v
363 p['deleted'] = False363 p['deleted'] = False
364 p['created_at'] = datetime.datetime.utcnow()364 p['created_at'] = datetime.datetime.utcnow()

Subscribers

People subscribed via source and target branches