Drop bm_pxe_ips table from baremetal database.

- added migration and tests
- removed model `BareMetalPxeIp`
- from nova/virt/baremetal/db/sqlalchemy/api.py removed functions
 `bm_pxe_ip_get_all`, `bm_pxe_ip_create`, `bm_pxe_ip_create_direct`,
 `bm_pxe_ip_destroy`, `bm_pxe_ip_destroy_by_address`, 'bm_pxe_ip_get`,
 `bm_pxe_ip_get_by_bm_node_id`, `bm_pxe_ip_associate`, 'bm_pxe_ip_disassociate`
- from nova/virt/baremetal/db/api.py removed functions
 `bm_node_associate_and_update`, `bm_pxe_ip_create`, `bm_pxe_ip_create_direct`,
 `bm_pxe_ip_destroy`, `bm_pxe_ip_destroy_by_address`, `bm_pxe_ip_get_all`,
 `bm_pxe_ip_get`, `bm_pxe_ip_get_by_bm_node_id, `bm_pxe_ip_associate`,
 `bm_pxe_ip_disassociate`
- from nova/tests/virt/baremetal/db/utils.py removed function `new_bm_pxe_ip`
- removed nova/tests/virt/baremetal/db/test_bm_pxe_ip.py
- modified `baremetal/volume_driver.py` - now we get `address` using
  nova db api

Fixes bug 1156745

Change-Id: I61f78d692da276694d79a7c1a8d45a466d124c70
This commit is contained in:
Victor Sergeyev
2013-06-13 19:20:18 +03:00
parent 27faee004a
commit b138117a8d
8 changed files with 74 additions and 261 deletions

View File

@@ -1746,6 +1746,13 @@ class TestBaremetalMigrations(BaseMigrationTestCase, CommonTestsMixIn):
columns = [c.name for c in bm_nodes.columns]
self.assertNotIn(u'prov_mac_address', columns)
def _check_008(self, engine, data):
self.assertRaises(sqlalchemy.exc.NoSuchTableError,
db_utils.get_table, engine, 'bm_pxe_ips')
def _post_downgrade_008(self, engine):
db_utils.get_table(engine, 'bm_pxe_ips')
class ProjectTestCase(test.TestCase):

View File

@@ -1,94 +0,0 @@
# Copyright (c) 2012 NTT DOCOMO, INC.
# All Rights Reserved.
#
# 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.
"""
Bare-metal DB testcase for BareMetalPxeIp
"""
from nova import exception
from nova.openstack.common.db import exception as db_exc
from nova.tests.virt.baremetal.db import base
from nova.tests.virt.baremetal.db import utils
from nova.virt.baremetal import db
class BareMetalPxeIpTestCase(base.BMDBTestCase):
def _create_pxe_ip(self):
i1 = utils.new_bm_pxe_ip(address='10.1.1.1',
server_address='10.1.1.101')
i2 = utils.new_bm_pxe_ip(address='10.1.1.2',
server_address='10.1.1.102')
i1_ref = db.bm_pxe_ip_create_direct(self.context, i1)
self.assertTrue(i1_ref['id'] is not None)
self.assertEqual(i1_ref['address'], '10.1.1.1')
self.assertEqual(i1_ref['server_address'], '10.1.1.101')
i2_ref = db.bm_pxe_ip_create_direct(self.context, i2)
self.assertTrue(i2_ref['id'] is not None)
self.assertEqual(i2_ref['address'], '10.1.1.2')
self.assertEqual(i2_ref['server_address'], '10.1.1.102')
self.i1 = i1_ref
self.i2 = i2_ref
def test_unuque_address(self):
self._create_pxe_ip()
# address duplicates
i = utils.new_bm_pxe_ip(address='10.1.1.1',
server_address='10.1.1.201')
self.assertRaises(db_exc.DBError,
db.bm_pxe_ip_create_direct,
self.context, i)
# server_address duplicates
i = utils.new_bm_pxe_ip(address='10.1.1.3',
server_address='10.1.1.101')
self.assertRaises(db_exc.DBError,
db.bm_pxe_ip_create_direct,
self.context, i)
db.bm_pxe_ip_destroy(self.context, self.i1['id'])
i = utils.new_bm_pxe_ip(address='10.1.1.1',
server_address='10.1.1.101')
ref = db.bm_pxe_ip_create_direct(self.context, i)
self.assertTrue(ref is not None)
def test_bm_pxe_ip_associate(self):
self._create_pxe_ip()
node = db.bm_node_create(self.context, utils.new_bm_node())
ip_id = db.bm_pxe_ip_associate(self.context, node['id'])
ref = db.bm_pxe_ip_get(self.context, ip_id)
self.assertEqual(ref['bm_node_id'], node['id'])
def test_bm_pxe_ip_associate_raise(self):
self._create_pxe_ip()
node_id = 123
self.assertRaises(exception.NovaException,
db.bm_pxe_ip_associate,
self.context, node_id)
def test_delete_by_address(self):
self._create_pxe_ip()
db.bm_pxe_ip_destroy_by_address(self.context, '10.1.1.1')
del_ref = db.bm_pxe_ip_get(self.context, self.i1['id'])
self.assertTrue(del_ref is None)
def test_delete_by_address_not_exist(self):
self._create_pxe_ip()
del_ref = db.bm_pxe_ip_destroy_by_address(self.context, '10.11.12.13')
self.assertTrue(del_ref is None)

View File

@@ -39,18 +39,6 @@ def new_bm_node(**kwargs):
return h
def new_bm_pxe_ip(**kwargs):
x = bm_models.BareMetalPxeIp()
x.id = kwargs.pop('id', None)
x.address = kwargs.pop('address', None)
x.server_address = kwargs.pop('server_address', None)
x.bm_node_id = kwargs.pop('bm_node_id', None)
if len(kwargs) > 0:
raise test.TestingException("unknown field: %s"
% ','.join(kwargs.keys()))
return x
def new_bm_interface(**kwargs):
x = bm_models.BareMetalInterface()
x.id = kwargs.pop('id', None)

View File

@@ -121,42 +121,6 @@ def bm_node_associate_and_update(context, node_uuid, values):
return IMPL.bm_node_associate_and_update(context, node_uuid, values)
def bm_pxe_ip_create(context, address, server_address):
return IMPL.bm_pxe_ip_create(context, address, server_address)
def bm_pxe_ip_create_direct(context, bm_pxe_ip):
return IMPL.bm_pxe_ip_create_direct(context, bm_pxe_ip)
def bm_pxe_ip_destroy(context, ip_id):
return IMPL.bm_pxe_ip_destroy(context, ip_id)
def bm_pxe_ip_destroy_by_address(context, address):
return IMPL.bm_pxe_ip_destroy_by_address(context, address)
def bm_pxe_ip_get_all(context):
return IMPL.bm_pxe_ip_get_all(context)
def bm_pxe_ip_get(context, ip_id):
return IMPL.bm_pxe_ip_get(context, ip_id)
def bm_pxe_ip_get_by_bm_node_id(context, bm_node_id):
return IMPL.bm_pxe_ip_get_by_bm_node_id(context, bm_node_id)
def bm_pxe_ip_associate(context, bm_node_id):
return IMPL.bm_pxe_ip_associate(context, bm_node_id)
def bm_pxe_ip_disassociate(context, bm_node_id):
return IMPL.bm_pxe_ip_disassociate(context, bm_node_id)
def bm_interface_get(context, if_id):
return IMPL.bm_interface_get(context, if_id)

View File

@@ -235,111 +235,6 @@ def bm_node_destroy(context, bm_node_id):
raise exception.NodeNotFound(node_id=bm_node_id)
@sqlalchemy_api.require_admin_context
def bm_pxe_ip_get_all(context):
query = model_query(context, models.BareMetalPxeIp, read_deleted="no")
return query.all()
@sqlalchemy_api.require_admin_context
def bm_pxe_ip_create(context, address, server_address):
ref = models.BareMetalPxeIp()
ref.address = address
ref.server_address = server_address
_save(ref)
return ref
@sqlalchemy_api.require_admin_context
def bm_pxe_ip_create_direct(context, bm_pxe_ip):
ref = bm_pxe_ip_create(context,
address=bm_pxe_ip['address'],
server_address=bm_pxe_ip['server_address'])
return ref
@sqlalchemy_api.require_admin_context
def bm_pxe_ip_destroy(context, ip_id):
# Delete physically since it has unique columns
model_query(context, models.BareMetalPxeIp, read_deleted="no").\
filter_by(id=ip_id).\
delete()
@sqlalchemy_api.require_admin_context
def bm_pxe_ip_destroy_by_address(context, address):
# Delete physically since it has unique columns
model_query(context, models.BareMetalPxeIp, read_deleted="no").\
filter_by(address=address).\
delete()
@sqlalchemy_api.require_admin_context
def bm_pxe_ip_get(context, ip_id):
result = model_query(context, models.BareMetalPxeIp, read_deleted="no").\
filter_by(id=ip_id).\
first()
return result
@sqlalchemy_api.require_admin_context
def bm_pxe_ip_get_by_bm_node_id(context, bm_node_id):
result = model_query(context, models.BareMetalPxeIp, read_deleted="no").\
filter_by(bm_node_id=bm_node_id).\
first()
if not result:
raise exception.NodeNotFound(node_id=bm_node_id)
return result
@sqlalchemy_api.require_admin_context
def bm_pxe_ip_associate(context, bm_node_id):
session = db_session.get_session()
with session.begin():
# Check if the node really exists
node_ref = model_query(context, models.BareMetalNode,
read_deleted="no", session=session).\
filter_by(id=bm_node_id).\
first()
if not node_ref:
raise exception.NodeNotFound(node_id=bm_node_id)
# Check if the node already has a pxe_ip
ip_ref = model_query(context, models.BareMetalPxeIp,
read_deleted="no", session=session).\
filter_by(bm_node_id=bm_node_id).\
first()
if ip_ref:
return ip_ref.id
# with_lockmode('update') and filter_by(bm_node_id=None) will lock all
# records. It may cause a performance problem in high-concurrency
# environment.
ip_ref = model_query(context, models.BareMetalPxeIp,
read_deleted="no", session=session).\
filter_by(bm_node_id=None).\
with_lockmode('update').\
first()
# this exception is not caught in nova/compute/manager
if not ip_ref:
raise exception.NovaException(_("No more PXE IPs available"))
ip_ref.bm_node_id = bm_node_id
session.add(ip_ref)
return ip_ref.id
@sqlalchemy_api.require_admin_context
def bm_pxe_ip_disassociate(context, bm_node_id):
model_query(context, models.BareMetalPxeIp, read_deleted="no").\
filter_by(bm_node_id=bm_node_id).\
update({'bm_node_id': None})
@sqlalchemy_api.require_admin_context
def bm_interface_get(context, if_id):
result = model_query(context, models.BareMetalInterface,

View File

@@ -0,0 +1,61 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2013 Mirantis Inc.
# All Rights Reserved
#
# 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 sqlalchemy import Boolean
from sqlalchemy import Column
from sqlalchemy import DateTime
from sqlalchemy import Index
from sqlalchemy import Integer
from sqlalchemy import MetaData
from sqlalchemy import String
from sqlalchemy import Table
table_name = 'bm_pxe_ips'
def upgrade(migrate_engine):
meta = MetaData()
meta.bind = migrate_engine
table = Table(table_name, meta, autoload=True)
table.drop()
def downgrade(migrate_engine):
meta = MetaData()
meta.bind = migrate_engine
bm_pxe_ips = Table(table_name, meta,
Column('created_at', DateTime),
Column('updated_at', DateTime),
Column('deleted_at', DateTime),
Column('deleted', Boolean),
Column('id', Integer, primary_key=True, nullable=False),
Column('address', String(length=255), unique=True),
Column('bm_node_id', Integer),
Column('server_address',
String(length=255), unique=True),
mysql_engine='InnoDB',
)
bm_pxe_ips.create()
Index(
'idx_bm_pxe_ips_bm_node_id_deleted',
bm_pxe_ips.c.bm_node_id,
bm_pxe_ips.c.deleted
).create(migrate_engine)

View File

@@ -54,15 +54,6 @@ class BareMetalNode(BASE, models.NovaBase):
swap_mb = Column(Integer)
class BareMetalPxeIp(BASE, models.NovaBase):
__tablename__ = 'bm_pxe_ips'
id = Column(Integer, primary_key=True)
deleted = Column(Boolean, default=False)
address = Column(String(255), unique=True)
server_address = Column(String(255), unique=True)
bm_node_id = Column(Integer, ForeignKey('bm_nodes.id'), nullable=True)
class BareMetalInterface(BASE, models.NovaBase):
__tablename__ = 'bm_interfaces'
id = Column(Integer, primary_key=True)

View File

@@ -21,6 +21,7 @@ import re
from oslo.config import cfg
from nova import context as nova_context
from nova.db import api as nova_db_api
from nova import exception
from nova.openstack.common import importutils
from nova.openstack.common import log as logging
@@ -219,10 +220,9 @@ class LibvirtVolumeDriver(VolumeDriver):
return method(connection_info, *args, **kwargs)
def attach_volume(self, connection_info, instance, mountpoint):
node = _get_baremetal_node_by_instance_uuid(instance['uuid'])
ctx = nova_context.get_admin_context()
pxe_ip = bmdb.bm_pxe_ip_get_by_bm_node_id(ctx, node['id'])
if not pxe_ip:
fixed_ips = nova_db_api.fixed_ip_get_by_instance(ctx, instance['uuid'])
if not fixed_ips:
if not CONF.baremetal.use_unsafe_iscsi:
raise exception.NovaException(_(
'No fixed PXE IP is associated to %s') % instance['uuid'])
@@ -236,8 +236,9 @@ class LibvirtVolumeDriver(VolumeDriver):
tid = _get_next_tid()
_create_iscsi_export_tgtadm(device_path, tid, iqn)
if pxe_ip:
_allow_iscsi_tgtadm(tid, pxe_ip['address'])
if fixed_ips:
for ip in fixed_ips:
_allow_iscsi_tgtadm(tid, ip['address'])
else:
# NOTE(NTTdocomo): Since nova-compute does not know the
# instance's initiator ip, it allows any initiators