summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwangxiyuan <wangxiyuan@huawei.com>2015-09-16 11:50:56 +0800
committerwangxiyuan <wangxiyuan@huawei.com>2016-09-01 10:53:08 +0800
commit2f803d3fa9d5870b38b195f91a146db9ef755ed1 (patch)
tree67c779ab0935ce6266b79ebedd459266c6588724
parent797a12361fa25fd483deac7f09813814309beb61 (diff)
Remove DB downgrade
As downgrade are not supported after Kilo, we should remove them now. Roll backs can be performed as mentioned in the below link: http://docs.openstack.org/ops-guide/ops-upgrades.html#rolling-back-a-failed-upgrade The DB downgrades were deprecated in Glance Mitaka release by commit e3366afdfb227794fd46cfd8b2cf553a7ff1a709. Change-Id: I937d15d93f16a3e44a50e6ff1a469098eab67c79 Implements: blueprint remove-db-downgrade
Notes
Notes (review): Code-Review+1: Hemanth Makkapati <hemanth.makkapati@rackspace.com> Code-Review+2: Nikhil Komawar <nik.komawar@gmail.com> Code-Review+2: Ian Cordasco <ian.cordasco@rackspace.com> Workflow+1: Ian Cordasco <ian.cordasco@rackspace.com> Verified+2: Jenkins Submitted-by: Jenkins Submitted-at: Thu, 01 Sep 2016 12:09:12 +0000 Reviewed-on: https://review.openstack.org/229220 Project: openstack/glance Branch: refs/heads/master
-rw-r--r--doc/source/db.rst9
-rw-r--r--doc/source/man/glancemanage.rst4
-rw-r--r--glance/cmd/manage.py25
-rw-r--r--glance/db/sqlalchemy/migrate_repo/versions/001_add_images_table.py9
-rw-r--r--glance/db/sqlalchemy/migrate_repo/versions/002_add_image_properties_table.py9
-rw-r--r--glance/db/sqlalchemy/migrate_repo/versions/003_add_disk_format.py44
-rw-r--r--glance/db/sqlalchemy/migrate_repo/versions/003_sqlite_downgrade.sql54
-rw-r--r--glance/db/sqlalchemy/migrate_repo/versions/004_add_checksum.py10
-rw-r--r--glance/db/sqlalchemy/migrate_repo/versions/005_size_big_integer.py30
-rw-r--r--glance/db/sqlalchemy/migrate_repo/versions/006_key_to_name.py69
-rw-r--r--glance/db/sqlalchemy/migrate_repo/versions/006_mysql_downgrade.sql11
-rw-r--r--glance/db/sqlalchemy/migrate_repo/versions/006_sqlite_downgrade.sql43
-rw-r--r--glance/db/sqlalchemy/migrate_repo/versions/007_add_owner.py23
-rw-r--r--glance/db/sqlalchemy/migrate_repo/versions/008_add_image_members_table.py21
-rw-r--r--glance/db/sqlalchemy/migrate_repo/versions/009_add_mindisk_and_minram.py24
-rw-r--r--glance/db/sqlalchemy/migrate_repo/versions/010_default_update_at.py37
-rw-r--r--glance/db/sqlalchemy/migrate_repo/versions/011_make_mindisk_and_minram_notnull.py7
-rw-r--r--glance/db/sqlalchemy/migrate_repo/versions/011_sqlite_downgrade.sql58
-rw-r--r--glance/db/sqlalchemy/migrate_repo/versions/012_id_to_uuid.py230
-rw-r--r--glance/db/sqlalchemy/migrate_repo/versions/013_add_protected.py7
-rw-r--r--glance/db/sqlalchemy/migrate_repo/versions/013_sqlite_downgrade.sql62
-rw-r--r--glance/db/sqlalchemy/migrate_repo/versions/014_add_image_tags_table.py7
-rw-r--r--glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py4
-rw-r--r--glance/db/sqlalchemy/migrate_repo/versions/016_add_status_image_member.py7
-rw-r--r--glance/db/sqlalchemy/migrate_repo/versions/016_sqlite_downgrade.sql43
-rw-r--r--glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py6
-rw-r--r--glance/db/sqlalchemy/migrate_repo/versions/018_add_image_locations_table.py7
-rw-r--r--glance/db/sqlalchemy/migrate_repo/versions/019_migrate_image_locations.py14
-rw-r--r--glance/db/sqlalchemy/migrate_repo/versions/020_drop_images_table_location.py9
-rw-r--r--glance/db/sqlalchemy/migrate_repo/versions/021_set_engine_mysql_innodb.py4
-rw-r--r--glance/db/sqlalchemy/migrate_repo/versions/022_image_member_index.py35
-rw-r--r--glance/db/sqlalchemy/migrate_repo/versions/023_placeholder.py4
-rw-r--r--glance/db/sqlalchemy/migrate_repo/versions/024_placeholder.py4
-rw-r--r--glance/db/sqlalchemy/migrate_repo/versions/025_placeholder.py4
-rw-r--r--glance/db/sqlalchemy/migrate_repo/versions/026_add_location_storage_information.py11
-rw-r--r--glance/db/sqlalchemy/migrate_repo/versions/027_checksum_index.py10
-rw-r--r--glance/db/sqlalchemy/migrate_repo/versions/028_owner_index.py10
-rw-r--r--glance/db/sqlalchemy/migrate_repo/versions/029_location_meta_data_pickle_to_string.py29
-rw-r--r--glance/db/sqlalchemy/migrate_repo/versions/030_add_tasks_table.py9
-rw-r--r--glance/db/sqlalchemy/migrate_repo/versions/031_remove_duplicated_locations.py6
-rw-r--r--glance/db/sqlalchemy/migrate_repo/versions/032_add_task_info_table.py29
-rw-r--r--glance/db/sqlalchemy/migrate_repo/versions/033_add_location_status.py11
-rw-r--r--glance/db/sqlalchemy/migrate_repo/versions/034_add_virtual_size.py8
-rw-r--r--glance/db/sqlalchemy/migrate_repo/versions/035_add_metadef_tables.py14
-rw-r--r--glance/db/sqlalchemy/migrate_repo/versions/036_rename_metadef_schema_columns.py9
-rw-r--r--glance/db/sqlalchemy/migrate_repo/versions/037_add_changes_to_satisfy_models.py43
-rw-r--r--glance/db/sqlalchemy/migrate_repo/versions/037_sqlite_downgrade.sql147
-rw-r--r--glance/db/sqlalchemy/migrate_repo/versions/038_add_metadef_tags_table.py9
-rw-r--r--glance/db/sqlalchemy/migrate_repo/versions/039_add_changes_to_satisfy_models_metadef.py172
-rw-r--r--glance/db/sqlalchemy/migrate_repo/versions/042_add_changes_to_reinstall_unique_metadef_constraints.py162
-rw-r--r--glance/db/sqlalchemy/migrate_repo/versions/044_update_metadef_os_nova_server.py5
-rw-r--r--glance/tests/unit/test_manage.py14
-rw-r--r--glance/tests/unit/test_migrations.py355
-rw-r--r--releasenotes/notes/remove-db-downgrade-0d1cc45b97605775.yaml11
54 files changed, 51 insertions, 1947 deletions
diff --git a/doc/source/db.rst b/doc/source/db.rst
index a84b4f4..a57052a 100644
--- a/doc/source/db.rst
+++ b/doc/source/db.rst
@@ -53,8 +53,9 @@ This will take an existing database and upgrade it to the specified VERSION.
53Downgrading an Existing Database 53Downgrading an Existing Database
54-------------------------------- 54--------------------------------
55 55
56 glance-manage db downgrade <VERSION> 56Upgrades involve complex operations and can fail. Before attempting any
57 57upgrade, you should make a full database backup of your production data. As of
58This will downgrade an existing database from the current version to the 58Kilo, database downgrades are not supported, and the only method available to
59specified VERSION. 59get back to a prior database version is to restore from backup[1].
60 60
61[1]: http://docs.openstack.org/ops-guide/ops-upgrades.html#perform-a-backup
diff --git a/doc/source/man/glancemanage.rst b/doc/source/man/glancemanage.rst
index 810ef14..921c645 100644
--- a/doc/source/man/glancemanage.rst
+++ b/doc/source/man/glancemanage.rst
@@ -50,10 +50,6 @@ COMMANDS
50 This will take an existing database and upgrade it to the 50 This will take an existing database and upgrade it to the
51 specified VERSION. 51 specified VERSION.
52 52
53 **db_downgrade <VERSION>**
54 This will take an existing database and downgrade it to the
55 specified VERSION.
56
57 **db_version_control** 53 **db_version_control**
58 Place the database under migration control. 54 Place the database under migration control.
59 55
diff --git a/glance/cmd/manage.py b/glance/cmd/manage.py
index f3ce24d..390729f 100644
--- a/glance/cmd/manage.py
+++ b/glance/cmd/manage.py
@@ -85,17 +85,6 @@ class DbCommands(object):
85 version) 85 version)
86 86
87 @args('--version', metavar='<version>', help='Database version') 87 @args('--version', metavar='<version>', help='Database version')
88 def downgrade(self, version=None):
89 """Downgrade the database's migration level"""
90 print("Warning: DB downgrade is deprecated and will be removed in N "
91 "release. Users should make a full database backup of the "
92 "production data before attempting any upgrade.",
93 file=sys.stderr)
94 migration.db_sync(db_api.get_engine(),
95 db_migration.MIGRATE_REPO_PATH,
96 version)
97
98 @args('--version', metavar='<version>', help='Database version')
99 def version_control(self, version=None): 88 def version_control(self, version=None):
100 """Place a database under migration control""" 89 """Place a database under migration control"""
101 migration.db_version_control(db_api.get_engine(), 90 migration.db_version_control(db_api.get_engine(),
@@ -107,7 +96,7 @@ class DbCommands(object):
107 help='Current Database version') 96 help='Current Database version')
108 def sync(self, version=None, current_version=None): 97 def sync(self, version=None, current_version=None):
109 """ 98 """
110 Place a database under migration control and upgrade/downgrade it, 99 Place a database under migration control and upgrade it,
111 creating first if necessary. 100 creating first if necessary.
112 """ 101 """
113 if current_version not in (None, 'None'): 102 if current_version not in (None, 'None'):
@@ -193,13 +182,6 @@ class DbLegacyCommands(object):
193 def upgrade(self, version=None): 182 def upgrade(self, version=None):
194 self.command_object.upgrade(CONF.command.version) 183 self.command_object.upgrade(CONF.command.version)
195 184
196 def downgrade(self, version=None):
197 print("Warning: DB downgrade is deprecated and will be removed in N "
198 "release. Users should make a full database backup of the "
199 "production data before attempting any upgrade.",
200 file=sys.stderr)
201 self.command_object.downgrade(CONF.command.version)
202
203 def version_control(self, version=None): 185 def version_control(self, version=None):
204 self.command_object.version_control(CONF.command.version) 186 self.command_object.version_control(CONF.command.version)
205 187
@@ -234,11 +216,6 @@ def add_legacy_command_parsers(command_object, subparsers):
234 parser.add_argument('version', nargs='?') 216 parser.add_argument('version', nargs='?')
235 parser.set_defaults(action='db_upgrade') 217 parser.set_defaults(action='db_upgrade')
236 218
237 parser = subparsers.add_parser('db_downgrade')
238 parser.set_defaults(action_fn=legacy_command_object.downgrade)
239 parser.add_argument('version')
240 parser.set_defaults(action='db_downgrade')
241
242 parser = subparsers.add_parser('db_version_control') 219 parser = subparsers.add_parser('db_version_control')
243 parser.set_defaults(action_fn=legacy_command_object.version_control) 220 parser.set_defaults(action_fn=legacy_command_object.version_control)
244 parser.add_argument('version', nargs='?') 221 parser.add_argument('version', nargs='?')
diff --git a/glance/db/sqlalchemy/migrate_repo/versions/001_add_images_table.py b/glance/db/sqlalchemy/migrate_repo/versions/001_add_images_table.py
index 2b9092c..35de356 100644
--- a/glance/db/sqlalchemy/migrate_repo/versions/001_add_images_table.py
+++ b/glance/db/sqlalchemy/migrate_repo/versions/001_add_images_table.py
@@ -16,7 +16,7 @@
16from sqlalchemy.schema import (Column, MetaData, Table) 16from sqlalchemy.schema import (Column, MetaData, Table)
17 17
18from glance.db.sqlalchemy.migrate_repo.schema import ( 18from glance.db.sqlalchemy.migrate_repo.schema import (
19 Boolean, DateTime, Integer, String, Text, create_tables, drop_tables) # noqa 19 Boolean, DateTime, Integer, String, Text, create_tables) # noqa
20 20
21 21
22def define_images_table(meta): 22def define_images_table(meta):
@@ -53,10 +53,3 @@ def upgrade(migrate_engine):
53 meta.bind = migrate_engine 53 meta.bind = migrate_engine
54 tables = [define_images_table(meta)] 54 tables = [define_images_table(meta)]
55 create_tables(tables) 55 create_tables(tables)
56
57
58def downgrade(migrate_engine):
59 meta = MetaData()
60 meta.bind = migrate_engine
61 tables = [define_images_table(meta)]
62 drop_tables(tables)
diff --git a/glance/db/sqlalchemy/migrate_repo/versions/002_add_image_properties_table.py b/glance/db/sqlalchemy/migrate_repo/versions/002_add_image_properties_table.py
index 64b64f4..0759a31 100644
--- a/glance/db/sqlalchemy/migrate_repo/versions/002_add_image_properties_table.py
+++ b/glance/db/sqlalchemy/migrate_repo/versions/002_add_image_properties_table.py
@@ -17,7 +17,7 @@ from sqlalchemy.schema import (
17 Column, ForeignKey, Index, MetaData, Table, UniqueConstraint) 17 Column, ForeignKey, Index, MetaData, Table, UniqueConstraint)
18 18
19from glance.db.sqlalchemy.migrate_repo.schema import ( 19from glance.db.sqlalchemy.migrate_repo.schema import (
20 Boolean, DateTime, Integer, String, Text, create_tables, drop_tables, 20 Boolean, DateTime, Integer, String, Text, create_tables,
21 from_migration_import) # noqa 21 from_migration_import) # noqa
22 22
23 23
@@ -76,10 +76,3 @@ def upgrade(migrate_engine):
76 meta.bind = migrate_engine 76 meta.bind = migrate_engine
77 tables = [define_image_properties_table(meta)] 77 tables = [define_image_properties_table(meta)]
78 create_tables(tables) 78 create_tables(tables)
79
80
81def downgrade(migrate_engine):
82 meta = MetaData()
83 meta.bind = migrate_engine
84 tables = [define_image_properties_table(meta)]
85 drop_tables(tables)
diff --git a/glance/db/sqlalchemy/migrate_repo/versions/003_add_disk_format.py b/glance/db/sqlalchemy/migrate_repo/versions/003_add_disk_format.py
index 0c19c15..c67b32a 100644
--- a/glance/db/sqlalchemy/migrate_repo/versions/003_add_disk_format.py
+++ b/glance/db/sqlalchemy/migrate_repo/versions/003_add_disk_format.py
@@ -13,7 +13,6 @@
13# License for the specific language governing permissions and limitations 13# License for the specific language governing permissions and limitations
14# under the License. 14# under the License.
15 15
16from migrate.changeset import * # noqa
17from sqlalchemy import * # noqa 16from sqlalchemy import * # noqa
18 17
19from glance.db.sqlalchemy.migrate_repo.schema import ( 18from glance.db.sqlalchemy.migrate_repo.schema import (
@@ -53,17 +52,6 @@ def get_images_table(meta):
53 return images 52 return images
54 53
55 54
56def get_image_properties_table(meta):
57 """
58 No changes to the image properties table from 002...
59 """
60 (define_image_properties_table,) = from_migration_import(
61 '002_add_image_properties_table', ['define_image_properties_table'])
62
63 image_properties = define_image_properties_table(meta)
64 return image_properties
65
66
67def upgrade(migrate_engine): 55def upgrade(migrate_engine):
68 meta = MetaData() 56 meta = MetaData()
69 meta.bind = migrate_engine 57 meta.bind = migrate_engine
@@ -119,35 +107,3 @@ def upgrade(migrate_engine):
119 container_format.create(images) 107 container_format.create(images)
120 108
121 images.columns['type'].drop() 109 images.columns['type'].drop()
122
123
124def downgrade(migrate_engine):
125 meta = MetaData()
126 meta.bind = migrate_engine
127
128 # Steps to take, in this order:
129 # 1) Add type column back to Image
130 # 2) Move the existing type properties from ImageProperty into
131 # Image.type
132 # 3) Drop the disk_format and container_format columns in Image
133
134 conn = migrate_engine.connect()
135 images = get_images_table(meta)
136 image_properties = get_image_properties_table(meta)
137
138 type_col = Column('type', String(30))
139 type_col.create(images)
140
141 sel = select([image_properties]).where(image_properties.c.key == 'type')
142 type_property_records = conn.execute(sel).fetchall()
143 for record in type_property_records:
144 upd = images.update().where(
145 images.c.id == record.image_id).values(type=record.value)
146 conn.execute(upd)
147 dlt = image_properties.delete().where(
148 image_properties.c.image_id == record.image_id)
149 conn.execute(dlt)
150 conn.close()
151
152 images.columns['disk_format'].drop()
153 images.columns['container_format'].drop()
diff --git a/glance/db/sqlalchemy/migrate_repo/versions/003_sqlite_downgrade.sql b/glance/db/sqlalchemy/migrate_repo/versions/003_sqlite_downgrade.sql
deleted file mode 100644
index 6087f90..0000000
--- a/glance/db/sqlalchemy/migrate_repo/versions/003_sqlite_downgrade.sql
+++ /dev/null
@@ -1,54 +0,0 @@
1-- Make changes to the base images table
2CREATE TEMPORARY TABLE images_backup (
3 id INTEGER NOT NULL,
4 name VARCHAR(255),
5 size INTEGER,
6 status VARCHAR(30) NOT NULL,
7 is_public BOOLEAN NOT NULL,
8 location TEXT,
9 created_at DATETIME NOT NULL,
10 updated_at DATETIME,
11 deleted_at DATETIME,
12 deleted BOOLEAN NOT NULL,
13 PRIMARY KEY (id)
14);
15
16INSERT INTO images_backup
17SELECT id, name, size, status, is_public, location, created_at, updated_at, deleted_at, deleted
18FROM images;
19
20DROP TABLE images;
21
22CREATE TABLE images (
23 id INTEGER NOT NULL,
24 name VARCHAR(255),
25 size INTEGER,
26 type VARCHAR(30),
27 status VARCHAR(30) NOT NULL,
28 is_public BOOLEAN NOT NULL,
29 location 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 (is_public IN (0, 1)),
36 CHECK (deleted IN (0, 1))
37);
38CREATE INDEX ix_images_deleted ON images (deleted);
39CREATE INDEX ix_images_is_public ON images (is_public);
40
41INSERT INTO images (id, name, size, status, is_public, location, created_at, updated_at, deleted_at, deleted)
42SELECT id, name, size, status, is_public, location, created_at, updated_at, deleted_at, deleted
43FROM images_backup;
44
45DROP TABLE images_backup;
46
47-- Re-insert the type values from the temp table
48UPDATE images
49SET type = (SELECT value FROM image_properties WHERE image_id = images.id AND key = 'type')
50WHERE EXISTS (SELECT * FROM image_properties WHERE image_id = images.id AND key = 'type');
51
52-- Remove the type properties from the image_properties table
53DELETE FROM image_properties
54WHERE key = 'type';
diff --git a/glance/db/sqlalchemy/migrate_repo/versions/004_add_checksum.py b/glance/db/sqlalchemy/migrate_repo/versions/004_add_checksum.py
index ee7e662..ea70fe2 100644
--- a/glance/db/sqlalchemy/migrate_repo/versions/004_add_checksum.py
+++ b/glance/db/sqlalchemy/migrate_repo/versions/004_add_checksum.py
@@ -13,7 +13,6 @@
13# License for the specific language governing permissions and limitations 13# License for the specific language governing permissions and limitations
14# under the License. 14# under the License.
15 15
16from migrate.changeset import * # noqa
17from sqlalchemy import * # noqa 16from sqlalchemy import * # noqa
18 17
19from glance.db.sqlalchemy.migrate_repo.schema import ( 18from glance.db.sqlalchemy.migrate_repo.schema import (
@@ -73,12 +72,3 @@ def upgrade(migrate_engine):
73 72
74 checksum = Column('checksum', String(32)) 73 checksum = Column('checksum', String(32))
75 checksum.create(images) 74 checksum.create(images)
76
77
78def downgrade(migrate_engine):
79 meta = MetaData()
80 meta.bind = migrate_engine
81
82 images = get_images_table(meta)
83
84 images.columns['checksum'].drop()
diff --git a/glance/db/sqlalchemy/migrate_repo/versions/005_size_big_integer.py b/glance/db/sqlalchemy/migrate_repo/versions/005_size_big_integer.py
index 0680399..b3d8616 100644
--- a/glance/db/sqlalchemy/migrate_repo/versions/005_size_big_integer.py
+++ b/glance/db/sqlalchemy/migrate_repo/versions/005_size_big_integer.py
@@ -13,7 +13,6 @@
13# License for the specific language governing permissions and limitations 13# License for the specific language governing permissions and limitations
14# under the License. 14# under the License.
15 15
16from migrate.changeset import * # noqa
17from sqlalchemy import * # noqa 16from sqlalchemy import * # noqa
18 17
19from glance.db.sqlalchemy.migrate_repo.schema import ( 18from glance.db.sqlalchemy.migrate_repo.schema import (
@@ -54,17 +53,6 @@ def get_images_table(meta):
54 return images 53 return images
55 54
56 55
57def get_image_properties_table(meta):
58 """
59 No changes to the image properties table from 002...
60 """
61 (define_image_properties_table,) = from_migration_import(
62 '002_add_image_properties_table', ['define_image_properties_table'])
63
64 image_properties = define_image_properties_table(meta)
65 return image_properties
66
67
68def upgrade(migrate_engine): 56def upgrade(migrate_engine):
69 meta = MetaData() 57 meta = MetaData()
70 meta.bind = migrate_engine 58 meta.bind = migrate_engine
@@ -84,21 +72,3 @@ def upgrade(migrate_engine):
84 72
85 images = get_images_table(meta) 73 images = get_images_table(meta)
86 images.columns['size'].alter(type=BigInteger()) 74 images.columns['size'].alter(type=BigInteger())
87
88
89def downgrade(migrate_engine):
90 meta = MetaData()
91 meta.bind = migrate_engine
92
93 # No changes to SQLite stores are necessary, since
94 # there is no BIG INTEGER type in SQLite. Unfortunately,
95 # running the Python 005_size_big_integer.py migration script
96 # on a SQLite datastore results in an error in the sa-migrate
97 # code that does the workarounds for SQLite not having
98 # ALTER TABLE MODIFY COLUMN ability
99
100 dialect = migrate_engine.url.get_dialect().name
101
102 if not dialect.startswith('sqlite'):
103 images = get_images_table(meta)
104 images.columns['size'].alter(type=Integer())
diff --git a/glance/db/sqlalchemy/migrate_repo/versions/006_key_to_name.py b/glance/db/sqlalchemy/migrate_repo/versions/006_key_to_name.py
index 5452234..2ec99e9 100644
--- a/glance/db/sqlalchemy/migrate_repo/versions/006_key_to_name.py
+++ b/glance/db/sqlalchemy/migrate_repo/versions/006_key_to_name.py
@@ -13,11 +13,9 @@
13# License for the specific language governing permissions and limitations 13# License for the specific language governing permissions and limitations
14# under the License. 14# under the License.
15 15
16from migrate.changeset import * # noqa
17from sqlalchemy import * # noqa 16from sqlalchemy import * # noqa
18 17
19from glance.db.sqlalchemy.migrate_repo.schema import ( 18from glance.db.sqlalchemy.migrate_repo.schema import from_migration_import
20 Boolean, DateTime, Integer, String, Text, from_migration_import) # noqa
21 19
22 20
23def get_images_table(meta): 21def get_images_table(meta):
@@ -31,44 +29,6 @@ def get_images_table(meta):
31 return images 29 return images
32 30
33 31
34def get_image_properties_table(meta):
35 """
36 Returns the Table object for the image_properties table that
37 corresponds to the image_properties table definition of this version.
38 """
39 (get_images_table,) = from_migration_import(
40 '004_add_checksum', ['get_images_table'])
41
42 images = get_images_table(meta) # noqa
43
44 image_properties = Table('image_properties',
45 meta,
46 Column('id',
47 Integer(),
48 primary_key=True,
49 nullable=False),
50 Column('image_id',
51 Integer(),
52 ForeignKey('images.id'),
53 nullable=False,
54 index=True),
55 Column('name', String(255), nullable=False),
56 Column('value', Text()),
57 Column('created_at', DateTime(), nullable=False),
58 Column('updated_at', DateTime()),
59 Column('deleted_at', DateTime()),
60 Column('deleted',
61 Boolean(),
62 nullable=False,
63 default=False,
64 index=True),
65 UniqueConstraint('image_id', 'name'),
66 mysql_engine='InnoDB',
67 extend_existing=True)
68
69 return image_properties
70
71
72def upgrade(migrate_engine): 32def upgrade(migrate_engine):
73 meta = MetaData() 33 meta = MetaData()
74 meta.bind = migrate_engine 34 meta.bind = migrate_engine
@@ -97,30 +57,3 @@ def upgrade(migrate_engine):
97 57
98 image_properties = get_image_properties_table(meta) 58 image_properties = get_image_properties_table(meta)
99 image_properties.columns['key'].alter(name="name") 59 image_properties.columns['key'].alter(name="name")
100
101
102def downgrade(migrate_engine):
103 meta = MetaData()
104 meta.bind = migrate_engine
105
106 image_properties = get_image_properties_table(meta)
107
108 if migrate_engine.name == "ibm_db_sa":
109 # NOTE(dperaza) ibm db2 does not allow ALTER INDEX so we will drop
110 # the index, rename the column, then re-create the index
111 sql_commands = [
112 """ALTER TABLE image_properties DROP UNIQUE
113 ix_image_properties_image_id_name;""",
114 """ALTER TABLE image_properties RENAME COLUMN name to \"key\";""",
115 """ALTER TABLE image_properties ADD CONSTRAINT
116 ix_image_properties_image_id_key UNIQUE(image_id, \"key\");""",
117 ]
118 for command in sql_commands:
119 meta.bind.execute(command)
120 else:
121 index = Index('ix_image_properties_image_id_name',
122 image_properties.c.image_id,
123 image_properties.c.name)
124 index.rename('ix_image_properties_image_id_key')
125
126 image_properties.columns['name'].alter(name="key")
diff --git a/glance/db/sqlalchemy/migrate_repo/versions/006_mysql_downgrade.sql b/glance/db/sqlalchemy/migrate_repo/versions/006_mysql_downgrade.sql
deleted file mode 100644
index 3a70463..0000000
--- a/glance/db/sqlalchemy/migrate_repo/versions/006_mysql_downgrade.sql
+++ /dev/null
@@ -1,11 +0,0 @@
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`);
diff --git a/glance/db/sqlalchemy/migrate_repo/versions/006_sqlite_downgrade.sql b/glance/db/sqlalchemy/migrate_repo/versions/006_sqlite_downgrade.sql
deleted file mode 100644
index 416a730..0000000
--- a/glance/db/sqlalchemy/migrate_repo/versions/006_sqlite_downgrade.sql
+++ /dev/null
@@ -1,43 +0,0 @@
1--
2-- This is necessary because SQLite does not support
3-- RENAME INDEX or ALTER TABLE CHANGE COLUMN.
4--
5CREATE TEMPORARY TABLE image_properties_backup (
6 id INTEGER NOT NULL,
7 image_id INTEGER NOT NULL,
8 key VARCHAR(255) NOT NULL,
9 value TEXT,
10 created_at DATETIME NOT NULL,
11 updated_at DATETIME,
12 deleted_at DATETIME,
13 deleted BOOLEAN NOT NULL,
14 PRIMARY KEY (id)
15);
16
17INSERT INTO image_properties_backup
18SELECT id, image_id, name, value, created_at, updated_at, deleted_at, deleted
19FROM image_properties;
20
21DROP TABLE image_properties;
22
23CREATE TABLE image_properties (
24 id INTEGER NOT NULL,
25 image_id INTEGER NOT NULL,
26 key VARCHAR(255) NOT NULL,
27 value TEXT,
28 created_at DATETIME NOT NULL,
29 updated_at DATETIME,
30 deleted_at DATETIME,
31 deleted BOOLEAN NOT NULL,
32 PRIMARY KEY (id),
33 CHECK (deleted IN (0, 1)),
34 UNIQUE (image_id, key),
35 FOREIGN KEY(image_id) REFERENCES images (id)
36);
37CREATE INDEX ix_image_properties_key ON image_properties (key);
38
39INSERT INTO image_properties (id, image_id, key, value, created_at, updated_at, deleted_at, deleted)
40SELECT id, image_id, key, value, created_at, updated_at, deleted_at, deleted
41FROM image_properties_backup;
42
43DROP TABLE image_properties_backup;
diff --git a/glance/db/sqlalchemy/migrate_repo/versions/007_add_owner.py b/glance/db/sqlalchemy/migrate_repo/versions/007_add_owner.py
index e8758aa..e43136b 100644
--- a/glance/db/sqlalchemy/migrate_repo/versions/007_add_owner.py
+++ b/glance/db/sqlalchemy/migrate_repo/versions/007_add_owner.py
@@ -13,12 +13,11 @@
13# License for the specific language governing permissions and limitations 13# License for the specific language governing permissions and limitations
14# under the License. 14# under the License.
15 15
16from migrate.changeset import * # noqa
17from sqlalchemy import * # noqa 16from sqlalchemy import * # noqa
18 17
19from glance.db.sqlalchemy.migrate_repo.schema import ( 18from glance.db.sqlalchemy.migrate_repo.schema import (
20 Boolean, DateTime, BigInteger, Integer, String, 19 Boolean, DateTime, BigInteger, Integer, String,
21 Text, from_migration_import) # noqa 20 Text) # noqa
22 21
23 22
24def get_images_table(meta): 23def get_images_table(meta):
@@ -56,17 +55,6 @@ def get_images_table(meta):
56 return images 55 return images
57 56
58 57
59def get_image_properties_table(meta):
60 """
61 No changes to the image properties table from 006...
62 """
63 (get_image_properties_table,) = from_migration_import(
64 '006_key_to_name', ['get_image_properties_table'])
65
66 image_properties = get_image_properties_table(meta)
67 return image_properties
68
69
70def upgrade(migrate_engine): 58def upgrade(migrate_engine):
71 meta = MetaData() 59 meta = MetaData()
72 meta.bind = migrate_engine 60 meta.bind = migrate_engine
@@ -75,12 +63,3 @@ def upgrade(migrate_engine):
75 63
76 owner = Column('owner', String(255)) 64 owner = Column('owner', String(255))
77 owner.create(images) 65 owner.create(images)
78
79
80def downgrade(migrate_engine):
81 meta = MetaData()
82 meta.bind = migrate_engine
83
84 images = get_images_table(meta)
85
86 images.columns['owner'].drop()
diff --git a/glance/db/sqlalchemy/migrate_repo/versions/008_add_image_members_table.py b/glance/db/sqlalchemy/migrate_repo/versions/008_add_image_members_table.py
index ff63785..2172e10 100644
--- a/glance/db/sqlalchemy/migrate_repo/versions/008_add_image_members_table.py
+++ b/glance/db/sqlalchemy/migrate_repo/versions/008_add_image_members_table.py
@@ -13,12 +13,11 @@
13# License for the specific language governing permissions and limitations 13# License for the specific language governing permissions and limitations
14# under the License. 14# under the License.
15 15
16from migrate.changeset import * # noqa
17from sqlalchemy import * # noqa 16from sqlalchemy import * # noqa
18 17
19from glance.db.sqlalchemy.migrate_repo.schema import ( 18from glance.db.sqlalchemy.migrate_repo.schema import (
20 Boolean, DateTime, Integer, String, create_tables, 19 Boolean, DateTime, Integer, String, create_tables,
21 drop_tables, from_migration_import) # noqa 20 from_migration_import) # noqa
22 21
23 22
24def get_images_table(meta): 23def get_images_table(meta):
@@ -32,17 +31,6 @@ def get_images_table(meta):
32 return images 31 return images
33 32
34 33
35def get_image_properties_table(meta):
36 """
37 No changes to the image properties table from 007...
38 """
39 (get_image_properties_table,) = from_migration_import(
40 '007_add_owner', ['get_image_properties_table'])
41
42 image_properties = get_image_properties_table(meta)
43 return image_properties
44
45
46def get_image_members_table(meta): 34def get_image_members_table(meta):
47 images = get_images_table(meta) # noqa 35 images = get_images_table(meta) # noqa
48 36
@@ -89,10 +77,3 @@ def upgrade(migrate_engine):
89 meta.bind = migrate_engine 77 meta.bind = migrate_engine
90 tables = [get_image_members_table(meta)] 78 tables = [get_image_members_table(meta)]
91 create_tables(tables) 79 create_tables(tables)
92
93
94def downgrade(migrate_engine):
95 meta = MetaData()
96 meta.bind = migrate_engine
97 tables = [get_image_members_table(meta)]
98 drop_tables(tables)
diff --git a/glance/db/sqlalchemy/migrate_repo/versions/009_add_mindisk_and_minram.py b/glance/db/sqlalchemy/migrate_repo/versions/009_add_mindisk_and_minram.py
index 719f611..0c45ab7 100644
--- a/glance/db/sqlalchemy/migrate_repo/versions/009_add_mindisk_and_minram.py
+++ b/glance/db/sqlalchemy/migrate_repo/versions/009_add_mindisk_and_minram.py
@@ -13,11 +13,10 @@
13# License for the specific language governing permissions and limitations 13# License for the specific language governing permissions and limitations
14# under the License. 14# under the License.
15 15
16from migrate.changeset import * # noqa
17from sqlalchemy import * # noqa 16from sqlalchemy import * # noqa
18 17
19from glance.db.sqlalchemy.migrate_repo.schema import ( 18from glance.db.sqlalchemy.migrate_repo.schema import (
20 Boolean, DateTime, Integer, String, Text, from_migration_import) # noqa 19 Boolean, DateTime, Integer, String, Text) # noqa
21 20
22 21
23def get_images_table(meta): 22def get_images_table(meta):
@@ -57,17 +56,6 @@ def get_images_table(meta):
57 return images 56 return images
58 57
59 58
60def get_image_properties_table(meta):
61 """
62 No changes to the image properties table from 008...
63 """
64 (define_image_properties_table,) = from_migration_import(
65 '008_add_image_members_table', ['define_image_properties_table'])
66
67 image_properties = define_image_properties_table(meta)
68 return image_properties
69
70
71def upgrade(migrate_engine): 59def upgrade(migrate_engine):
72 meta = MetaData() 60 meta = MetaData()
73 meta.bind = migrate_engine 61 meta.bind = migrate_engine
@@ -79,13 +67,3 @@ def upgrade(migrate_engine):
79 67
80 min_ram = Column('min_ram', Integer(), default=0) 68 min_ram = Column('min_ram', Integer(), default=0)
81 min_ram.create(images) 69 min_ram.create(images)
82
83
84def downgrade(migrate_engine):
85 meta = MetaData()
86 meta.bind = migrate_engine
87
88 images = get_images_table(meta)
89
90 images.columns['min_disk'].drop()
91 images.columns['min_ram'].drop()
diff --git a/glance/db/sqlalchemy/migrate_repo/versions/010_default_update_at.py b/glance/db/sqlalchemy/migrate_repo/versions/010_default_update_at.py
index 6d6d43b..9d1b151 100644
--- a/glance/db/sqlalchemy/migrate_repo/versions/010_default_update_at.py
+++ b/glance/db/sqlalchemy/migrate_repo/versions/010_default_update_at.py
@@ -13,7 +13,6 @@
13# License for the specific language governing permissions and limitations 13# License for the specific language governing permissions and limitations
14# under the License. 14# under the License.
15 15
16from migrate.changeset import * # noqa
17from sqlalchemy import * # noqa 16from sqlalchemy import * # noqa
18 17
19from glance.db.sqlalchemy.migrate_repo.schema import from_migration_import 18from glance.db.sqlalchemy.migrate_repo.schema import from_migration_import
@@ -30,28 +29,6 @@ def get_images_table(meta):
30 return images 29 return images
31 30
32 31
33def get_image_properties_table(meta):
34 """
35 No changes to the image properties table from 008...
36 """
37 (get_image_properties_table,) = from_migration_import(
38 '008_add_image_members_table', ['get_image_properties_table'])
39
40 image_properties = get_image_properties_table(meta)
41 return image_properties
42
43
44def get_image_members_table(meta):
45 """
46 No changes to the image members table from 008...
47 """
48 (get_image_members_table,) = from_migration_import(
49 '008_add_image_members_table', ['get_image_members_table'])
50
51 images = get_image_members_table(meta)
52 return images
53
54
55def upgrade(migrate_engine): 32def upgrade(migrate_engine):
56 meta = MetaData() 33 meta = MetaData()
57 meta.bind = migrate_engine 34 meta.bind = migrate_engine
@@ -64,17 +41,3 @@ def upgrade(migrate_engine):
64 images_table.update( 41 images_table.update(
65 images_table.c.updated_at == None, 42 images_table.c.updated_at == None,
66 {images_table.c.updated_at: images_table.c.created_at})) 43 {images_table.c.updated_at: images_table.c.created_at}))
67
68
69def downgrade(migrate_engine):
70 meta = MetaData()
71 meta.bind = migrate_engine
72
73 images_table = get_images_table(meta)
74
75 # set updated_at to None if equal to created_at
76 conn = migrate_engine.connect()
77 conn.execute(
78 images_table.update(
79 images_table.c.updated_at == images_table.c.created_at,
80 {images_table.c.updated_at: None}))
diff --git a/glance/db/sqlalchemy/migrate_repo/versions/011_make_mindisk_and_minram_notnull.py b/glance/db/sqlalchemy/migrate_repo/versions/011_make_mindisk_and_minram_notnull.py
index fe7b017..120e3ad 100644
--- a/glance/db/sqlalchemy/migrate_repo/versions/011_make_mindisk_and_minram_notnull.py
+++ b/glance/db/sqlalchemy/migrate_repo/versions/011_make_mindisk_and_minram_notnull.py
@@ -24,10 +24,3 @@ def upgrade(migrate_engine):
24 images = sqlalchemy.Table('images', meta, autoload=True) 24 images = sqlalchemy.Table('images', meta, autoload=True)
25 images.c.min_disk.alter(nullable=False) 25 images.c.min_disk.alter(nullable=False)
26 images.c.min_ram.alter(nullable=False) 26 images.c.min_ram.alter(nullable=False)
27
28
29def downgrade(migrate_engine):
30 meta.bind = migrate_engine
31 images = sqlalchemy.Table('images', meta, autoload=True)
32 images.c.min_disk.alter(nullable=True)
33 images.c.min_ram.alter(nullable=True)
diff --git a/glance/db/sqlalchemy/migrate_repo/versions/011_sqlite_downgrade.sql b/glance/db/sqlalchemy/migrate_repo/versions/011_sqlite_downgrade.sql
deleted file mode 100644
index 008ab80..0000000
--- a/glance/db/sqlalchemy/migrate_repo/versions/011_sqlite_downgrade.sql
+++ /dev/null
@@ -1,58 +0,0 @@
1CREATE TEMPORARY TABLE images_backup (
2 id INTEGER NOT NULL,
3 name VARCHAR(255),
4 size INTEGER,
5 status VARCHAR(30) NOT NULL,
6 is_public BOOLEAN NOT NULL,
7 location TEXT,
8 created_at DATETIME NOT NULL,
9 updated_at DATETIME,
10 deleted_at DATETIME,
11 deleted BOOLEAN NOT NULL,
12 disk_format VARCHAR(20),
13 container_format VARCHAR(20),
14 checksum VARCHAR(32),
15 owner VARCHAR(255),
16 min_disk INTEGER NOT NULL,
17 min_ram INTEGER NOT NULL,
18 PRIMARY KEY (id),
19 CHECK (is_public IN (0, 1)),
20 CHECK (deleted IN (0, 1))
21);
22
23INSERT INTO images_backup
24SELECT id, name, size, status, is_public, location, created_at, updated_at, deleted_at, deleted, disk_format, container_format, checksum, owner, min_disk, min_ram
25FROM images;
26
27DROP TABLE images;
28
29CREATE TABLE images (
30 id INTEGER NOT NULL,
31 name VARCHAR(255),
32 size INTEGER,
33 status VARCHAR(30) NOT NULL,
34 is_public BOOLEAN NOT NULL,
35 location TEXT,
36 created_at DATETIME NOT NULL,
37 updated_at DATETIME,
38 deleted_at DATETIME,
39 deleted BOOLEAN NOT NULL,
40 disk_format VARCHAR(20),
41 container_format VARCHAR(20),
42 checksum VARCHAR(32),
43 owner VARCHAR(255),
44 min_disk INTEGER,
45 min_ram INTEGER,
46 PRIMARY KEY (id),
47 CHECK (is_public IN (0, 1)),
48 CHECK (deleted IN (0, 1))
49);
50
51CREATE INDEX ix_images_deleted ON images (deleted);
52CREATE INDEX ix_images_is_public ON images (is_public);
53
54INSERT INTO images
55SELECT id, name, size, status, is_public, location, created_at, updated_at, deleted_at, deleted, disk_format, container_format, checksum, owner, min_disk, min_ram
56FROM images_backup;
57
58DROP TABLE images_backup;
diff --git a/glance/db/sqlalchemy/migrate_repo/versions/012_id_to_uuid.py b/glance/db/sqlalchemy/migrate_repo/versions/012_id_to_uuid.py
index 781038b..0701f14 100644
--- a/glance/db/sqlalchemy/migrate_repo/versions/012_id_to_uuid.py
+++ b/glance/db/sqlalchemy/migrate_repo/versions/012_id_to_uuid.py
@@ -53,29 +53,6 @@ def upgrade(migrate_engine):
53 _upgrade_other(t_images, t_image_members, t_image_properties, dialect) 53 _upgrade_other(t_images, t_image_members, t_image_properties, dialect)
54 54
55 55
56def downgrade(migrate_engine):
57 """
58 Call the correct dialect-specific downgrade.
59 """
60 meta = sqlalchemy.MetaData()
61 meta.bind = migrate_engine
62
63 t_images = _get_table('images', meta)
64 t_image_members = _get_table('image_members', meta)
65 t_image_properties = _get_table('image_properties', meta)
66 dialect = migrate_engine.url.get_dialect().name
67 if dialect == "sqlite":
68 _update_all_uuids_to_ids(t_images, t_image_members, t_image_properties)
69 _downgrade_sqlite(meta, t_images, t_image_members, t_image_properties)
70 elif dialect == "ibm_db_sa":
71 _remove_db2_constraints(meta)
72 _update_all_uuids_to_ids(t_images, t_image_members, t_image_properties)
73 _downgrade_db2(meta, t_images, t_image_members, t_image_properties)
74 else:
75 _downgrade_other(t_images, t_image_members, t_image_properties,
76 dialect)
77
78
79def _upgrade_sqlite(meta, t_images, t_image_members, t_image_properties): 56def _upgrade_sqlite(meta, t_images, t_image_members, t_image_properties):
80 """ 57 """
81 Upgrade 011 -> 012 with special SQLite-compatible logic. 58 Upgrade 011 -> 012 with special SQLite-compatible logic.
@@ -252,178 +229,6 @@ def _add_db2_constraints(meta):
252 meta.bind.execute(command) 229 meta.bind.execute(command)
253 230
254 231
255def _remove_db2_constraints(meta):
256 # Remove the foreign keys constraints
257 sql_commands = [
258 """ALTER TABLE image_members DROP CONSTRAINT member_image_id;""",
259 """ALTER TABLE image_properties DROP CONSTRAINT property_image_id;"""
260 ]
261 for command in sql_commands:
262 meta.bind.execute(command)
263
264
265def _downgrade_db2(meta, t_images, t_image_members, t_image_properties):
266 """
267 Downgrade for DB2.
268 """
269 t_images.c.id.alter(sqlalchemy.Integer(), primary_key=True)
270
271 image_members_old = sqlalchemy.Table(
272 'image_members_old',
273 meta,
274 sqlalchemy.Column('id',
275 sqlalchemy.Integer(),
276 primary_key=True,
277 nullable=False),
278 sqlalchemy.Column('image_id',
279 sqlalchemy.Integer(),
280 nullable=False,
281 index=True),
282 sqlalchemy.Column('member',
283 sqlalchemy.String(255),
284 nullable=False),
285 sqlalchemy.Column('can_share',
286 sqlalchemy.Boolean(),
287 nullable=False,
288 default=False),
289 sqlalchemy.Column('created_at',
290 sqlalchemy.DateTime(),
291 nullable=False),
292 sqlalchemy.Column('updated_at',
293 sqlalchemy.DateTime()),
294 sqlalchemy.Column('deleted_at',
295 sqlalchemy.DateTime()),
296 sqlalchemy.Column('deleted',
297 sqlalchemy.Boolean(),
298 nullable=False,
299 default=False,
300 index=True),
301 sqlalchemy.UniqueConstraint('image_id', 'member'),
302 extend_existing=True)
303
304 image_properties_old = sqlalchemy.Table(
305 'image_properties_old',
306 meta,
307 sqlalchemy.Column('id',
308 sqlalchemy.Integer(),
309 primary_key=True,
310 nullable=False),
311 sqlalchemy.Column('image_id',
312 sqlalchemy.Integer(),
313 nullable=False,
314 index=True),
315 sqlalchemy.Column('name',
316 sqlalchemy.String(255),
317 nullable=False),
318 sqlalchemy.Column('value',
319 sqlalchemy.Text()),
320 sqlalchemy.Column('created_at',
321 sqlalchemy.DateTime(),
322 nullable=False),
323 sqlalchemy.Column('updated_at',
324 sqlalchemy.DateTime()),
325 sqlalchemy.Column('deleted_at',
326 sqlalchemy.DateTime()),
327 sqlalchemy.Column('deleted',
328 sqlalchemy.Boolean(),
329 nullable=False,
330 default=False,
331 index=True),
332 sqlalchemy.UniqueConstraint(
333 'image_id', 'name',
334 name='ix_image_properties_image_id_name'),
335 extend_existing=True)
336
337 image_members_old.create()
338 image_properties_old.create()
339
340 sql_commands = [
341 """INSERT INTO image_members_old
342 SELECT * FROM image_members;""",
343 """INSERT INTO image_properties_old
344 SELECT * FROM image_properties;""",
345 ]
346
347 for command in sql_commands:
348 meta.bind.execute(command)
349
350 t_image_members.drop()
351 t_image_properties.drop()
352
353 image_members_old.rename(name='image_members')
354 image_properties_old.rename(name='image_properties')
355
356
357def _downgrade_sqlite(meta, t_images, t_image_members, t_image_properties):
358 """
359 Downgrade 012 -> 011 with special SQLite-compatible logic.
360 """
361
362 sql_commands = [
363 """CREATE TABLE images_backup (
364 id INTEGER NOT NULL,
365 name VARCHAR(255),
366 size INTEGER,
367 status VARCHAR(30) NOT NULL,
368 is_public BOOLEAN NOT NULL,
369 location TEXT,
370 created_at DATETIME NOT NULL,
371 updated_at DATETIME,
372 deleted_at DATETIME,
373 deleted BOOLEAN NOT NULL,
374 disk_format VARCHAR(20),
375 container_format VARCHAR(20),
376 checksum VARCHAR(32),
377 owner VARCHAR(255),
378 min_disk INTEGER NOT NULL,
379 min_ram INTEGER NOT NULL,
380 PRIMARY KEY (id),
381 CHECK (is_public IN (0, 1)),
382 CHECK (deleted IN (0, 1))
383 );""",
384 """INSERT INTO images_backup
385 SELECT * FROM images;""",
386 """CREATE TABLE image_members_backup (
387 id INTEGER NOT NULL,
388 image_id INTEGER NOT NULL,
389 member VARCHAR(255) NOT NULL,
390 can_share BOOLEAN NOT NULL,
391 created_at DATETIME NOT NULL,
392 updated_at DATETIME,
393 deleted_at DATETIME,
394 deleted BOOLEAN NOT NULL,
395 PRIMARY KEY (id),
396 UNIQUE (image_id, member),
397 CHECK (can_share IN (0, 1)),
398 CHECK (deleted IN (0, 1)),
399 FOREIGN KEY(image_id) REFERENCES images (id)
400 );""",
401 """INSERT INTO image_members_backup
402 SELECT * FROM image_members;""",
403 """CREATE TABLE image_properties_backup (
404 id INTEGER NOT NULL,
405 image_id INTEGER NOT NULL,
406 name VARCHAR(255) NOT NULL,
407 value TEXT,
408 created_at DATETIME NOT NULL,
409 updated_at DATETIME,
410 deleted_at DATETIME,
411 deleted BOOLEAN NOT NULL,
412 PRIMARY KEY (id),
413 CHECK (deleted IN (0, 1)),
414 UNIQUE (image_id, name),
415 FOREIGN KEY(image_id) REFERENCES images (id)
416 );""",
417 """INSERT INTO image_properties_backup
418 SELECT * FROM image_properties;""",
419 ]
420
421 for command in sql_commands:
422 meta.bind.execute(command)
423
424 _sqlite_table_swap(meta, t_image_members, t_image_properties, t_images)
425
426
427def _upgrade_other(t_images, t_image_members, t_image_properties, dialect): 232def _upgrade_other(t_images, t_image_members, t_image_properties, dialect):
428 """ 233 """
429 Upgrade 011 -> 012 with logic for non-SQLite databases. 234 Upgrade 011 -> 012 with logic for non-SQLite databases.
@@ -445,41 +250,6 @@ def _upgrade_other(t_images, t_image_members, t_image_properties, dialect):
445 fk.create() 250 fk.create()
446 251
447 252
448def _downgrade_other(t_images, t_image_members, t_image_properties, dialect):
449 """
450 Downgrade 012 -> 011 with logic for non-SQLite databases.
451 """
452 foreign_keys = _get_foreign_keys(t_images,
453 t_image_members,
454 t_image_properties, dialect)
455
456 for fk in foreign_keys:
457 fk.drop()
458
459 _update_all_uuids_to_ids(t_images, t_image_members, t_image_properties)
460
461 t_images.c.id.alter(primary_key=True)
462 # we have to use raw sql for postgresql as we have errors
463 # if we use alter type on sqlalchemy
464 if dialect == 'postgresql':
465 t_images.bind.execute('''ALTER TABLE images
466 ALTER COLUMN id TYPE INTEGER
467 USING (id::INTEGER)''')
468 t_images.bind.execute('''ALTER TABLE image_members
469 ALTER COLUMN image_id TYPE INTEGER
470 USING (image_id::INTEGER)''')
471 t_images.bind.execute('''ALTER TABLE image_properties
472 ALTER COLUMN image_id TYPE INTEGER
473 USING (image_id::INTEGER)''')
474 else:
475 t_images.c.id.alter(sqlalchemy.Integer())
476 t_image_members.c.image_id.alter(sqlalchemy.Integer())
477 t_image_properties.c.image_id.alter(sqlalchemy.Integer())
478
479 for fk in foreign_keys:
480 fk.create()
481
482
483def _sqlite_table_swap(meta, t_image_members, t_image_properties, t_images): 253def _sqlite_table_swap(meta, t_image_members, t_image_properties, t_images):
484 t_image_members.drop() 254 t_image_members.drop()
485 t_image_properties.drop() 255 t_image_properties.drop()
diff --git a/glance/db/sqlalchemy/migrate_repo/versions/013_add_protected.py b/glance/db/sqlalchemy/migrate_repo/versions/013_add_protected.py
index 09219e6..29afeef 100644
--- a/glance/db/sqlalchemy/migrate_repo/versions/013_add_protected.py
+++ b/glance/db/sqlalchemy/migrate_repo/versions/013_add_protected.py
@@ -26,10 +26,3 @@ def upgrade(migrate_engine):
26 26
27 images = Table('images', meta, autoload=True) 27 images = Table('images', meta, autoload=True)
28 images.create_column(protected) 28 images.create_column(protected)
29
30
31def downgrade(migrate_engine):
32 meta.bind = migrate_engine
33
34 images = Table('images', meta, autoload=True)
35 images.drop_column(protected)
diff --git a/glance/db/sqlalchemy/migrate_repo/versions/013_sqlite_downgrade.sql b/glance/db/sqlalchemy/migrate_repo/versions/013_sqlite_downgrade.sql
deleted file mode 100644
index ecdfdcd..0000000
--- a/glance/db/sqlalchemy/migrate_repo/versions/013_sqlite_downgrade.sql
+++ /dev/null
@@ -1,62 +0,0 @@
1--
2-- This is necessary because sqlalchemy has various bugs preventing
3-- downgrades from working correctly.
4--
5CREATE TEMPORARY TABLE images_backup (
6 id VARCHAR(36) NOT NULL,
7 name VARCHAR(255),
8 size INTEGER,
9 status VARCHAR(30) NOT NULL,
10 is_public BOOLEAN NOT NULL,
11 location TEXT,
12 created_at DATETIME NOT NULL,
13 updated_at DATETIME,
14 deleted_at DATETIME,
15 deleted BOOLEAN NOT NULL,
16 disk_format VARCHAR(20),
17 container_format VARCHAR(20),
18 checksum VARCHAR(32),
19 owner VARCHAR(255),
20 min_disk INTEGER NOT NULL,
21 min_ram INTEGER NOT NULL,
22 PRIMARY KEY (id),
23 CHECK (is_public IN (0, 1)),
24 CHECK (deleted IN (0, 1))
25);
26
27
28INSERT INTO images_backup
29SELECT id, name, size, status, is_public, location, created_at, updated_at, deleted_at, deleted, disk_format, container_format, checksum, owner, min_disk, min_ram
30FROM images;
31
32DROP TABLE images;
33
34CREATE TABLE images (
35 id VARCHAR(36) NOT NULL,
36 name VARCHAR(255),
37 size INTEGER,
38 status VARCHAR(30) NOT NULL,
39 is_public BOOLEAN NOT NULL,
40 location TEXT,
41 created_at DATETIME NOT NULL,
42 updated_at DATETIME,
43 deleted_at DATETIME,
44 deleted BOOLEAN NOT NULL,
45 disk_format VARCHAR(20),
46 container_format VARCHAR(20),
47 checksum VARCHAR(32),
48 owner VARCHAR(255),
49 min_disk INTEGER NOT NULL,
50 min_ram INTEGER NOT NULL,
51 PRIMARY KEY (id),
52 CHECK (is_public IN (0, 1)),
53 CHECK (deleted IN (0, 1))
54);
55CREATE INDEX ix_images_is_public ON images (is_public);
56CREATE INDEX ix_images_deleted ON images (deleted);
57
58INSERT INTO images
59SELECT id, name, size, status, is_public, location, created_at, updated_at, deleted_at, deleted, disk_format, container_format, checksum, owner, min_disk, min_ram
60FROM images_backup;
61
62DROP TABLE images_backup;
diff --git a/glance/db/sqlalchemy/migrate_repo/versions/014_add_image_tags_table.py b/glance/db/sqlalchemy/migrate_repo/versions/014_add_image_tags_table.py
index 5f41fd5..84d28a3 100644
--- a/glance/db/sqlalchemy/migrate_repo/versions/014_add_image_tags_table.py
+++ b/glance/db/sqlalchemy/migrate_repo/versions/014_add_image_tags_table.py
@@ -64,10 +64,3 @@ def upgrade(migrate_engine):
64 meta.bind = migrate_engine 64 meta.bind = migrate_engine
65 tables = [define_image_tags_table(meta)] 65 tables = [define_image_tags_table(meta)]
66 glance_schema.create_tables(tables) 66 glance_schema.create_tables(tables)
67
68
69def downgrade(migrate_engine):
70 meta = schema.MetaData()
71 meta.bind = migrate_engine
72 tables = [define_image_tags_table(meta)]
73 glance_schema.drop_tables(tables)
diff --git a/glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py b/glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py
index c1045b1..ad3a31f 100644
--- a/glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py
+++ b/glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py
@@ -28,10 +28,6 @@ def upgrade(migrate_engine):
28 migrate_location_credentials(migrate_engine, to_quoted=True) 28 migrate_location_credentials(migrate_engine, to_quoted=True)
29 29
30 30
31def downgrade(migrate_engine):
32 migrate_location_credentials(migrate_engine, to_quoted=False)
33
34
35def migrate_location_credentials(migrate_engine, to_quoted): 31def migrate_location_credentials(migrate_engine, to_quoted):
36 """ 32 """
37 Migrate location credentials for swift uri's between the quoted 33 Migrate location credentials for swift uri's between the quoted
diff --git a/glance/db/sqlalchemy/migrate_repo/versions/016_add_status_image_member.py b/glance/db/sqlalchemy/migrate_repo/versions/016_add_status_image_member.py
index 2998df1..45d3b72 100644
--- a/glance/db/sqlalchemy/migrate_repo/versions/016_add_status_image_member.py
+++ b/glance/db/sqlalchemy/migrate_repo/versions/016_add_status_image_member.py
@@ -26,10 +26,3 @@ def upgrade(migrate_engine):
26 26
27 image_members = Table('image_members', meta, autoload=True) 27 image_members = Table('image_members', meta, autoload=True)
28 image_members.create_column(status) 28 image_members.create_column(status)
29
30
31def downgrade(migrate_engine):
32 meta.bind = migrate_engine
33
34 image_members = Table('image_members', meta, autoload=True)
35 image_members.drop_column(status)
diff --git a/glance/db/sqlalchemy/migrate_repo/versions/016_sqlite_downgrade.sql b/glance/db/sqlalchemy/migrate_repo/versions/016_sqlite_downgrade.sql
deleted file mode 100644
index 460ca27..0000000
--- a/glance/db/sqlalchemy/migrate_repo/versions/016_sqlite_downgrade.sql
+++ /dev/null
@@ -1,43 +0,0 @@
1CREATE TEMPORARY TABLE image_members_backup (
2 id INTEGER NOT NULL,
3 image_id VARCHAR(36) NOT NULL,
4 member VARCHAR(255) NOT NULL,
5 can_share BOOLEAN NOT NULL,
6 created_at DATETIME NOT NULL,
7 updated_at DATETIME,
8 deleted_at DATETIME,
9 deleted BOOLEAN NOT NULL,
10 PRIMARY KEY (id),
11 UNIQUE (image_id, member),
12 CHECK (can_share IN (0, 1)),
13 CHECK (deleted IN (0, 1)),
14 FOREIGN KEY(image_id) REFERENCES images (id)
15);
16
17INSERT INTO image_members_backup
18SELECT id, image_id, member, can_share, created_at, updated_at, deleted_at, deleted
19FROM image_members;
20
21DROP TABLE image_members;
22
23CREATE TABLE image_members (
24 id INTEGER NOT NULL,
25 image_id VARCHAR(36) NOT NULL,
26 member VARCHAR(255) NOT NULL,
27 can_share BOOLEAN NOT NULL,
28 created_at DATETIME NOT NULL,
29 updated_at DATETIME,
30 deleted_at DATETIME,
31 deleted BOOLEAN NOT NULL,
32 PRIMARY KEY (id),
33 UNIQUE (image_id, member),
34 CHECK (can_share IN (0, 1)),
35 CHECK (deleted IN (0, 1)),
36 FOREIGN KEY(image_id) REFERENCES images (id)
37);
38
39INSERT INTO image_members
40SELECT id, image_id, member, can_share, created_at, updated_at, deleted_at, deleted
41FROM image_members_backup;
42
43DROP TABLE image_members_backup;
diff --git a/glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py b/glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py
index 09e32ea..0c8b4c4 100644
--- a/glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py
+++ b/glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py
@@ -26,8 +26,6 @@ migration performs the following steps for every entry in the images table:
26 26
27Fixes bug #1081043 27Fixes bug #1081043
28""" 28"""
29import types # noqa
30
31from oslo_config import cfg 29from oslo_config import cfg
32from oslo_log import log as logging 30from oslo_log import log as logging
33from oslo_utils import encodeutils 31from oslo_utils import encodeutils
@@ -48,10 +46,6 @@ def upgrade(migrate_engine):
48 migrate_location_credentials(migrate_engine, to_quoted=True) 46 migrate_location_credentials(migrate_engine, to_quoted=True)
49 47
50 48
51def downgrade(migrate_engine):
52 migrate_location_credentials(migrate_engine, to_quoted=False)
53
54
55def migrate_location_credentials(migrate_engine, to_quoted): 49def migrate_location_credentials(migrate_engine, to_quoted):
56 """ 50 """
57 Migrate location credentials for encrypted swift uri's between the 51 Migrate location credentials for encrypted swift uri's between the
diff --git a/glance/db/sqlalchemy/migrate_repo/versions/018_add_image_locations_table.py b/glance/db/sqlalchemy/migrate_repo/versions/018_add_image_locations_table.py
index 5809d95..3ce38c6 100644
--- a/glance/db/sqlalchemy/migrate_repo/versions/018_add_image_locations_table.py
+++ b/glance/db/sqlalchemy/migrate_repo/versions/018_add_image_locations_table.py
@@ -55,10 +55,3 @@ def upgrade(migrate_engine):
55 ) 55 )
56 56
57 schema.create_tables([image_locations_table]) 57 schema.create_tables([image_locations_table])
58
59
60def downgrade(migrate_engine):
61 meta = sqlalchemy.schema.MetaData(migrate_engine)
62 image_locations_table = sqlalchemy.Table('image_locations', meta,
63 autoload=True)
64 schema.drop_tables([image_locations_table])
diff --git a/glance/db/sqlalchemy/migrate_repo/versions/019_migrate_image_locations.py b/glance/db/sqlalchemy/migrate_repo/versions/019_migrate_image_locations.py
index 29c9824..5e7e013 100644
--- a/glance/db/sqlalchemy/migrate_repo/versions/019_migrate_image_locations.py
+++ b/glance/db/sqlalchemy/migrate_repo/versions/019_migrate_image_locations.py
@@ -42,17 +42,3 @@ def upgrade(migrate_engine):
42 'deleted_at': image.deleted_at, 42 'deleted_at': image.deleted_at,
43 } 43 }
44 image_locations_table.insert(values=values).execute() 44 image_locations_table.insert(values=values).execute()
45
46
47def downgrade(migrate_engine):
48 meta = sqlalchemy.schema.MetaData(migrate_engine)
49
50 images_table = get_images_table(meta)
51 image_locations_table = get_image_locations_table(meta)
52
53 image_records = image_locations_table.select().execute().fetchall()
54
55 for image_location in image_records:
56 images_table.update(
57 values={'location': image_location.value}).where(
58 images_table.c.id == image_location.image_id).execute()
diff --git a/glance/db/sqlalchemy/migrate_repo/versions/020_drop_images_table_location.py b/glance/db/sqlalchemy/migrate_repo/versions/020_drop_images_table_location.py
index 392af57..c4c5b0d 100644
--- a/glance/db/sqlalchemy/migrate_repo/versions/020_drop_images_table_location.py
+++ b/glance/db/sqlalchemy/migrate_repo/versions/020_drop_images_table_location.py
@@ -15,8 +15,6 @@
15 15
16import sqlalchemy 16import sqlalchemy
17 17
18from glance.db.sqlalchemy.migrate_repo import schema
19
20 18
21def get_images_table(meta): 19def get_images_table(meta):
22 return sqlalchemy.Table('images', meta, autoload=True) 20 return sqlalchemy.Table('images', meta, autoload=True)
@@ -26,10 +24,3 @@ def upgrade(migrate_engine):
26 meta = sqlalchemy.schema.MetaData(migrate_engine) 24 meta = sqlalchemy.schema.MetaData(migrate_engine)
27 images_table = get_images_table(meta) 25 images_table = get_images_table(meta)
28 images_table.columns['location'].drop() 26 images_table.columns['location'].drop()
29
30
31def downgrade(migrate_engine):
32 meta = sqlalchemy.schema.MetaData(migrate_engine)
33 images_table = get_images_table(meta)
34 location = sqlalchemy.Column('location', schema.Text())
35 location.create(images_table)
diff --git a/glance/db/sqlalchemy/migrate_repo/versions/021_set_engine_mysql_innodb.py b/glance/db/sqlalchemy/migrate_repo/versions/021_set_engine_mysql_innodb.py
index 12a0b68..3891d59 100644
--- a/glance/db/sqlalchemy/migrate_repo/versions/021_set_engine_mysql_innodb.py
+++ b/glance/db/sqlalchemy/migrate_repo/versions/021_set_engine_mysql_innodb.py
@@ -29,7 +29,3 @@ def upgrade(migrate_engine):
29 if table_name in tables: 29 if table_name in tables:
30 migrate_engine.execute("ALTER TABLE %s Engine=InnoDB" % 30 migrate_engine.execute("ALTER TABLE %s Engine=InnoDB" %
31 table_name) 31 table_name)
32
33
34def downgrade(migrate_engine):
35 pass
diff --git a/glance/db/sqlalchemy/migrate_repo/versions/022_image_member_index.py b/glance/db/sqlalchemy/migrate_repo/versions/022_image_member_index.py
index 3c47796..f39de5f 100644
--- a/glance/db/sqlalchemy/migrate_repo/versions/022_image_member_index.py
+++ b/glance/db/sqlalchemy/migrate_repo/versions/022_image_member_index.py
@@ -17,7 +17,6 @@ import re
17 17
18from migrate.changeset import UniqueConstraint 18from migrate.changeset import UniqueConstraint
19from oslo_db import exception as db_exception 19from oslo_db import exception as db_exception
20from sqlalchemy import and_, func, orm
21from sqlalchemy import MetaData, Table 20from sqlalchemy import MetaData, Table
22from sqlalchemy.exc import OperationalError, ProgrammingError 21from sqlalchemy.exc import OperationalError, ProgrammingError
23 22
@@ -45,20 +44,6 @@ def upgrade(migrate_engine):
45 table=image_members).create() 44 table=image_members).create()
46 45
47 46
48def downgrade(migrate_engine):
49 image_members = _get_image_members_table(migrate_engine)
50
51 if migrate_engine.name in ('mysql', 'postgresql'):
52 _sanitize(migrate_engine, image_members)
53 UniqueConstraint('image_id',
54 name=NEW_KEYNAME,
55 table=image_members).drop()
56 UniqueConstraint('image_id',
57 'member',
58 name=_get_original_keyname(migrate_engine.name),
59 table=image_members).create()
60
61
62def _get_image_members_table(migrate_engine): 47def _get_image_members_table(migrate_engine):
63 meta = MetaData() 48 meta = MetaData()
64 meta.bind = migrate_engine 49 meta.bind = migrate_engine
@@ -74,23 +59,3 @@ def _infer_original_keyname(table):
74 for i in table.indexes: 59 for i in table.indexes:
75 if ORIGINAL_KEYNAME_RE.match(i.name): 60 if ORIGINAL_KEYNAME_RE.match(i.name):
76 return i.name 61 return i.name
77
78
79def _sanitize(migrate_engine, table):
80 """
81 Avoid possible integrity error by removing deleted rows
82 to accommodate less restrictive uniqueness constraint
83 """
84 session = orm.sessionmaker(bind=migrate_engine)()
85 # find the image_member rows containing duplicate combinations
86 # of image_id and member
87 qry = (session.query(table.c.image_id, table.c.member)
88 .group_by(table.c.image_id, table.c.member)
89 .having(func.count() > 1))
90 for image_id, member in qry:
91 # only remove duplicate rows already marked deleted
92 d = table.delete().where(and_(table.c.deleted == True,
93 table.c.image_id == image_id,
94 table.c.member == member))
95 d.execute()
96 session.close()
diff --git a/glance/db/sqlalchemy/migrate_repo/versions/023_placeholder.py b/glance/db/sqlalchemy/migrate_repo/versions/023_placeholder.py
index 5c63682..43f3c57 100644
--- a/glance/db/sqlalchemy/migrate_repo/versions/023_placeholder.py
+++ b/glance/db/sqlalchemy/migrate_repo/versions/023_placeholder.py
@@ -17,7 +17,3 @@
17 17
18def upgrade(migrate_engine): 18def upgrade(migrate_engine):
19 pass 19 pass
20
21
22def downgrade(migration_engine):
23 pass
diff --git a/glance/db/sqlalchemy/migrate_repo/versions/024_placeholder.py b/glance/db/sqlalchemy/migrate_repo/versions/024_placeholder.py
index 5c63682..43f3c57 100644
--- a/glance/db/sqlalchemy/migrate_repo/versions/024_placeholder.py
+++ b/glance/db/sqlalchemy/migrate_repo/versions/024_placeholder.py
@@ -17,7 +17,3 @@
17 17
18def upgrade(migrate_engine): 18def upgrade(migrate_engine):
19 pass 19 pass
20
21
22def downgrade(migration_engine):
23 pass
diff --git a/glance/db/sqlalchemy/migrate_repo/versions/025_placeholder.py b/glance/db/sqlalchemy/migrate_repo/versions/025_placeholder.py
index 5c63682..43f3c57 100644
--- a/glance/db/sqlalchemy/migrate_repo/versions/025_placeholder.py
+++ b/glance/db/sqlalchemy/migrate_repo/versions/025_placeholder.py
@@ -17,7 +17,3 @@
17 17
18def upgrade(migrate_engine): 18def upgrade(migrate_engine):
19 pass 19 pass
20
21
22def downgrade(migration_engine):
23 pass
diff --git a/glance/db/sqlalchemy/migrate_repo/versions/026_add_location_storage_information.py b/glance/db/sqlalchemy/migrate_repo/versions/026_add_location_storage_information.py
index 05970fc..881d8bb 100644
--- a/glance/db/sqlalchemy/migrate_repo/versions/026_add_location_storage_information.py
+++ b/glance/db/sqlalchemy/migrate_repo/versions/026_add_location_storage_information.py
@@ -30,14 +30,3 @@ def upgrade(migrate_engine):
30 schema.PickleType(), 30 schema.PickleType(),
31 default={}) 31 default={})
32 meta_data.create(image_locations_table) 32 meta_data.create(image_locations_table)
33
34
35def downgrade(migrate_engine):
36 meta = sqlalchemy.schema.MetaData()
37 meta.bind = migrate_engine
38
39 image_locations_table = sqlalchemy.Table('image_locations',
40 meta,
41 autoload=True)
42
43 image_locations_table.columns['meta_data'].drop()
diff --git a/glance/db/sqlalchemy/migrate_repo/versions/027_checksum_index.py b/glance/db/sqlalchemy/migrate_repo/versions/027_checksum_index.py
index b74746c..1db7d2e 100644
--- a/glance/db/sqlalchemy/migrate_repo/versions/027_checksum_index.py
+++ b/glance/db/sqlalchemy/migrate_repo/versions/027_checksum_index.py
@@ -26,13 +26,3 @@ def upgrade(migrate_engine):
26 26
27 index = Index(INDEX_NAME, images.c.checksum) 27 index = Index(INDEX_NAME, images.c.checksum)
28 index.create(migrate_engine) 28 index.create(migrate_engine)
29
30
31def downgrade(migrate_engine):
32 meta = MetaData()
33 meta.bind = migrate_engine
34
35 images = Table('images', meta, autoload=True)
36
37 index = Index(INDEX_NAME, images.c.checksum)
38 index.drop(migrate_engine)
diff --git a/glance/db/sqlalchemy/migrate_repo/versions/028_owner_index.py b/glance/db/sqlalchemy/migrate_repo/versions/028_owner_index.py
index 73815fa..f8b24c9 100644
--- a/glance/db/sqlalchemy/migrate_repo/versions/028_owner_index.py
+++ b/glance/db/sqlalchemy/migrate_repo/versions/028_owner_index.py
@@ -26,13 +26,3 @@ def upgrade(migrate_engine):
26 26
27 index = Index(INDEX_NAME, images.c.owner) 27 index = Index(INDEX_NAME, images.c.owner)
28 index.create(migrate_engine) 28 index.create(migrate_engine)
29
30
31def downgrade(migrate_engine):
32 meta = MetaData()
33 meta.bind = migrate_engine
34
35 images = Table('images', meta, autoload=True)
36
37 index = Index(INDEX_NAME, images.c.owner)
38 index.drop(migrate_engine)
diff --git a/glance/db/sqlalchemy/migrate_repo/versions/029_location_meta_data_pickle_to_string.py b/glance/db/sqlalchemy/migrate_repo/versions/029_location_meta_data_pickle_to_string.py
index f2a3761..41e0463 100644
--- a/glance/db/sqlalchemy/migrate_repo/versions/029_location_meta_data_pickle_to_string.py
+++ b/glance/db/sqlalchemy/migrate_repo/versions/029_location_meta_data_pickle_to_string.py
@@ -13,11 +13,10 @@
13# License for the specific language governing permissions and limitations 13# License for the specific language governing permissions and limitations
14# under the License. 14# under the License.
15 15
16import json
17import pickle 16import pickle
18 17
19import sqlalchemy 18import sqlalchemy
20from sqlalchemy import MetaData, Table, Column # noqa 19from sqlalchemy import Table, Column # noqa
21from glance.db.sqlalchemy import models 20from glance.db.sqlalchemy import models
22 21
23 22
@@ -44,29 +43,3 @@ def upgrade(migrate_engine):
44 conn.close() 43 conn.close()
45 image_locations.columns['meta_data'].drop() 44 image_locations.columns['meta_data'].drop()
46 image_locations.columns['storage_meta_data'].alter(name='meta_data') 45 image_locations.columns['storage_meta_data'].alter(name='meta_data')
47
48
49def downgrade(migrate_engine):
50 meta = sqlalchemy.schema.MetaData(migrate_engine)
51 image_locations = Table('image_locations', meta, autoload=True)
52 old_meta_data = Column('old_meta_data', sqlalchemy.PickleType(),
53 default={})
54 old_meta_data.create(image_locations)
55
56 noj = json.dumps({})
57 s = sqlalchemy.sql.select([image_locations]).where(
58 image_locations.c.meta_data != noj)
59 conn = migrate_engine.connect()
60 res = conn.execute(s)
61
62 for row in res:
63 x = row['meta_data']
64 meta_data = json.loads(x)
65 if meta_data != {}:
66 stmt = image_locations.update().where(
67 image_locations.c.id == row['id']).values(
68 old_meta_data=meta_data)
69 conn.execute(stmt)
70 conn.close()
71 image_locations.columns['meta_data'].drop()
72 image_locations.columns['old_meta_data'].alter(name='meta_data')
diff --git a/glance/db/sqlalchemy/migrate_repo/versions/030_add_tasks_table.py b/glance/db/sqlalchemy/migrate_repo/versions/030_add_tasks_table.py
index f1c5ec9..4f03100 100644
--- a/glance/db/sqlalchemy/migrate_repo/versions/030_add_tasks_table.py
+++ b/glance/db/sqlalchemy/migrate_repo/versions/030_add_tasks_table.py
@@ -17,7 +17,7 @@
17from sqlalchemy.schema import (Column, MetaData, Table, Index) 17from sqlalchemy.schema import (Column, MetaData, Table, Index)
18 18
19from glance.db.sqlalchemy.migrate_repo.schema import ( 19from glance.db.sqlalchemy.migrate_repo.schema import (
20 Boolean, DateTime, String, Text, create_tables, drop_tables) # noqa 20 Boolean, DateTime, String, Text, create_tables) # noqa
21 21
22 22
23def define_tasks_table(meta): 23def define_tasks_table(meta):
@@ -56,10 +56,3 @@ def upgrade(migrate_engine):
56 meta.bind = migrate_engine 56 meta.bind = migrate_engine
57 tables = [define_tasks_table(meta)] 57 tables = [define_tasks_table(meta)]
58 create_tables(tables) 58 create_tables(tables)
59
60
61def downgrade(migrate_engine):
62 meta = MetaData()
63 meta.bind = migrate_engine
64 tables = [define_tasks_table(meta)]
65 drop_tables(tables)
diff --git a/glance/db/sqlalchemy/migrate_repo/versions/031_remove_duplicated_locations.py b/glance/db/sqlalchemy/migrate_repo/versions/031_remove_duplicated_locations.py
index a468aeb..f884621 100644
--- a/glance/db/sqlalchemy/migrate_repo/versions/031_remove_duplicated_locations.py
+++ b/glance/db/sqlalchemy/migrate_repo/versions/031_remove_duplicated_locations.py
@@ -73,9 +73,3 @@ def upgrade(migrate_engine):
73 stmt.execute() 73 stmt.execute()
74 74
75 session.close() 75 session.close()
76
77
78def downgrade(migrate_engine):
79 # NOTE(flaper87): There's no downgrade
80 # path for this.
81 return
diff --git a/glance/db/sqlalchemy/migrate_repo/versions/032_add_task_info_table.py b/glance/db/sqlalchemy/migrate_repo/versions/032_add_task_info_table.py
index bc51349..a5ce70a 100644
--- a/glance/db/sqlalchemy/migrate_repo/versions/032_add_task_info_table.py
+++ b/glance/db/sqlalchemy/migrate_repo/versions/032_add_task_info_table.py
@@ -17,8 +17,7 @@ from sqlalchemy.schema import (Column, ForeignKey, MetaData, Table)
17 17
18from glance.db.sqlalchemy.migrate_repo.schema import (String, 18from glance.db.sqlalchemy.migrate_repo.schema import (String,
19 Text, 19 Text,
20 create_tables, 20 create_tables) # noqa
21 drop_tables) # noqa
22 21
23TASKS_MIGRATE_COLUMNS = ['input', 'message', 'result'] 22TASKS_MIGRATE_COLUMNS = ['input', 'message', 'result']
24 23
@@ -65,29 +64,3 @@ def upgrade(migrate_engine):
65 64
66 for col_name in TASKS_MIGRATE_COLUMNS: 65 for col_name in TASKS_MIGRATE_COLUMNS:
67 tasks_table.columns[col_name].drop() 66 tasks_table.columns[col_name].drop()
68
69
70def downgrade(migrate_engine):
71 meta = MetaData()
72 meta.bind = migrate_engine
73
74 tasks_table = Table('tasks', meta, autoload=True)
75 task_info_table = Table('task_info', meta, autoload=True)
76
77 for col_name in TASKS_MIGRATE_COLUMNS:
78 column = Column(col_name, Text())
79 column.create(tasks_table)
80
81 task_info_records = task_info_table.select().execute().fetchall()
82
83 for task_info in task_info_records:
84 values = {
85 'input': task_info.input,
86 'result': task_info.result,
87 'message': task_info.message
88 }
89
90 tasks_table.update(values=values).where(
91 tasks_table.c.id == task_info.task_id).execute()
92
93 drop_tables([task_info_table])
diff --git a/glance/db/sqlalchemy/migrate_repo/versions/033_add_location_status.py b/glance/db/sqlalchemy/migrate_repo/versions/033_add_location_status.py
index 895f7eb..798cc4b 100644
--- a/glance/db/sqlalchemy/migrate_repo/versions/033_add_location_status.py
+++ b/glance/db/sqlalchemy/migrate_repo/versions/033_add_location_status.py
@@ -39,14 +39,3 @@ def upgrade(migrate_engine):
39 images_table.c.status == src) 39 images_table.c.status == src)
40 image_locations_table.update(values={'status': dst}).where( 40 image_locations_table.update(values={'status': dst}).where(
41 image_locations_table.c.image_id.in_(subq)).execute() 41 image_locations_table.c.image_id.in_(subq)).execute()
42
43
44def downgrade(migrate_engine):
45 meta = sqlalchemy.schema.MetaData()
46 meta.bind = migrate_engine
47
48 image_locations_table = sqlalchemy.Table('image_locations', meta,
49 autoload=True)
50
51 # Remove 'status' column from image_locations table
52 image_locations_table.columns['status'].drop()
diff --git a/glance/db/sqlalchemy/migrate_repo/versions/034_add_virtual_size.py b/glance/db/sqlalchemy/migrate_repo/versions/034_add_virtual_size.py
index cfae3be..a80ae5d 100644
--- a/glance/db/sqlalchemy/migrate_repo/versions/034_add_virtual_size.py
+++ b/glance/db/sqlalchemy/migrate_repo/versions/034_add_virtual_size.py
@@ -24,11 +24,3 @@ def upgrade(migrate_engine):
24 virtual_size = sqlalchemy.Column('virtual_size', 24 virtual_size = sqlalchemy.Column('virtual_size',
25 sqlalchemy.BigInteger) 25 sqlalchemy.BigInteger)
26 images.create_column(virtual_size) 26 images.create_column(virtual_size)
27
28
29def downgrade(migrate_engine):
30 meta = sqlalchemy.MetaData()
31 meta.bind = migrate_engine
32
33 images = sqlalchemy.Table('images', meta, autoload=True)
34 images.columns['virtual_size'].drop()
diff --git a/glance/db/sqlalchemy/migrate_repo/versions/035_add_metadef_tables.py b/glance/db/sqlalchemy/migrate_repo/versions/035_add_metadef_tables.py
index 1602e73..f7dd250 100644
--- a/glance/db/sqlalchemy/migrate_repo/versions/035_add_metadef_tables.py
+++ b/glance/db/sqlalchemy/migrate_repo/versions/035_add_metadef_tables.py
@@ -18,8 +18,7 @@ from sqlalchemy.schema import (
18 18
19from glance.common import timeutils 19from glance.common import timeutils
20from glance.db.sqlalchemy.migrate_repo.schema import ( 20from glance.db.sqlalchemy.migrate_repo.schema import (
21 Boolean, DateTime, Integer, String, Text, create_tables, 21 Boolean, DateTime, Integer, String, Text, create_tables) # noqa
22 drop_tables) # noqa
23 22
24 23
25RESOURCE_TYPES = [u'OS::Glance::Image', u'OS::Cinder::Volume', 24RESOURCE_TYPES = [u'OS::Glance::Image', u'OS::Cinder::Volume',
@@ -207,14 +206,3 @@ def upgrade(migrate_engine):
207 206
208 resource_types_table = _get_metadef_resource_types_table(meta) 207 resource_types_table = _get_metadef_resource_types_table(meta)
209 _populate_resource_types(resource_types_table) 208 _populate_resource_types(resource_types_table)
210
211
212def downgrade(migrate_engine):
213 meta = MetaData()
214 meta.bind = migrate_engine
215 tables = [define_metadef_objects_table(meta),
216 define_metadef_properties_table(meta),
217 define_metadef_namespace_resource_types_table(meta),
218 define_metadef_resource_types_table(meta),
219 define_metadef_namespaces_table(meta)]
220 drop_tables(tables)
diff --git a/glance/db/sqlalchemy/migrate_repo/versions/036_rename_metadef_schema_columns.py b/glance/db/sqlalchemy/migrate_repo/versions/036_rename_metadef_schema_columns.py
index ad62f2c..79bced6 100644
--- a/glance/db/sqlalchemy/migrate_repo/versions/036_rename_metadef_schema_columns.py
+++ b/glance/db/sqlalchemy/migrate_repo/versions/036_rename_metadef_schema_columns.py
@@ -23,12 +23,3 @@ def upgrade(migrate_engine):
23 23
24 metadef_properties = Table('metadef_properties', meta, autoload=True) 24 metadef_properties = Table('metadef_properties', meta, autoload=True)
25 metadef_properties.c.schema.alter(name='json_schema') 25 metadef_properties.c.schema.alter(name='json_schema')
26
27
28def downgrade(migrate_engine):
29 meta = MetaData(bind=migrate_engine)
30 metadef_objects = Table('metadef_objects', meta, autoload=True)
31 metadef_objects.c.json_schema.alter(name='schema')
32
33 metadef_properties = Table('metadef_properties', meta, autoload=True)
34 metadef_properties.c.json_schema.alter(name='schema')
diff --git a/glance/db/sqlalchemy/migrate_repo/versions/037_add_changes_to_satisfy_models.py b/glance/db/sqlalchemy/migrate_repo/versions/037_add_changes_to_satisfy_models.py
index fae8875..0eba966 100644
--- a/glance/db/sqlalchemy/migrate_repo/versions/037_add_changes_to_satisfy_models.py
+++ b/glance/db/sqlalchemy/migrate_repo/versions/037_add_changes_to_satisfy_models.py
@@ -11,8 +11,8 @@
11# under the License. 11# under the License.
12 12
13import sqlalchemy 13import sqlalchemy
14from sqlalchemy import Table, Index, UniqueConstraint, Sequence 14from sqlalchemy import Table, Index, UniqueConstraint
15from sqlalchemy.schema import (AddConstraint, DropConstraint, CreateIndex, 15from sqlalchemy.schema import (AddConstraint, DropConstraint,
16 ForeignKeyConstraint) 16 ForeignKeyConstraint)
17from sqlalchemy import sql 17from sqlalchemy import sql
18from sqlalchemy import update 18from sqlalchemy import update
@@ -82,42 +82,3 @@ def upgrade(migrate_engine):
82 if len(image_locations.foreign_keys) == 0: 82 if len(image_locations.foreign_keys) == 0:
83 migrate_engine.execute(AddConstraint(ForeignKeyConstraint( 83 migrate_engine.execute(AddConstraint(ForeignKeyConstraint(
84 [image_locations.c.image_id], [images.c.id]))) 84 [image_locations.c.image_id], [images.c.id])))
85
86
87def downgrade(migrate_engine):
88 meta = sqlalchemy.MetaData()
89 meta.bind = migrate_engine
90
91 if migrate_engine.name not in ['mysql', 'postgresql']:
92 return
93
94 image_properties = Table('image_properties', meta, autoload=True)
95 image_members = Table('image_members', meta, autoload=True)
96 images = Table('images', meta, autoload=True)
97
98 if migrate_engine.name == 'postgresql':
99 constraint = UniqueConstraint(image_properties.c.image_id,
100 image_properties.c.name,
101 name='ix_image_properties_image_id_name')
102 migrate_engine.execute(DropConstraint(constraint))
103
104 constraint = UniqueConstraint(image_properties.c.image_id,
105 image_properties.c.name)
106 migrate_engine.execute(AddConstraint(constraint))
107
108 index = Index('ix_image_properties_image_id_name',
109 image_properties.c.image_id,
110 image_properties.c.name)
111 migrate_engine.execute(CreateIndex(index))
112
113 images.c.id.alter(server_default=Sequence('images_id_seq')
114 .next_value())
115
116 if migrate_engine.name == 'mysql':
117 constraint = UniqueConstraint(image_properties.c.image_id,
118 image_properties.c.name,
119 name='image_id')
120 migrate_engine.execute(AddConstraint(constraint))
121
122 image_members.c.status.alter(nullable=True, server_default=None)
123 images.c.protected.alter(nullable=True, server_default=None)
diff --git a/glance/db/sqlalchemy/migrate_repo/versions/037_sqlite_downgrade.sql b/glance/db/sqlalchemy/migrate_repo/versions/037_sqlite_downgrade.sql
deleted file mode 100644
index ac4d6e9..0000000
--- a/glance/db/sqlalchemy/migrate_repo/versions/037_sqlite_downgrade.sql
+++ /dev/null
@@ -1,147 +0,0 @@
1CREATE TEMPORARY TABLE images_backup (
2 id VARCHAR(36) NOT NULL,
3 name VARCHAR(255),
4 size INTEGER,
5 status VARCHAR(30) NOT NULL,
6 is_public BOOLEAN NOT NULL,
7 created_at DATETIME NOT NULL,
8 updated_at DATETIME,
9 deleted_at DATETIME,
10 deleted BOOLEAN NOT NULL,
11 disk_format VARCHAR(20),
12 container_format VARCHAR(20),
13 checksum VARCHAR(32),
14 owner VARCHAR(255),
15 min_disk INTEGER,
16 min_ram INTEGER,
17 protected BOOLEAN,
18 virtual_size INTEGER,
19 PRIMARY KEY (id),
20 CHECK (is_public IN (0, 1)),
21 CHECK (deleted IN (0, 1))
22);
23
24INSERT INTO images_backup
25 SELECT id, name, size, status, is_public, created_at, updated_at, deleted_at, deleted, disk_format, container_format, checksum, owner, min_disk, min_ram, virtual_size, protected
26 FROM images;
27
28DROP TABLE images;
29
30CREATE TABLE images (
31 id VARCHAR(36) NOT NULL,
32 name VARCHAR(255),
33 size INTEGER,
34 status VARCHAR(30) NOT NULL,
35 is_public BOOLEAN NOT NULL,
36 created_at DATETIME NOT NULL,
37 updated_at DATETIME,
38 deleted_at DATETIME,
39 deleted BOOLEAN NOT NULL,
40 disk_format VARCHAR(20),
41 container_format VARCHAR(20),
42 checksum VARCHAR(32),
43 owner VARCHAR(255),
44 min_disk INTEGER NOT NULL,
45 min_ram INTEGER NOT NULL,
46 protected BOOLEAN,
47 virtual_size INTEGER,
48 PRIMARY KEY (id),
49 CHECK (is_public IN (0, 1)),
50 CHECK (deleted IN (0, 1))
51);
52
53CREATE INDEX owner_image_idx ON images (owner);
54CREATE INDEX checksum_image_idx ON images (checksum);
55
56INSERT INTO images
57 SELECT id, name, size, status, is_public, created_at, updated_at, deleted_at, deleted, disk_format, container_format, checksum, owner, min_disk, min_ram, protected, virtual_size
58 FROM images_backup;
59
60DROP TABLE images_backup;
61
62CREATE TEMPORARY TABLE image_members_backup (
63 id INTEGER NOT NULL,
64 image_id VARCHAR(36) NOT NULL,
65 member VARCHAR(255) NOT NULL,
66 can_share BOOLEAN NOT NULL,
67 created_at DATETIME NOT NULL,
68 updated_at DATETIME,
69 deleted_at DATETIME,
70 deleted BOOLEAN NOT NULL,
71 status VARCHAR(20),
72 PRIMARY KEY (id),
73 UNIQUE (image_id, member),
74 CHECK (can_share IN (0, 1)),
75 CHECK (deleted IN (0, 1)),
76 FOREIGN KEY(image_id) REFERENCES images (id)
77);
78
79INSERT INTO image_members_backup
80 SELECT id, image_id, member, can_share, created_at, updated_at, deleted_at, deleted, status
81 FROM image_members;
82
83DROP TABLE image_members;
84
85CREATE TABLE image_members (
86 id INTEGER NOT NULL,
87 image_id VARCHAR(36) NOT NULL,
88 member VARCHAR(255) NOT NULL,
89 can_share BOOLEAN NOT NULL,
90 created_at DATETIME NOT NULL,
91 updated_at DATETIME,
92 deleted_at DATETIME,
93 deleted BOOLEAN NOT NULL,
94 status VARCHAR(20),
95 PRIMARY KEY (id),
96 UNIQUE (image_id, member),
97 CHECK (can_share IN (0, 1)),
98 CHECK (deleted IN (0, 1)),
99 FOREIGN KEY(image_id) REFERENCES images (id)
100);
101
102INSERT INTO image_members
103 SELECT id, image_id, member, can_share, created_at, updated_at, deleted_at, deleted, status
104 FROM image_members_backup;
105
106DROP TABLE image_members_backup;
107
108CREATE TEMPORARY TABLE image_properties_backup (
109 id INTEGER NOT NULL,
110 image_id VARCHAR(36) NOT NULL,
111 name VARCHAR(255) NOT NULL,
112 value TEXT,
113 created_at DATETIME NOT NULL,
114 updated_at DATETIME,
115 deleted_at DATETIME,
116 deleted BOOLEAN NOT NULL,
117 PRIMARY KEY (id)
118);
119
120INSERT INTO image_properties_backup
121 SELECT id, image_id, name, value, created_at, updated_at, deleted_at, deleted
122 FROM image_properties;
123
124DROP TABLE image_properties;
125
126CREATE TABLE image_properties (
127 id INTEGER NOT NULL,
128 image_id VARCHAR(36) NOT NULL,
129 name VARCHAR(255) NOT NULL,
130 value TEXT,
131 created_at DATETIME NOT NULL,
132 updated_at DATETIME,
133 deleted_at DATETIME,
134 deleted BOOLEAN NOT NULL,
135 PRIMARY KEY (id),
136 CHECK (deleted IN (0, 1)),
137 UNIQUE (image_id, name),
138 FOREIGN KEY(image_id) REFERENCES images (id)
139);
140
141CREATE INDEX ix_image_properties_name ON image_properties (name);
142
143INSERT INTO image_properties (id, image_id, name, value, created_at, updated_at, deleted_at, deleted)
144 SELECT id, image_id, name, value, created_at, updated_at, deleted_at, deleted
145 FROM image_properties_backup;
146
147DROP TABLE image_properties_backup;
diff --git a/glance/db/sqlalchemy/migrate_repo/versions/038_add_metadef_tags_table.py b/glance/db/sqlalchemy/migrate_repo/versions/038_add_metadef_tags_table.py
index 9fb3f1f..fced9f1 100644
--- a/glance/db/sqlalchemy/migrate_repo/versions/038_add_metadef_tags_table.py
+++ b/glance/db/sqlalchemy/migrate_repo/versions/038_add_metadef_tags_table.py
@@ -16,7 +16,7 @@ from sqlalchemy.schema import (
16 Column, Index, MetaData, Table, UniqueConstraint) # noqa 16 Column, Index, MetaData, Table, UniqueConstraint) # noqa
17 17
18from glance.db.sqlalchemy.migrate_repo.schema import ( 18from glance.db.sqlalchemy.migrate_repo.schema import (
19 DateTime, Integer, String, create_tables, drop_tables) # noqa 19 DateTime, Integer, String, create_tables) # noqa
20 20
21 21
22def define_metadef_tags_table(meta): 22def define_metadef_tags_table(meta):
@@ -49,10 +49,3 @@ def upgrade(migrate_engine):
49 meta.bind = migrate_engine 49 meta.bind = migrate_engine
50 tables = [define_metadef_tags_table(meta)] 50 tables = [define_metadef_tags_table(meta)]
51 create_tables(tables) 51 create_tables(tables)
52
53
54def downgrade(migrate_engine):
55 meta = MetaData()
56 meta.bind = migrate_engine
57 tables = [define_metadef_tags_table(meta)]
58 drop_tables(tables)
diff --git a/glance/db/sqlalchemy/migrate_repo/versions/039_add_changes_to_satisfy_models_metadef.py b/glance/db/sqlalchemy/migrate_repo/versions/039_add_changes_to_satisfy_models_metadef.py
index 0475b76..0466f3a 100644
--- a/glance/db/sqlalchemy/migrate_repo/versions/039_add_changes_to_satisfy_models_metadef.py
+++ b/glance/db/sqlalchemy/migrate_repo/versions/039_add_changes_to_satisfy_models_metadef.py
@@ -14,7 +14,7 @@ import migrate
14import sqlalchemy 14import sqlalchemy
15from sqlalchemy import inspect 15from sqlalchemy import inspect
16from sqlalchemy import (Table, Index, UniqueConstraint) 16from sqlalchemy import (Table, Index, UniqueConstraint)
17from sqlalchemy.schema import (AddConstraint, DropConstraint) 17from sqlalchemy.schema import (DropConstraint)
18 18
19 19
20def _change_db2_unique_constraint(operation_type, constraint_name, *columns): 20def _change_db2_unique_constraint(operation_type, constraint_name, *columns):
@@ -194,173 +194,3 @@ def upgrade(migrate_engine):
194 # origional logic for other database backends. 194 # origional logic for other database backends.
195 for (constraint_name, cols) in constraints: 195 for (constraint_name, cols) in constraints:
196 _change_db2_unique_constraint('create', constraint_name, *cols) 196 _change_db2_unique_constraint('create', constraint_name, *cols)
197
198
199def downgrade(migrate_engine):
200 meta = sqlalchemy.MetaData()
201 meta.bind = migrate_engine
202 inspector = inspect(migrate_engine)
203
204 metadef_namespaces = Table('metadef_namespaces', meta, autoload=True)
205 metadef_properties = Table('metadef_properties', meta, autoload=True)
206 metadef_objects = Table('metadef_objects', meta, autoload=True)
207 metadef_ns_res_types = Table('metadef_namespace_resource_types',
208 meta, autoload=True)
209 metadef_resource_types = Table('metadef_resource_types', meta,
210 autoload=True)
211 metadef_tags = Table('metadef_tags', meta, autoload=True)
212
213 constraints = [('ix_namespaces_namespace',
214 [metadef_namespaces.c.namespace]),
215 ('ix_objects_namespace_id_name',
216 [metadef_objects.c.namespace_id,
217 metadef_objects.c.name]),
218 ('ix_metadef_properties_namespace_id_name',
219 [metadef_properties.c.namespace_id,
220 metadef_properties.c.name])]
221 metadef_tags_constraints = inspector.get_unique_constraints('metadef_tags')
222 for constraint in metadef_tags_constraints:
223 if set(constraint['column_names']) == set(['namespace_id', 'name']):
224 constraints.append((constraint['name'],
225 [metadef_tags.c.namespace_id,
226 metadef_tags.c.name]))
227
228 if meta.bind.name == "ibm_db_sa":
229 # For db2, the following constraints need to be dropped first,
230 # otherwise the index like ix_metadef_ns_res_types_namespace_id
231 # will fail to drop. These constraints will be added back at
232 # the end. It should not affect the origional logic for other
233 # database backends.
234 for (constraint_name, cols) in constraints:
235 _change_db2_unique_constraint('drop', constraint_name, *cols)
236 else:
237 Index('ix_namespaces_namespace',
238 metadef_namespaces.c.namespace).create()
239
240 Index('ix_objects_namespace_id_name', metadef_objects.c.namespace_id,
241 metadef_objects.c.name).create()
242
243 Index('ix_metadef_properties_namespace_id_name',
244 metadef_properties.c.namespace_id,
245 metadef_properties.c.name).create()
246
247 Index('ix_metadef_tags_name', metadef_tags.c.name).drop()
248
249 Index('ix_metadef_tags_namespace_id', metadef_tags.c.namespace_id,
250 metadef_tags.c.name).drop()
251
252 if migrate_engine.name != 'sqlite':
253 fkc = migrate.ForeignKeyConstraint([metadef_tags.c.namespace_id],
254 [metadef_namespaces.c.id])
255 fkc.drop()
256
257 if meta.bind.name != "ibm_db_sa":
258 # This index would not be created when it is db2 backend.
259 Index('ix_tags_namespace_id_name', metadef_tags.c.namespace_id,
260 metadef_tags.c.name).create()
261 else:
262 # NOTE(ochuprykov): fkc can't be dropped via `migrate` in sqlite,so it
263 # is necessary to recreate table manually and populate it with data
264 temp = Table('temp_', meta, *(
265 [c.copy() for c in metadef_tags.columns]))
266 temp.create()
267 migrate_engine.execute('insert into temp_ select * from metadef_tags')
268 metadef_tags.drop()
269 migrate_engine.execute('alter table temp_ rename to metadef_tags')
270
271 # Refresh old metadata for this table
272 meta = sqlalchemy.MetaData()
273 meta.bind = migrate_engine
274 metadef_tags = Table('metadef_tags', meta, autoload=True)
275
276 Index('ix_tags_namespace_id_name', metadef_tags.c.namespace_id,
277 metadef_tags.c.name).create()
278
279 uc = migrate.UniqueConstraint(metadef_tags.c.namespace_id,
280 metadef_tags.c.name)
281 uc.create()
282
283 if migrate_engine.name == 'mysql':
284 constraint = UniqueConstraint(metadef_properties.c.namespace_id,
285 metadef_properties.c.name,
286 name='namespace_id')
287 migrate_engine.execute(AddConstraint(constraint))
288
289 constraint = UniqueConstraint(metadef_objects.c.namespace_id,
290 metadef_objects.c.name,
291 name='namespace_id')
292 migrate_engine.execute(AddConstraint(constraint))
293
294 constraint = UniqueConstraint(metadef_ns_res_types.c.resource_type_id,
295 metadef_ns_res_types.c.namespace_id,
296 name='resource_type_id')
297 migrate_engine.execute(AddConstraint(constraint))
298
299 constraint = UniqueConstraint(metadef_namespaces.c.namespace,
300 name='namespace')
301 migrate_engine.execute(AddConstraint(constraint))
302
303 constraint = UniqueConstraint(metadef_resource_types.c.name,
304 name='name')
305 migrate_engine.execute(AddConstraint(constraint))
306
307 if migrate_engine.name == 'postgresql':
308 constraint = UniqueConstraint(
309 metadef_objects.c.namespace_id,
310 metadef_objects.c.name)
311 migrate_engine.execute(AddConstraint(constraint))
312
313 constraint = UniqueConstraint(
314 metadef_properties.c.namespace_id,
315 metadef_properties.c.name)
316 migrate_engine.execute(AddConstraint(constraint))
317
318 constraint = UniqueConstraint(
319 metadef_namespaces.c.namespace)
320 migrate_engine.execute(AddConstraint(constraint))
321
322 constraint = UniqueConstraint(
323 metadef_resource_types.c.name)
324 migrate_engine.execute(AddConstraint(constraint))
325
326 constraint = UniqueConstraint(
327 metadef_tags.c.namespace_id,
328 metadef_tags.c.name,
329 name='metadef_tags_namespace_id_name_key')
330 migrate_engine.execute(AddConstraint(constraint))
331
332 if migrate_engine.name == 'mysql':
333 fkc = migrate.ForeignKeyConstraint(
334 [metadef_ns_res_types.c.resource_type_id],
335 [metadef_namespaces.c.id],
336 name='metadef_namespace_resource_types_ibfk_2')
337 fkc.drop()
338
339 Index('ix_metadef_ns_res_types_namespace_id',
340 metadef_ns_res_types.c.namespace_id).drop()
341
342 fkc.create()
343 else:
344 Index('ix_metadef_ns_res_types_namespace_id',
345 metadef_ns_res_types.c.namespace_id).drop()
346
347 Index('ix_metadef_namespaces_namespace',
348 metadef_namespaces.c.namespace).drop()
349
350 Index('ix_metadef_namespaces_owner', metadef_namespaces.c.owner).drop()
351
352 Index('ix_metadef_objects_name', metadef_objects.c.name).drop()
353
354 Index('ix_metadef_objects_namespace_id',
355 metadef_objects.c.namespace_id).drop()
356
357 Index('ix_metadef_properties_name', metadef_properties.c.name).drop()
358
359 Index('ix_metadef_properties_namespace_id',
360 metadef_properties.c.namespace_id).drop()
361
362 if meta.bind.name == "ibm_db_sa":
363 # For db2, add these constraints back. It should not affect the
364 # origional logic for other database backends.
365 for (constraint_name, cols) in constraints:
366 _change_db2_unique_constraint('create', constraint_name, *cols)
diff --git a/glance/db/sqlalchemy/migrate_repo/versions/042_add_changes_to_reinstall_unique_metadef_constraints.py b/glance/db/sqlalchemy/migrate_repo/versions/042_add_changes_to_reinstall_unique_metadef_constraints.py
index 836e953..af7863a 100644
--- a/glance/db/sqlalchemy/migrate_repo/versions/042_add_changes_to_reinstall_unique_metadef_constraints.py
+++ b/glance/db/sqlalchemy/migrate_repo/versions/042_add_changes_to_reinstall_unique_metadef_constraints.py
@@ -231,27 +231,6 @@ def _update_sqlite_namespace_id_name_constraint(metadef, metadef_namespaces,
231 name=new_fk_name).create() 231 name=new_fk_name).create()
232 232
233 233
234def _downgrade_sqlite_namespace_id_name_constraint(metadef,
235 metadef_namespaces,
236 constraint_name,
237 fk_name):
238 migrate.UniqueConstraint(
239 metadef.c.namespace_id,
240 metadef.c.name,
241 name=constraint_name).drop()
242 migrate.UniqueConstraint(
243 metadef.c.namespace_id,
244 metadef.c.name).create()
245
246 migrate.ForeignKeyConstraint(
247 [metadef.c.namespace_id],
248 [metadef_namespaces.c.id],
249 name=fk_name).drop()
250 migrate.ForeignKeyConstraint(
251 [metadef.c.namespace_id],
252 [metadef_namespaces.c.id]).create()
253
254
255def _drop_unique_constraint_if_exists(inspector, table_name, metadef): 234def _drop_unique_constraint_if_exists(inspector, table_name, metadef):
256 name = _get_unique_constraint_name(inspector, 235 name = _get_unique_constraint_name(inspector,
257 table_name, 236 table_name,
@@ -281,24 +260,6 @@ def _drop_index_with_fk_constraint(metadef, metadef_namespaces,
281 fkc.create() 260 fkc.create()
282 261
283 262
284def _downgrade_constraint_with_fk(metadef, metadef_namespaces,
285 constraint_name,
286 fk_curr_name, fk_next_name):
287
288 fkc = migrate.ForeignKeyConstraint([metadef.c.namespace_id],
289 [metadef_namespaces.c.id],
290 name=fk_curr_name)
291 fkc.drop()
292
293 migrate.UniqueConstraint(metadef.c.namespace_id, metadef.c.name,
294 name=constraint_name).drop()
295
296 fkc = migrate.ForeignKeyConstraint([metadef.c.namespace_id],
297 [metadef_namespaces.c.id],
298 name=fk_next_name)
299 fkc.create()
300
301
302def _get_unique_constraint_name(inspector, table_name, columns): 263def _get_unique_constraint_name(inspector, table_name, columns):
303 constraints = inspector.get_unique_constraints(table_name) 264 constraints = inspector.get_unique_constraints(table_name)
304 for constraint in constraints: 265 for constraint in constraints:
@@ -479,126 +440,3 @@ def upgrade(migrate_engine):
479 migrate.UniqueConstraint( 440 migrate.UniqueConstraint(
480 metadef_resource_types.c.name, 441 metadef_resource_types.c.name,
481 name='uq_metadef_resource_types_name').create() 442 name='uq_metadef_resource_types_name').create()
482
483
484def downgrade(migrate_engine):
485 meta = sqlalchemy.MetaData()
486 meta.bind = migrate_engine
487
488 # ORM tables
489 metadef_namespaces = Table('metadef_namespaces', meta, autoload=True)
490 metadef_objects = Table('metadef_objects', meta, autoload=True)
491 metadef_properties = Table('metadef_properties', meta, autoload=True)
492 metadef_tags = Table('metadef_tags', meta, autoload=True)
493 metadef_resource_types = Table('metadef_resource_types', meta,
494 autoload=True)
495 metadef_ns_res_types = Table('metadef_namespace_resource_types',
496 meta, autoload=True)
497
498 # Drop the unique constraints
499 if migrate_engine.name == 'sqlite':
500 # Objects
501 _downgrade_sqlite_namespace_id_name_constraint(
502 metadef_objects, metadef_namespaces,
503 'uq_metadef_objects_namespace_id_name',
504 'metadef_objects_fk_1')
505
506 # Properties
507 _downgrade_sqlite_namespace_id_name_constraint(
508 metadef_properties, metadef_namespaces,
509 'uq_metadef_properties_namespace_id_name',
510 'metadef_properties_fk_1')
511
512 # Tags
513 _downgrade_sqlite_namespace_id_name_constraint(
514 metadef_tags, metadef_namespaces,
515 'uq_metadef_tags_namespace_id_name',
516 'metadef_tags_fk_1')
517
518 # Namespaces
519 migrate.UniqueConstraint(
520 metadef_namespaces.c.namespace,
521 name='uq_metadef_namespaces_namespace').drop()
522 migrate.UniqueConstraint(
523 metadef_namespaces.c.namespace).create()
524
525 # ResourceTypes
526 migrate.UniqueConstraint(
527 metadef_resource_types.c.name,
528 name='uq_metadef_resource_types_name').drop()
529 migrate.UniqueConstraint(
530 metadef_resource_types.c.name).create()
531 else:
532 # For mysql, must drop foreign key constraints before dropping the
533 # unique constraint. So drop the fkc, then drop the constraints,
534 # then recreate the fkc.
535
536 # Objects
537 _downgrade_constraint_with_fk(
538 metadef_objects, metadef_namespaces,
539 'uq_metadef_objects_namespace_id_name',
540 'metadef_objects_fk_1', None)
541
542 # Properties
543 _downgrade_constraint_with_fk(
544 metadef_properties, metadef_namespaces,
545 'uq_metadef_properties_namespace_id_name',
546 'metadef_properties_fk_1', None)
547
548 # Tags
549 _downgrade_constraint_with_fk(
550 metadef_tags, metadef_namespaces,
551 'uq_metadef_tags_namespace_id_name',
552 'metadef_tags_fk_1', 'metadef_tags_namespace_id_fkey')
553
554 # Namespaces
555 migrate.UniqueConstraint(
556 metadef_namespaces.c.namespace,
557 name='uq_metadef_namespaces_namespace').drop()
558
559 # Resource_types
560 migrate.UniqueConstraint(
561 metadef_resource_types.c.name,
562 name='uq_metadef_resource_types_name').drop()
563
564 # Create dropped unique constraints as bad, non-unique indexes
565 Index('ix_metadef_objects_namespace_id',
566 metadef_objects.c.namespace_id).create()
567 Index('ix_metadef_properties_namespace_id',
568 metadef_properties.c.namespace_id).create()
569
570 # These need to be done before the metadef_tags and metadef_namespaces
571 # unique constraints are created to avoid 'tuple out of range' errors
572 # in db2.
573 Index('ix_metadef_tags_namespace_id',
574 metadef_tags.c.namespace_id,
575 metadef_tags.c.name).create()
576 Index('ix_metadef_namespaces_namespace',
577 metadef_namespaces.c.namespace).create()
578
579 # Create these everywhere, except for db2
580 if migrate_engine.name != 'ibm_db_sa':
581 Index('ix_metadef_resource_types_name',
582 metadef_resource_types.c.name).create()
583 Index('ix_metadef_ns_res_types_res_type_id_ns_id',
584 metadef_ns_res_types.c.resource_type_id,
585 metadef_ns_res_types.c.namespace_id).create()
586 else:
587 # Recreate the badly named unique constraints in db2
588 migrate.UniqueConstraint(
589 metadef_namespaces.c.namespace,
590 name='ix_namespaces_namespace').create()
591 migrate.UniqueConstraint(
592 metadef_objects.c.namespace_id,
593 metadef_objects.c.name,
594 name='ix_objects_namespace_id_name').create()
595 migrate.UniqueConstraint(
596 metadef_properties.c.namespace_id,
597 metadef_properties.c.name,
598 name='ix_metadef_properties_namespace_id_name').create()
599 migrate.UniqueConstraint(
600 metadef_tags.c.namespace_id,
601 metadef_tags.c.name).create()
602 migrate.UniqueConstraint(
603 metadef_resource_types.c.name,
604 name='ix_metadef_resource_types_name').create()
diff --git a/glance/db/sqlalchemy/migrate_repo/versions/044_update_metadef_os_nova_server.py b/glance/db/sqlalchemy/migrate_repo/versions/044_update_metadef_os_nova_server.py
index 26daf87..f749062 100644
--- a/glance/db/sqlalchemy/migrate_repo/versions/044_update_metadef_os_nova_server.py
+++ b/glance/db/sqlalchemy/migrate_repo/versions/044_update_metadef_os_nova_server.py
@@ -24,8 +24,3 @@ def upgrade(migrate_engine):
24 24
25 resource_types_table.update(values={'name': 'OS::Nova::Server'}).where( 25 resource_types_table.update(values={'name': 'OS::Nova::Server'}).where(
26 resource_types_table.c.name == 'OS::Nova::Instance').execute() 26 resource_types_table.c.name == 'OS::Nova::Instance').execute()
27
28
29def downgrade(migrate_engine):
30 # NOTE(TravT): This is a bug fix (1537903). It shouldn't be downgraded.
31 return
diff --git a/glance/tests/unit/test_manage.py b/glance/tests/unit/test_manage.py
index 2ad97ae..16a76ab 100644
--- a/glance/tests/unit/test_manage.py
+++ b/glance/tests/unit/test_manage.py
@@ -94,13 +94,6 @@ class TestLegacyManage(TestManageBase):
94 db_api.get_engine(), 94 db_api.get_engine(),
95 db_migration.MIGRATE_REPO_PATH, '20') 95 db_migration.MIGRATE_REPO_PATH, '20')
96 96
97 @mock.patch.object(migration, 'db_sync')
98 def test_legacy_db_downgrade_version(self, db_sync):
99 self._main_test_helper(['glance.cmd.manage', 'db_downgrade', '20'],
100 migration.db_sync,
101 db_api.get_engine(),
102 db_migration.MIGRATE_REPO_PATH, '20')
103
104 def test_db_metadefs_unload(self): 97 def test_db_metadefs_unload(self):
105 db_metadata.db_unload_metadefs = mock.Mock() 98 db_metadata.db_unload_metadefs = mock.Mock()
106 self._main_test_helper(['glance.cmd.manage', 'db_unload_metadefs'], 99 self._main_test_helper(['glance.cmd.manage', 'db_unload_metadefs'],
@@ -207,13 +200,6 @@ class TestManage(TestManageBase):
207 db_api.get_engine(), 200 db_api.get_engine(),
208 db_migration.MIGRATE_REPO_PATH, '20') 201 db_migration.MIGRATE_REPO_PATH, '20')
209 202
210 @mock.patch.object(migration, 'db_sync')
211 def test_db_downgrade_version(self, db_sync):
212 self._main_test_helper(['glance.cmd.manage', 'db', 'downgrade', '20'],
213 migration.db_sync,
214 db_api.get_engine(),
215 db_migration.MIGRATE_REPO_PATH, '20')
216
217 def test_db_metadefs_unload(self): 203 def test_db_metadefs_unload(self):
218 db_metadata.db_unload_metadefs = mock.Mock() 204 db_metadata.db_unload_metadefs = mock.Mock()
219 self._main_test_helper(['glance.cmd.manage', 'db', 'unload_metadefs'], 205 self._main_test_helper(['glance.cmd.manage', 'db', 'unload_metadefs'],
diff --git a/glance/tests/unit/test_migrations.py b/glance/tests/unit/test_migrations.py
index 0c8b71e..6262105 100644
--- a/glance/tests/unit/test_migrations.py
+++ b/glance/tests/unit/test_migrations.py
@@ -38,7 +38,6 @@ from oslo_utils import uuidutils
38# NOTE(jokke): simplified transition to py3, behaves like py2 xrange 38# NOTE(jokke): simplified transition to py3, behaves like py2 xrange
39from six.moves import range 39from six.moves import range
40import sqlalchemy 40import sqlalchemy
41from sqlalchemy import inspect
42import sqlalchemy.types as types 41import sqlalchemy.types as types
43 42
44from glance.common import crypt 43from glance.common import crypt
@@ -47,9 +46,11 @@ from glance.common import timeutils
47from glance.db import migration 46from glance.db import migration
48from glance.db.sqlalchemy import migrate_repo 47from glance.db.sqlalchemy import migrate_repo
49from glance.db.sqlalchemy.migrate_repo.schema import from_migration_import 48from glance.db.sqlalchemy.migrate_repo.schema import from_migration_import
49from glance.db.sqlalchemy.migrate_repo import versions
50from glance.db.sqlalchemy import models 50from glance.db.sqlalchemy import models
51from glance.db.sqlalchemy import models_glare 51from glance.db.sqlalchemy import models_glare
52from glance.db.sqlalchemy import models_metadef 52from glance.db.sqlalchemy import models_metadef
53import glance.tests.utils as test_utils
53 54
54from glance.i18n import _ 55from glance.i18n import _
55 56
@@ -366,44 +367,6 @@ class MigrationsMixin(test_migrations.WalkVersionsMixin):
366 if row['name'] == 'ramdisk_id': 367 if row['name'] == 'ramdisk_id':
367 self.assertEqual(row['value'], uuids['ramdisk']) 368 self.assertEqual(row['value'], uuids['ramdisk'])
368 369
369 def _post_downgrade_012(self, engine):
370 images = db_utils.get_table(engine, 'images')
371 image_members = db_utils.get_table(engine, 'image_members')
372 image_properties = db_utils.get_table(engine, 'image_properties')
373
374 # Find kernel, ramdisk and normal images. Make sure id has been
375 # changed back to an integer
376 ids = {}
377 for name in ('kernel', 'ramdisk', 'normal'):
378 image_name = '%s migration 012 test' % name
379 rows = images.select().where(
380 images.c.name == image_name).execute().fetchall()
381 self.assertEqual(1, len(rows))
382
383 row = rows[0]
384 self.assertFalse(uuidutils.is_uuid_like(row['id']))
385
386 ids[name] = row['id']
387
388 # Find all image_members to ensure image_id has been updated
389 results = image_members.select().where(
390 image_members.c.image_id == ids['normal']).execute().fetchall()
391 self.assertEqual(1, len(results))
392
393 # Find all image_properties to ensure image_id has been updated
394 # as well as ensure kernel_id and ramdisk_id values have been
395 # updated too
396 results = image_properties.select().where(
397 image_properties.c.image_id == ids['normal']).execute().fetchall()
398 self.assertEqual(2, len(results))
399 for row in results:
400 self.assertIn(row['name'], ('kernel_id', 'ramdisk_id'))
401
402 if row['name'] == 'kernel_id':
403 self.assertEqual(row['value'], str(ids['kernel']))
404 if row['name'] == 'ramdisk_id':
405 self.assertEqual(row['value'], str(ids['ramdisk']))
406
407 def _assert_invalid_swift_uri_raises_bad_store_uri(self, 370 def _assert_invalid_swift_uri_raises_bad_store_uri(self,
408 legacy_parse_uri_fn): 371 legacy_parse_uri_fn):
409 invalid_uri = ('swift://http://acct:usr:pass@example.com' 372 invalid_uri = ('swift://http://acct:usr:pass@example.com'
@@ -718,18 +681,6 @@ class MigrationsMixin(test_migrations.WalkVersionsMixin):
718 681
719 self.assertIn((owner_index, columns), index_data) 682 self.assertIn((owner_index, columns), index_data)
720 683
721 def _post_downgrade_028(self, engine):
722 owner_index = "owner_image_idx"
723 columns = ["owner"]
724
725 images_table = db_utils.get_table(engine, 'images')
726
727 index_data = [(idx.name, idx.columns.keys())
728 for idx in images_table.indexes
729 if idx.name == owner_index]
730
731 self.assertNotIn((owner_index, columns), index_data)
732
733 def _pre_upgrade_029(self, engine): 684 def _pre_upgrade_029(self, engine):
734 image_locations = db_utils.get_table(engine, 'image_locations') 685 image_locations = db_utils.get_table(engine, 'image_locations')
735 686
@@ -774,19 +725,6 @@ class MigrationsMixin(test_migrations.WalkVersionsMixin):
774 d = jsonutils.loads(r['meta_data']) 725 d = jsonutils.loads(r['meta_data'])
775 self.assertEqual(d, meta_data) 726 self.assertEqual(d, meta_data)
776 727
777 def _post_downgrade_029(self, engine):
778 image_id = 'fake_029_id'
779
780 image_locations = db_utils.get_table(engine, 'image_locations')
781
782 records = image_locations.select().where(
783 image_locations.c.image_id == image_id).execute().fetchall()
784
785 for r in records:
786 md = r['meta_data']
787 d = pickle.loads(md)
788 self.assertIsInstance(d, dict)
789
790 def _check_030(self, engine, data): 728 def _check_030(self, engine, data):
791 table = "tasks" 729 table = "tasks"
792 index_type = ('ix_tasks_type', ['type']) 730 index_type = ('ix_tasks_type', ['type'])
@@ -828,10 +766,6 @@ class MigrationsMixin(test_migrations.WalkVersionsMixin):
828 col_data = [col.name for col in tasks_table.columns] 766 col_data = [col.name for col in tasks_table.columns]
829 self.assertEqual(expected, col_data) 767 self.assertEqual(expected, col_data)
830 768
831 def _post_downgrade_030(self, engine):
832 self.assertRaises(sqlalchemy.exc.NoSuchTableError,
833 db_utils.get_table, engine, 'tasks')
834
835 def _pre_upgrade_031(self, engine): 769 def _pre_upgrade_031(self, engine):
836 images = db_utils.get_table(engine, 'images') 770 images = db_utils.get_table(engine, 'images')
837 now = datetime.datetime.now() 771 now = datetime.datetime.now()
@@ -928,26 +862,6 @@ class MigrationsMixin(test_migrations.WalkVersionsMixin):
928 self.assertNotIn('result', tasks_table.c) 862 self.assertNotIn('result', tasks_table.c)
929 self.assertNotIn('message', tasks_table.c) 863 self.assertNotIn('message', tasks_table.c)
930 864
931 def _post_downgrade_032(self, engine):
932 self.assertRaises(sqlalchemy.exc.NoSuchTableError,
933 db_utils.get_table, engine, 'task_info')
934
935 tasks_table = db_utils.get_table(engine, 'tasks')
936 records = tasks_table.select().execute().fetchall()
937 self.assertEqual(2, len(records))
938
939 tasks = {t.id: t for t in records}
940
941 task_1 = tasks.get('task-1')
942 self.assertEqual('some input', task_1.input)
943 self.assertEqual('successful', task_1.result)
944 self.assertIsNone(task_1.message)
945
946 task_2 = tasks.get('task-2')
947 self.assertIsNone(task_2.input)
948 self.assertIsNone(task_2.result)
949 self.assertIsNone(task_2.message)
950
951 def _pre_upgrade_033(self, engine): 865 def _pre_upgrade_033(self, engine):
952 images = db_utils.get_table(engine, 'images') 866 images = db_utils.get_table(engine, 'images')
953 image_locations = db_utils.get_table(engine, 'image_locations') 867 image_locations = db_utils.get_table(engine, 'image_locations')
@@ -997,10 +911,6 @@ class MigrationsMixin(test_migrations.WalkVersionsMixin):
997 self.assertIn('status', r[0]) 911 self.assertIn('status', r[0])
998 self.assertEqual(status_list[idx], r[0]['status']) 912 self.assertEqual(status_list[idx], r[0]['status'])
999 913
1000 def _post_downgrade_033(self, engine):
1001 image_locations = db_utils.get_table(engine, 'image_locations')
1002 self.assertNotIn('status', image_locations.c)
1003
1004 def _pre_upgrade_034(self, engine): 914 def _pre_upgrade_034(self, engine):
1005 images = db_utils.get_table(engine, 'images') 915 images = db_utils.get_table(engine, 'images')
1006 916
@@ -1024,10 +934,6 @@ class MigrationsMixin(test_migrations.WalkVersionsMixin):
1024 .execute().fetchone()) 934 .execute().fetchone())
1025 self.assertIsNone(result.virtual_size) 935 self.assertIsNone(result.virtual_size)
1026 936
1027 def _post_downgrade_034(self, engine):
1028 images = db_utils.get_table(engine, 'images')
1029 self.assertNotIn('virtual_size', images.c)
1030
1031 def _pre_upgrade_035(self, engine): 937 def _pre_upgrade_035(self, engine):
1032 self.assertRaises(sqlalchemy.exc.NoSuchTableError, 938 self.assertRaises(sqlalchemy.exc.NoSuchTableError,
1033 db_utils.get_table, engine, 'metadef_namespaces') 939 db_utils.get_table, engine, 'metadef_namespaces')
@@ -1137,19 +1043,6 @@ class MigrationsMixin(test_migrations.WalkVersionsMixin):
1137 col_data = [col.name for col in table.columns] 1043 col_data = [col.name for col in table.columns]
1138 self.assertEqual(expected_cols, col_data) 1044 self.assertEqual(expected_cols, col_data)
1139 1045
1140 def _post_downgrade_035(self, engine):
1141 self.assertRaises(sqlalchemy.exc.NoSuchTableError,
1142 db_utils.get_table, engine, 'metadef_namespaces')
1143 self.assertRaises(sqlalchemy.exc.NoSuchTableError,
1144 db_utils.get_table, engine, 'metadef_properties')
1145 self.assertRaises(sqlalchemy.exc.NoSuchTableError,
1146 db_utils.get_table, engine, 'metadef_objects')
1147 self.assertRaises(sqlalchemy.exc.NoSuchTableError,
1148 db_utils.get_table, engine, 'metadef_resource_types')
1149 self.assertRaises(sqlalchemy.exc.NoSuchTableError,
1150 db_utils.get_table, engine,
1151 'metadef_namespace_resource_types')
1152
1153 def _pre_upgrade_036(self, engine): 1046 def _pre_upgrade_036(self, engine):
1154 meta = sqlalchemy.MetaData() 1047 meta = sqlalchemy.MetaData()
1155 meta.bind = engine 1048 meta.bind = engine
@@ -1206,34 +1099,6 @@ class MigrationsMixin(test_migrations.WalkVersionsMixin):
1206 col_data = [col.name for col in table.columns] 1099 col_data = [col.name for col in table.columns]
1207 self.assertEqual(expected_cols, col_data) 1100 self.assertEqual(expected_cols, col_data)
1208 1101
1209 def _post_downgrade_036(self, engine):
1210 meta = sqlalchemy.MetaData()
1211 meta.bind = engine
1212
1213 # metadef_objects
1214 table = sqlalchemy.Table("metadef_objects", meta, autoload=True)
1215 expected_cols = [u'id',
1216 u'namespace_id',
1217 u'name',
1218 u'description',
1219 u'required',
1220 u'schema',
1221 u'created_at',
1222 u'updated_at']
1223 col_data = [col.name for col in table.columns]
1224 self.assertEqual(expected_cols, col_data)
1225
1226 # metadef_properties
1227 table = sqlalchemy.Table("metadef_properties", meta, autoload=True)
1228 expected_cols = [u'id',
1229 u'namespace_id',
1230 u'name',
1231 u'schema',
1232 u'created_at',
1233 u'updated_at']
1234 col_data = [col.name for col in table.columns]
1235 self.assertEqual(expected_cols, col_data)
1236
1237 def _check_037(self, engine, data): 1102 def _check_037(self, engine, data):
1238 if engine.name == 'mysql': 1103 if engine.name == 'mysql':
1239 self.assertFalse(unique_constraint_exist('image_id', 1104 self.assertFalse(unique_constraint_exist('image_id',
@@ -1286,62 +1151,6 @@ class MigrationsMixin(test_migrations.WalkVersionsMixin):
1286 1151
1287 self.assertEqual('pending', image_member['status']) 1152 self.assertEqual('pending', image_member['status'])
1288 1153
1289 def _post_downgrade_037(self, engine):
1290 if engine.name == 'mysql':
1291 self.assertTrue(unique_constraint_exist('image_id',
1292 'image_properties',
1293 engine))
1294
1295 if engine.name == 'postgresql':
1296 self.assertTrue(index_exist('ix_image_properties_image_id_name',
1297 'image_properties', engine))
1298
1299 self.assertFalse(unique_constraint_exist(
1300 'ix_image_properties_image_id_name',
1301 'image_properties',
1302 engine))
1303
1304 image_members = db_utils.get_table(engine, 'image_members')
1305 images = db_utils.get_table(engine, 'images')
1306
1307 self.assertTrue(image_members.c.status.nullable)
1308 self.assertTrue(images.c.protected.nullable)
1309
1310 now = datetime.datetime.now()
1311 temp = dict(
1312 deleted=False,
1313 created_at=now,
1314 status='active',
1315 is_public=True,
1316 min_disk=0,
1317 min_ram=0,
1318 id='fake_image_035_d'
1319 )
1320 images.insert().values(temp).execute()
1321
1322 image = (images.select()
1323 .where(images.c.id == 'fake_image_035_d')
1324 .execute().fetchone())
1325
1326 self.assertIsNone(image['protected'])
1327
1328 temp = dict(
1329 deleted=False,
1330 created_at=now,
1331 image_id='fake_image_035_d',
1332 member='fake_member',
1333 can_share=True,
1334 id=4
1335 )
1336
1337 image_members.insert().values(temp).execute()
1338
1339 image_member = (image_members.select()
1340 .where(image_members.c.id == 4)
1341 .execute().fetchone())
1342
1343 self.assertIsNone(image_member['status'])
1344
1345 def _pre_upgrade_038(self, engine): 1154 def _pre_upgrade_038(self, engine):
1346 self.assertRaises(sqlalchemy.exc.NoSuchTableError, 1155 self.assertRaises(sqlalchemy.exc.NoSuchTableError,
1347 db_utils.get_table, engine, 'metadef_tags') 1156 db_utils.get_table, engine, 'metadef_tags')
@@ -1360,10 +1169,6 @@ class MigrationsMixin(test_migrations.WalkVersionsMixin):
1360 col_data = [col.name for col in table.columns] 1169 col_data = [col.name for col in table.columns]
1361 self.assertEqual(expected_cols, col_data) 1170 self.assertEqual(expected_cols, col_data)
1362 1171
1363 def _post_downgrade_038(self, engine):
1364 self.assertRaises(sqlalchemy.exc.NoSuchTableError,
1365 db_utils.get_table, engine, 'metadef_tags')
1366
1367 def _check_039(self, engine, data): 1172 def _check_039(self, engine, data):
1368 meta = sqlalchemy.MetaData() 1173 meta = sqlalchemy.MetaData()
1369 meta.bind = engine 1174 meta.bind = engine
@@ -1416,77 +1221,6 @@ class MigrationsMixin(test_migrations.WalkVersionsMixin):
1416 self.assertTrue(index_exist('ix_metadef_properties_namespace_id', 1221 self.assertTrue(index_exist('ix_metadef_properties_namespace_id',
1417 metadef_properties.name, engine)) 1222 metadef_properties.name, engine))
1418 1223
1419 def _post_downgrade_039(self, engine):
1420 meta = sqlalchemy.MetaData()
1421 meta.bind = engine
1422
1423 metadef_namespaces = sqlalchemy.Table('metadef_namespaces', meta,
1424 autoload=True)
1425 metadef_properties = sqlalchemy.Table('metadef_properties', meta,
1426 autoload=True)
1427 metadef_objects = sqlalchemy.Table('metadef_objects', meta,
1428 autoload=True)
1429 metadef_ns_res_types = sqlalchemy.Table(
1430 'metadef_namespace_resource_types',
1431 meta, autoload=True)
1432 metadef_resource_types = sqlalchemy.Table('metadef_resource_types',
1433 meta, autoload=True)
1434
1435 self.assertFalse(index_exist('ix_metadef_ns_res_types_namespace_id',
1436 metadef_ns_res_types.name, engine))
1437
1438 self.assertFalse(index_exist('ix_metadef_namespaces_namespace',
1439 metadef_namespaces.name, engine))
1440
1441 self.assertFalse(index_exist('ix_metadef_namespaces_owner',
1442 metadef_namespaces.name, engine))
1443
1444 self.assertFalse(index_exist('ix_metadef_objects_name',
1445 metadef_objects.name, engine))
1446
1447 self.assertFalse(index_exist('ix_metadef_objects_namespace_id',
1448 metadef_objects.name, engine))
1449
1450 self.assertFalse(index_exist('ix_metadef_properties_name',
1451 metadef_properties.name, engine))
1452
1453 self.assertFalse(index_exist('ix_metadef_properties_namespace_id',
1454 metadef_properties.name, engine))
1455
1456 self.assertTrue(index_exist('ix_namespaces_namespace',
1457 metadef_namespaces.name, engine))
1458
1459 self.assertTrue(index_exist('ix_objects_namespace_id_name',
1460 metadef_objects.name, engine))
1461
1462 self.assertTrue(index_exist('ix_metadef_properties_namespace_id_name',
1463 metadef_properties.name, engine))
1464
1465 if engine.name == 'postgresql':
1466 inspector = inspect(engine)
1467
1468 self.assertEqual(1, len(inspector.get_unique_constraints(
1469 'metadef_objects')))
1470
1471 self.assertEqual(1, len(inspector.get_unique_constraints(
1472 'metadef_properties')))
1473
1474 if engine.name == 'mysql':
1475 self.assertTrue(unique_constraint_exist(
1476 'namespace_id', metadef_properties.name, engine))
1477
1478 self.assertTrue(unique_constraint_exist(
1479 'namespace_id', metadef_objects.name, engine))
1480
1481 self.assertTrue(unique_constraint_exist(
1482 'resource_type_id', metadef_ns_res_types.name, engine))
1483
1484 self.assertTrue(unique_constraint_exist(
1485 'namespace', metadef_namespaces.name, engine))
1486
1487 self.assertTrue(unique_constraint_exist(
1488 'name', metadef_resource_types.name, engine))
1489
1490 def _check_040(self, engine, data): 1224 def _check_040(self, engine, data):
1491 meta = sqlalchemy.MetaData() 1225 meta = sqlalchemy.MetaData()
1492 meta.bind = engine 1226 meta.bind = engine
@@ -1755,73 +1489,6 @@ class MigrationsMixin(test_migrations.WalkVersionsMixin):
1755 metadef_resource_types.name, engine) 1489 metadef_resource_types.name, engine)
1756 ) 1490 )
1757 1491
1758 def _post_downgrade_042(self, engine):
1759 meta = sqlalchemy.MetaData()
1760 meta.bind = engine
1761
1762 metadef_namespaces = sqlalchemy.Table('metadef_namespaces', meta,
1763 autoload=True)
1764 metadef_objects = sqlalchemy.Table('metadef_objects', meta,
1765 autoload=True)
1766 metadef_properties = sqlalchemy.Table('metadef_properties', meta,
1767 autoload=True)
1768 metadef_tags = sqlalchemy.Table('metadef_tags', meta, autoload=True)
1769 metadef_resource_types = sqlalchemy.Table('metadef_resource_types',
1770 meta, autoload=True)
1771 metadef_ns_res_types = sqlalchemy.Table(
1772 'metadef_namespace_resource_types',
1773 meta, autoload=True)
1774
1775 # These have been recreated
1776 self.assertTrue(index_exist('ix_metadef_namespaces_namespace',
1777 metadef_namespaces.name, engine))
1778 self.assertTrue(index_exist('ix_metadef_objects_namespace_id',
1779 metadef_objects.name, engine))
1780 self.assertTrue(index_exist('ix_metadef_properties_namespace_id',
1781 metadef_properties.name, engine))
1782 self.assertTrue(index_exist('ix_metadef_tags_namespace_id',
1783 metadef_tags.name, engine))
1784 self.assertTrue(index_exist('ix_metadef_resource_types_name',
1785 metadef_resource_types.name, engine))
1786
1787 self.assertTrue(index_exist(
1788 'ix_metadef_ns_res_types_res_type_id_ns_id',
1789 metadef_ns_res_types.name, engine))
1790
1791 # The rest must remain
1792 self.assertTrue(index_exist('ix_metadef_namespaces_owner',
1793 metadef_namespaces.name, engine))
1794 self.assertTrue(index_exist('ix_metadef_objects_name',
1795 metadef_objects.name, engine))
1796 self.assertTrue(index_exist('ix_metadef_properties_name',
1797 metadef_properties.name, engine))
1798 self.assertTrue(index_exist('ix_metadef_tags_name',
1799 metadef_tags.name, engine))
1800 self.assertTrue(index_exist('ix_metadef_ns_res_types_namespace_id',
1801 metadef_ns_res_types.name, engine))
1802
1803 # Dropped
1804 self.assertFalse(unique_constraint_exist
1805 ('uq_metadef_objects_namespace_id_name',
1806 metadef_objects.name, engine)
1807 )
1808 self.assertFalse(unique_constraint_exist
1809 ('uq_metadef_properties_namespace_id_name',
1810 metadef_properties.name, engine)
1811 )
1812 self.assertFalse(unique_constraint_exist
1813 ('uq_metadef_tags_namespace_id_name',
1814 metadef_tags.name, engine)
1815 )
1816 self.assertFalse(unique_constraint_exist
1817 ('uq_metadef_namespaces_namespace',
1818 metadef_namespaces.name, engine)
1819 )
1820 self.assertFalse(unique_constraint_exist
1821 ('uq_metadef_resource_types_name',
1822 metadef_resource_types.name, engine)
1823 )
1824
1825 def assert_table(self, engine, table_name, indices, columns): 1492 def assert_table(self, engine, table_name, indices, columns):
1826 table = db_utils.get_table(engine, table_name) 1493 table = db_utils.get_table(engine, table_name)
1827 index_data = [(index.name, index.columns.keys()) for index in 1494 index_data = [(index.name, index.columns.keys()) for index in
@@ -1831,6 +1498,24 @@ class MigrationsMixin(test_migrations.WalkVersionsMixin):
1831 self.assertItemsEqual(indices, index_data) 1498 self.assertItemsEqual(indices, index_data)
1832 1499
1833 1500
1501class TestMigrations(test_base.DbTestCase, test_utils.BaseTestCase):
1502
1503 def test_no_downgrade(self):
1504 migrate_file = versions.__path__[0]
1505 for parent, dirnames, filenames in os.walk(migrate_file):
1506 for filename in filenames:
1507 if filename.split('.')[1] == 'py':
1508 model_name = filename.split('.')[0]
1509 model = __import__(
1510 'glance.db.sqlalchemy.migrate_repo.versions.' +
1511 model_name)
1512 obj = getattr(getattr(getattr(getattr(getattr(
1513 model, 'db'), 'sqlalchemy'), 'migrate_repo'),
1514 'versions'), model_name)
1515 func = getattr(obj, 'downgrade', None)
1516 self.assertIsNone(func)
1517
1518
1834class TestMysqlMigrations(test_base.MySQLOpportunisticTestCase, 1519class TestMysqlMigrations(test_base.MySQLOpportunisticTestCase,
1835 MigrationsMixin): 1520 MigrationsMixin):
1836 1521
diff --git a/releasenotes/notes/remove-db-downgrade-0d1cc45b97605775.yaml b/releasenotes/notes/remove-db-downgrade-0d1cc45b97605775.yaml
new file mode 100644
index 0000000..d835b89
--- /dev/null
+++ b/releasenotes/notes/remove-db-downgrade-0d1cc45b97605775.yaml
@@ -0,0 +1,11 @@
1---
2prelude: >
3 Database downgrades have been removed from the Glance source tree. Please
4 see ``upgrade`` section for more details.
5upgrade:
6 - The ``db_downgrade`` command has been removed from the
7 ``glance-manage`` utility and all database downgrade
8 scripts have been removed. In accord with OpenStack
9 policy, Glance cannot be downgraded any more. Operators
10 are advised to make a full database backup of their
11 production data before attempting any upgrade. \ No newline at end of file