Merge "Add node (database and objects) fields for all interfaces"
This commit is contained in:
commit
c0308d8034
@ -0,0 +1,45 @@
|
|||||||
|
# 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.
|
||||||
|
|
||||||
|
"""Add fields for all interfaces
|
||||||
|
|
||||||
|
Revision ID: bcdd431ba0bf
|
||||||
|
Revises: 60cf717201bc
|
||||||
|
Create Date: 2016-11-11 16:44:52.823881
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = 'bcdd431ba0bf'
|
||||||
|
down_revision = '60cf717201bc'
|
||||||
|
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
op.add_column('nodes', sa.Column('boot_interface',
|
||||||
|
sa.String(length=255), nullable=True))
|
||||||
|
op.add_column('nodes', sa.Column('console_interface',
|
||||||
|
sa.String(length=255), nullable=True))
|
||||||
|
op.add_column('nodes', sa.Column('deploy_interface',
|
||||||
|
sa.String(length=255), nullable=True))
|
||||||
|
op.add_column('nodes', sa.Column('inspect_interface',
|
||||||
|
sa.String(length=255), nullable=True))
|
||||||
|
op.add_column('nodes', sa.Column('management_interface',
|
||||||
|
sa.String(length=255), nullable=True))
|
||||||
|
op.add_column('nodes', sa.Column('power_interface',
|
||||||
|
sa.String(length=255), nullable=True))
|
||||||
|
op.add_column('nodes', sa.Column('raid_interface',
|
||||||
|
sa.String(length=255), nullable=True))
|
||||||
|
op.add_column('nodes', sa.Column('vendor_interface',
|
||||||
|
sa.String(length=255), nullable=True))
|
@ -144,7 +144,15 @@ class Node(Base):
|
|||||||
inspection_started_at = Column(DateTime, nullable=True)
|
inspection_started_at = Column(DateTime, nullable=True)
|
||||||
extra = Column(db_types.JsonEncodedDict)
|
extra = Column(db_types.JsonEncodedDict)
|
||||||
|
|
||||||
|
boot_interface = Column(String(255), nullable=True)
|
||||||
|
console_interface = Column(String(255), nullable=True)
|
||||||
|
deploy_interface = Column(String(255), nullable=True)
|
||||||
|
inspect_interface = Column(String(255), nullable=True)
|
||||||
|
management_interface = Column(String(255), nullable=True)
|
||||||
network_interface = Column(String(255), nullable=True)
|
network_interface = Column(String(255), nullable=True)
|
||||||
|
raid_interface = Column(String(255), nullable=True)
|
||||||
|
power_interface = Column(String(255), nullable=True)
|
||||||
|
vendor_interface = Column(String(255), nullable=True)
|
||||||
|
|
||||||
|
|
||||||
class Port(Base):
|
class Port(Base):
|
||||||
|
@ -171,6 +171,13 @@ class BareDriver(BaseDriver):
|
|||||||
self.core_interfaces.append('network')
|
self.core_interfaces.append('network')
|
||||||
|
|
||||||
|
|
||||||
|
ALL_INTERFACES = set(BareDriver().all_interfaces)
|
||||||
|
"""Constant holding all known interfaces.
|
||||||
|
|
||||||
|
Includes interfaces not exposed via BaseDriver.all_interfaces.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
@six.add_metaclass(abc.ABCMeta)
|
@six.add_metaclass(abc.ABCMeta)
|
||||||
class BaseInterface(object):
|
class BaseInterface(object):
|
||||||
"""A base interface implementing common functions for Driver Interfaces."""
|
"""A base interface implementing common functions for Driver Interfaces."""
|
||||||
|
@ -58,7 +58,10 @@ class Node(base.IronicObject, object_base.VersionedObjectDictCompat):
|
|||||||
# Version 1.16: Add network_interface field
|
# Version 1.16: Add network_interface field
|
||||||
# Version 1.17: Add resource_class field
|
# Version 1.17: Add resource_class field
|
||||||
# Version 1.18: Add default setting for network_interface
|
# Version 1.18: Add default setting for network_interface
|
||||||
VERSION = '1.18'
|
# Version 1.19: Add fields: boot_interface, console_interface,
|
||||||
|
# deploy_interface, inspect_interface, management_interface,
|
||||||
|
# power_interface, raid_interface, vendor_interface
|
||||||
|
VERSION = '1.19'
|
||||||
|
|
||||||
dbapi = db_api.get_instance()
|
dbapi = db_api.get_instance()
|
||||||
|
|
||||||
@ -118,8 +121,16 @@ class Node(base.IronicObject, object_base.VersionedObjectDictCompat):
|
|||||||
|
|
||||||
'extra': object_fields.FlexibleDictField(nullable=True),
|
'extra': object_fields.FlexibleDictField(nullable=True),
|
||||||
|
|
||||||
|
'boot_interface': object_fields.StringField(nullable=True),
|
||||||
|
'console_interface': object_fields.StringField(nullable=True),
|
||||||
|
'deploy_interface': object_fields.StringField(nullable=True),
|
||||||
|
'inspect_interface': object_fields.StringField(nullable=True),
|
||||||
|
'management_interface': object_fields.StringField(nullable=True),
|
||||||
'network_interface': object_fields.StringFieldThatAcceptsCallable(
|
'network_interface': object_fields.StringFieldThatAcceptsCallable(
|
||||||
nullable=False, default=_default_network_interface),
|
nullable=False, default=_default_network_interface),
|
||||||
|
'power_interface': object_fields.StringField(nullable=True),
|
||||||
|
'raid_interface': object_fields.StringField(nullable=True),
|
||||||
|
'vendor_interface': object_fields.StringField(nullable=True),
|
||||||
}
|
}
|
||||||
|
|
||||||
def _validate_property_values(self, properties):
|
def _validate_property_values(self, properties):
|
||||||
|
@ -23,6 +23,7 @@ from ironic.api.controllers.v1 import chassis as chassis_controller
|
|||||||
from ironic.api.controllers.v1 import node as node_controller
|
from ironic.api.controllers.v1 import node as node_controller
|
||||||
from ironic.api.controllers.v1 import port as port_controller
|
from ironic.api.controllers.v1 import port as port_controller
|
||||||
from ironic.api.controllers.v1 import portgroup as portgroup_controller
|
from ironic.api.controllers.v1 import portgroup as portgroup_controller
|
||||||
|
from ironic.drivers import base as drivers_base
|
||||||
from ironic.tests.unit.db import utils
|
from ironic.tests.unit.db import utils
|
||||||
|
|
||||||
ADMIN_TOKEN = '4562138218392831'
|
ADMIN_TOKEN = '4562138218392831'
|
||||||
@ -99,8 +100,10 @@ def node_post_data(**kw):
|
|||||||
# NOTE(jroll): pop out fields that were introduced in later API versions,
|
# NOTE(jroll): pop out fields that were introduced in later API versions,
|
||||||
# unless explicitly requested. Otherwise, these will cause tests using
|
# unless explicitly requested. Otherwise, these will cause tests using
|
||||||
# older API versions to fail.
|
# older API versions to fail.
|
||||||
if 'network_interface' not in kw:
|
for iface in drivers_base.ALL_INTERFACES:
|
||||||
node.pop('network_interface')
|
name = '%s_interface' % iface
|
||||||
|
if name not in kw:
|
||||||
|
node.pop(name)
|
||||||
if 'resource_class' not in kw:
|
if 'resource_class' not in kw:
|
||||||
node.pop('resource_class')
|
node.pop('resource_class')
|
||||||
|
|
||||||
|
@ -53,6 +53,7 @@ import sqlalchemy.exc
|
|||||||
from ironic.common.i18n import _LE
|
from ironic.common.i18n import _LE
|
||||||
from ironic.db.sqlalchemy import migration
|
from ironic.db.sqlalchemy import migration
|
||||||
from ironic.db.sqlalchemy import models
|
from ironic.db.sqlalchemy import models
|
||||||
|
from ironic.drivers import base as base_driver
|
||||||
from ironic.tests import base
|
from ironic.tests import base
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
@ -537,6 +538,15 @@ class MigrationCheckersMixin(object):
|
|||||||
(sqlalchemy.types.Boolean,
|
(sqlalchemy.types.Boolean,
|
||||||
sqlalchemy.types.Integer))
|
sqlalchemy.types.Integer))
|
||||||
|
|
||||||
|
def _check_bcdd431ba0bf(self, engine, data):
|
||||||
|
nodes = db_utils.get_table(engine, 'nodes')
|
||||||
|
col_names = [column.name for column in nodes.c]
|
||||||
|
for iface in base_driver.ALL_INTERFACES:
|
||||||
|
name = '%s_interface' % iface
|
||||||
|
self.assertIn(name, col_names)
|
||||||
|
self.assertIsInstance(getattr(nodes.c, name).type,
|
||||||
|
sqlalchemy.types.String)
|
||||||
|
|
||||||
def test_upgrade_and_version(self):
|
def test_upgrade_and_version(self):
|
||||||
with patch_with_engine(self.engine):
|
with patch_with_engine(self.engine):
|
||||||
self.migration_api.upgrade('head')
|
self.migration_api.upgrade('head')
|
||||||
|
@ -19,6 +19,7 @@ from oslo_utils import timeutils
|
|||||||
|
|
||||||
from ironic.common import states
|
from ironic.common import states
|
||||||
from ironic.db import api as db_api
|
from ironic.db import api as db_api
|
||||||
|
from ironic.drivers import base as drivers_base
|
||||||
|
|
||||||
|
|
||||||
def get_test_ipmi_info():
|
def get_test_ipmi_info():
|
||||||
@ -214,7 +215,7 @@ def get_test_node(**kw):
|
|||||||
fake_internal_info = {
|
fake_internal_info = {
|
||||||
"private_state": "secret value"
|
"private_state": "secret value"
|
||||||
}
|
}
|
||||||
return {
|
result = {
|
||||||
'id': kw.get('id', 123),
|
'id': kw.get('id', 123),
|
||||||
'name': kw.get('name', None),
|
'name': kw.get('name', None),
|
||||||
'uuid': kw.get('uuid', '1be26c0b-03f2-4d2e-ae87-c02d7f33c123'),
|
'uuid': kw.get('uuid', '1be26c0b-03f2-4d2e-ae87-c02d7f33c123'),
|
||||||
@ -248,9 +249,14 @@ def get_test_node(**kw):
|
|||||||
'target_raid_config': kw.get('target_raid_config'),
|
'target_raid_config': kw.get('target_raid_config'),
|
||||||
'tags': kw.get('tags', []),
|
'tags': kw.get('tags', []),
|
||||||
'resource_class': kw.get('resource_class'),
|
'resource_class': kw.get('resource_class'),
|
||||||
'network_interface': kw.get('network_interface'),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for iface in drivers_base.ALL_INTERFACES:
|
||||||
|
name = '%s_interface' % iface
|
||||||
|
result[name] = kw.get(name)
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
def create_test_node(**kw):
|
def create_test_node(**kw):
|
||||||
"""Create test node entry in DB and return Node DB object.
|
"""Create test node entry in DB and return Node DB object.
|
||||||
|
@ -404,7 +404,7 @@ class TestObject(_LocalTest, _TestObject):
|
|||||||
# version bump. It is md5 hash of object fields and remotable methods.
|
# version bump. It is md5 hash of object fields and remotable methods.
|
||||||
# The fingerprint values should only be changed if there is a version bump.
|
# The fingerprint values should only be changed if there is a version bump.
|
||||||
expected_object_fingerprints = {
|
expected_object_fingerprints = {
|
||||||
'Node': '1.18-37a1d39ba8a4957f505dda936ac9146b',
|
'Node': '1.19-e8b294016d8d5b322df813f790d092b4',
|
||||||
'MyObj': '1.5-4f5efe8f0fcaf182bbe1c7fe3ba858db',
|
'MyObj': '1.5-4f5efe8f0fcaf182bbe1c7fe3ba858db',
|
||||||
'Chassis': '1.3-d656e039fd8ae9f34efc232ab3980905',
|
'Chassis': '1.3-d656e039fd8ae9f34efc232ab3980905',
|
||||||
'Port': '1.6-609504503d68982a10f495659990084b',
|
'Port': '1.6-609504503d68982a10f495659990084b',
|
||||||
|
@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
upgrade:
|
||||||
|
- Add database migration to add new fields corresponding to all interfaces
|
||||||
|
to the node table.
|
Loading…
Reference in New Issue
Block a user