85 lines
2.8 KiB
Python
85 lines
2.8 KiB
Python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
|
|
|
# Copyright (c) 2013 NTT DOCOMO, INC.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
from ironic.openstack.common import log as logging
|
|
from sqlalchemy import and_, MetaData, select, Table, exists
|
|
from sqlalchemy import exc
|
|
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
|
|
def upgrade(migrate_engine):
|
|
meta = MetaData()
|
|
meta.bind = migrate_engine
|
|
|
|
nodes = Table('bm_nodes', meta, autoload=True)
|
|
ifs = Table('bm_interfaces', meta, autoload=True)
|
|
|
|
q = select([nodes.c.id, nodes.c.prov_mac_address],
|
|
from_obj=nodes)
|
|
|
|
# Iterate all elements before starting insert since IntegrityError
|
|
# may disturb the iteration.
|
|
node_address = {}
|
|
for node_id, address in q.execute():
|
|
node_address[node_id] = address
|
|
|
|
i = ifs.insert()
|
|
for node_id, address in node_address.iteritems():
|
|
try:
|
|
i.execute({'bm_node_id': node_id, 'address': address})
|
|
except exc.IntegrityError:
|
|
# The address is registered in both bm_nodes and bm_interfaces.
|
|
# It is expected.
|
|
pass
|
|
|
|
|
|
def downgrade(migrate_engine):
|
|
meta = MetaData()
|
|
meta.bind = migrate_engine
|
|
|
|
nodes = Table('bm_nodes', meta, autoload=True)
|
|
ifs = Table('bm_interfaces', meta, autoload=True)
|
|
|
|
subq = exists().where(and_(ifs.c.bm_node_id == nodes.c.id,
|
|
ifs.c.address == nodes.c.prov_mac_address))
|
|
|
|
ifs.delete().where(subq).execute()
|
|
|
|
# NOTE(arata):
|
|
# In fact, this downgrade may not return the db to the previous state.
|
|
# It seems to be not so match a problem, so this is just for memo.
|
|
#
|
|
# Think these two state before upgrading:
|
|
#
|
|
# (A) address 'x' is duplicate
|
|
# bm_nodes.prov_mac_address='x'
|
|
# bm_interfaces.address=['x', 'y']
|
|
#
|
|
# (B) no address is duplicate
|
|
# bm_nodes.prov_mac_address='x'
|
|
# bm_interfaces.address=['y']
|
|
#
|
|
# Upgrading them results in the same state:
|
|
#
|
|
# bm_nodes.prov_mac_address='x'
|
|
# bm_interfaces.address=['x', 'y']
|
|
#
|
|
# Downgrading this results in B, even if the actual initial status was A
|
|
# Of course we can change it to downgrade to B, but then we cannot
|
|
# downgrade to A; it is an exclusive choice since we do not have
|
|
# information about the initial state.
|