Coverage for manila/db/migrations/alembic/versions/a87e0fb17dee_multiple_share_server_subnets.py: 73%
92 statements
« prev ^ index » next coverage.py v7.11.0, created at 2026-02-18 22:19 +0000
« prev ^ index » next coverage.py v7.11.0, created at 2026-02-18 22:19 +0000
1# Licensed under the Apache License, Version 2.0 (the "License"); you may
2# not use this file except in compliance with the License. You may obtain
3# a copy of the License at
4#
5# http://www.apache.org/licenses/LICENSE-2.0
6#
7# Unless required by applicable law or agreed to in writing, software
8# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10# License for the specific language governing permissions and limitations
11# under the License.
13"""multiple share server subnets
15Revision ID: a87e0fb17dee
16Revises: 1946cb97bb8d
17Create Date: 2022-01-14 06:12:27.596130
19"""
21# revision identifiers, used by Alembic.
22revision = 'a87e0fb17dee'
23down_revision = '1946cb97bb8d'
26from alembic import op
27from oslo_log import log
28import sqlalchemy as sa
30from manila.db.migrations import utils
33SHARE_SERVERS_TABLE = 'share_servers'
34SHARE_SERVER_SUBNET_MAP_TABLE = 'share_server_share_network_subnet_mappings'
35NETWORK_ALLOCATIONS_TABLE = 'network_allocations'
36LOG = log.getLogger(__name__)
39def upgrade():
41 # Create mappings table.
42 context = op.get_context()
43 mysql_dl = context.bind.dialect.name == 'mysql'
44 datetime_type = (sa.dialects.mysql.DATETIME(fsp=6)
45 if mysql_dl else sa.DateTime)
46 try:
47 share_server_fk_name = "fk_ss_sns_m_share_server_id_share_servers"
48 share_network_subnet_fk_name = (
49 "fk_ss_sns_m_share_network_subnet_id_share_network_subnets")
50 server_subnet_mappings_table = op.create_table(
51 SHARE_SERVER_SUBNET_MAP_TABLE,
52 sa.Column('id', sa.Integer, primary_key=True, nullable=False),
53 sa.Column('created_at', datetime_type),
54 sa.Column('updated_at', datetime_type),
55 sa.Column('deleted_at', datetime_type),
56 sa.Column('deleted', sa.Integer, default=0),
57 sa.Column(
58 'share_server_id', sa.String(length=36),
59 sa.ForeignKey('share_servers.id', name=share_server_fk_name),
60 nullable=False),
61 sa.Column(
62 'share_network_subnet_id', sa.String(length=36),
63 sa.ForeignKey('share_network_subnets.id',
64 name=share_network_subnet_fk_name),
65 nullable=False),
66 mysql_engine='InnoDB',
67 mysql_charset='utf8')
68 except Exception:
69 LOG.error('Table %s could not be created.',
70 SHARE_SERVER_SUBNET_MAP_TABLE)
71 raise
73 # Populate the mappings table from the share servers table.
74 try:
75 connection = op.get_bind()
76 share_servers_table = utils.load_table(SHARE_SERVERS_TABLE, connection)
77 server_subnet_mappings = []
78 for server in connection.execute(share_servers_table.select()):
79 if server.share_network_subnet_id:
80 server_subnet_mappings.append({
81 'created_at': server.created_at,
82 'updated_at': server.updated_at,
83 'deleted_at': server.deleted_at,
84 'deleted': 0 if server.deleted == 'False' else 1,
85 'share_server_id': server.id,
86 'share_network_subnet_id': server.share_network_subnet_id,
87 })
88 op.bulk_insert(server_subnet_mappings_table, server_subnet_mappings)
89 except Exception:
90 LOG.error('Table %s could not be populated from the %s table.',
91 SHARE_SERVER_SUBNET_MAP_TABLE, SHARE_SERVERS_TABLE)
92 raise
94 # add subnet id column to the allocations table.
95 try:
96 network_allocation_fk_name = (
97 "fk_network_allocation_subnet_id_share_network_subnets")
98 op.add_column(
99 NETWORK_ALLOCATIONS_TABLE,
100 sa.Column('share_network_subnet_id', sa.String(length=36),
101 sa.ForeignKey('share_network_subnets.id',
102 name=network_allocation_fk_name))
103 )
104 except Exception:
105 LOG.error("Could not add ForeignKey column 'share_network_subnet_id'"
106 "to table %s.", NETWORK_ALLOCATIONS_TABLE)
107 raise
109 # populate the allocation with its subnet id using the share server.
110 network_allocation_table = utils.load_table(NETWORK_ALLOCATIONS_TABLE,
111 connection)
112 for alloc in connection.execute(network_allocation_table.select()):
113 # admin allocations should not contain subnet id.
114 if alloc._mapping['label'] == 'admin':
115 continue
117 server = connection.execute(
118 share_servers_table.select().where(
119 alloc._mapping['share_server_id'] == (
120 share_servers_table.c.id))).first()
122 # pylint: disable=no-value-for-parameter
123 op.execute(network_allocation_table.update().where(
124 alloc._mapping['id'] == network_allocation_table.c.id).values(
125 {'share_network_subnet_id':
126 server._mapping['share_network_subnet_id']}))
128 # add a new column to share_servers.
129 try:
130 op.add_column(
131 SHARE_SERVERS_TABLE,
132 sa.Column('network_allocation_update_support', sa.Boolean,
133 nullable=False, server_default=sa.sql.false()))
134 except Exception:
135 LOG.error("Table %s could not add column "
136 "'network_allocation_update_support'.",
137 SHARE_SERVERS_TABLE)
138 raise
140 # drop subnet id foreign key from share servers.
141 try:
142 share_serves_fk_name = (
143 "fk_share_servers_share_network_subnet_id_share_network_subnets")
144 if connection.engine.name == 'mysql':
145 op.drop_constraint(share_serves_fk_name, SHARE_SERVERS_TABLE,
146 type_="foreignkey")
147 op.drop_column(SHARE_SERVERS_TABLE, 'share_network_subnet_id')
148 except Exception:
149 LOG.error("Table %s could not drop column 'share_network_subnet_id'.",
150 SHARE_SERVERS_TABLE)
151 raise
154def downgrade():
155 """Remove share_server_share_network_subnet_mapping table and new columns.
157 This method can lead to data loss because the share server can have
158 more than one subnet.
159 """
160 try:
161 share_serves_fk_name = (
162 "fk_share_servers_share_network_subnet_id_share_network_subnets")
163 op.add_column(
164 SHARE_SERVERS_TABLE,
165 sa.Column(
166 'share_network_subnet_id', sa.String(36),
167 sa.ForeignKey('share_network_subnets.id',
168 name=share_serves_fk_name),
169 )
170 )
172 connection = op.get_bind()
173 server_subnet_mappings_table = utils.load_table(
174 SHARE_SERVER_SUBNET_MAP_TABLE, connection)
175 share_servers_table = utils.load_table(SHARE_SERVERS_TABLE,
176 connection)
178 with sa.orm.Session(bind=op.get_bind()) as session:
179 for server in connection.execute(share_servers_table.select()):
180 subnets = session.query(
181 server_subnet_mappings_table).filter(
182 server._mapping['id'] == (
183 server_subnet_mappings_table.c.share_server_id)
184 ).all()
186 if server._mapping['deleted'] != 'False' and len(subnets) > 1: 186 ↛ 187line 186 didn't jump to line 187 because the condition on line 186 was never true
187 LOG.warning('Share server %s is not deleted and it '
188 'has more than one subnet (%s subnets), '
189 'the downgrade may cause an inconsistent '
190 'environment.',
191 server._mapping['id'], len(subnets))
193 subnet_id = (
194 subnets[0].share_network_subnet_id if subnets else None
195 )
197 # pylint: disable=no-value-for-parameter
198 op.execute(share_servers_table.update().where(
199 server._mapping['id'] == share_servers_table.c.id).values(
200 {'share_network_subnet_id': subnet_id}))
202 except Exception:
203 LOG.error("'share_network_subnet_id' field in the %s table could not "
204 "be created and populated from %s table.",
205 SHARE_SERVERS_TABLE, SHARE_SERVER_SUBNET_MAP_TABLE)
206 raise
208 try:
209 op.drop_table(SHARE_SERVER_SUBNET_MAP_TABLE)
210 except Exception:
211 LOG.error("Failed to drop table %s.", SHARE_SERVER_SUBNET_MAP_TABLE)
212 raise
214 try:
215 op.drop_column(SHARE_SERVERS_TABLE,
216 'network_allocation_update_support')
217 except Exception:
218 LOG.error("Table %s failed to drop the column "
219 "'network_allocation_update_support'.", SHARE_SERVERS_TABLE)
220 raise
222 try:
223 network_allocation_fk_name = (
224 "fk_network_allocation_subnet_id_share_network_subnets")
225 if connection.engine.name == 'mysql':
226 op.drop_constraint(network_allocation_fk_name,
227 NETWORK_ALLOCATIONS_TABLE,
228 type_="foreignkey")
229 op.drop_column(NETWORK_ALLOCATIONS_TABLE, 'share_network_subnet_id')
230 except Exception:
231 LOG.error("Column 'network_allocations.share_network_subnet_id' from "
232 "table %s failed to drop.", NETWORK_ALLOCATIONS_TABLE)
233 raise