Remove the old db implementation.
This commit is contained in:
parent
39a9f767ce
commit
c4c6204acf
171
ironic/db/api.py
171
ironic/db/api.py
|
@ -1,171 +0,0 @@
|
||||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
|
||||||
|
|
||||||
# Copyright (c) 2012 NTT DOCOMO, INC.
|
|
||||||
# Copyright (c) 2011 X.commerce, a business unit of eBay Inc.
|
|
||||||
# Copyright 2010 United States Government as represented by the
|
|
||||||
# Administrator of the National Aeronautics and Space Administration.
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
"""Defines interface for DB access.
|
|
||||||
|
|
||||||
The underlying driver is loaded as a :class:`LazyPluggable`.
|
|
||||||
|
|
||||||
Functions in this module are imported into the ironic.db
|
|
||||||
namespace. Call these functions from ironic.db namespace, not
|
|
||||||
the ironic.db.api namespace.
|
|
||||||
|
|
||||||
All functions in this module return objects that implement a dictionary-like
|
|
||||||
interface. Currently, many of these objects are sqlalchemy objects that
|
|
||||||
implement a dictionary interface. However, a future goal is to have all of
|
|
||||||
these objects be simple dictionaries.
|
|
||||||
|
|
||||||
|
|
||||||
**Related Flags**
|
|
||||||
|
|
||||||
:db_backend: string to lookup in the list of LazyPluggable backends.
|
|
||||||
`sqlalchemy` is the only supported backend right now.
|
|
||||||
|
|
||||||
:sql_connection: string specifying the sqlalchemy connection to
|
|
||||||
use, like: `sqlite:///var/lib/ironic/ironic.sqlite`.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
from oslo.config import cfg
|
|
||||||
|
|
||||||
from ironic.common import utils
|
|
||||||
from ironic.openstack.common.db import api as db_api
|
|
||||||
|
|
||||||
|
|
||||||
_BACKEND_MAPPING = {'sqlalchemy': 'ironic.db.sqlalchemy.api'}
|
|
||||||
|
|
||||||
IMPL = db_api.DBAPI(backend_mapping=_BACKEND_MAPPING)
|
|
||||||
|
|
||||||
|
|
||||||
def bm_node_get_all(context, service_host=None):
|
|
||||||
return IMPL.bm_node_get_all(context,
|
|
||||||
service_host=service_host)
|
|
||||||
|
|
||||||
|
|
||||||
def bm_node_get_associated(context, service_host=None):
|
|
||||||
return IMPL.bm_node_get_associated(context,
|
|
||||||
service_host=service_host)
|
|
||||||
|
|
||||||
|
|
||||||
def bm_node_get_unassociated(context, service_host=None):
|
|
||||||
return IMPL.bm_node_get_unassociated(context,
|
|
||||||
service_host=service_host)
|
|
||||||
|
|
||||||
|
|
||||||
def bm_node_find_free(context, service_host=None,
|
|
||||||
memory_mb=None, cpus=None, local_gb=None):
|
|
||||||
return IMPL.bm_node_find_free(context,
|
|
||||||
service_host=service_host,
|
|
||||||
memory_mb=memory_mb,
|
|
||||||
cpus=cpus,
|
|
||||||
local_gb=local_gb)
|
|
||||||
|
|
||||||
|
|
||||||
def bm_node_get(context, bm_node_id):
|
|
||||||
return IMPL.bm_node_get(context, bm_node_id)
|
|
||||||
|
|
||||||
|
|
||||||
def bm_node_get_by_instance_uuid(context, instance_uuid):
|
|
||||||
return IMPL.bm_node_get_by_instance_uuid(context,
|
|
||||||
instance_uuid)
|
|
||||||
|
|
||||||
|
|
||||||
def bm_node_get_by_node_uuid(context, node_uuid):
|
|
||||||
return IMPL.bm_node_get_by_node_uuid(context, node_uuid)
|
|
||||||
|
|
||||||
|
|
||||||
def bm_node_create(context, values):
|
|
||||||
return IMPL.bm_node_create(context, values)
|
|
||||||
|
|
||||||
|
|
||||||
def bm_node_destroy(context, bm_node_id):
|
|
||||||
return IMPL.bm_node_destroy(context, bm_node_id)
|
|
||||||
|
|
||||||
|
|
||||||
def bm_node_update(context, bm_node_id, values):
|
|
||||||
return IMPL.bm_node_update(context, bm_node_id, values)
|
|
||||||
|
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
|
|
||||||
def bm_interface_get_all(context):
|
|
||||||
return IMPL.bm_interface_get_all(context)
|
|
||||||
|
|
||||||
|
|
||||||
def bm_interface_destroy(context, if_id):
|
|
||||||
return IMPL.bm_interface_destroy(context, if_id)
|
|
||||||
|
|
||||||
|
|
||||||
def bm_interface_create(context, bm_node_id, address, datapath_id, port_no):
|
|
||||||
return IMPL.bm_interface_create(context, bm_node_id, address,
|
|
||||||
datapath_id, port_no)
|
|
||||||
|
|
||||||
|
|
||||||
def bm_interface_set_vif_uuid(context, if_id, vif_uuid):
|
|
||||||
return IMPL.bm_interface_set_vif_uuid(context, if_id, vif_uuid)
|
|
||||||
|
|
||||||
|
|
||||||
def bm_interface_get_by_vif_uuid(context, vif_uuid):
|
|
||||||
return IMPL.bm_interface_get_by_vif_uuid(context, vif_uuid)
|
|
||||||
|
|
||||||
|
|
||||||
def bm_interface_get_all_by_bm_node_id(context, bm_node_id):
|
|
||||||
return IMPL.bm_interface_get_all_by_bm_node_id(context, bm_node_id)
|
|
|
@ -1,14 +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.
|
|
|
@ -1,418 +0,0 @@
|
||||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
|
||||||
|
|
||||||
# Copyright (c) 2012 NTT DOCOMO, INC.
|
|
||||||
# Copyright (c) 2011 X.commerce, a business unit of eBay Inc.
|
|
||||||
# Copyright 2010 United States Government as represented by the
|
|
||||||
# Administrator of the National Aeronautics and Space Administration.
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
"""Implementation of SQLAlchemy backend."""
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import uuid
|
|
||||||
|
|
||||||
from sqlalchemy.sql.expression import asc
|
|
||||||
from sqlalchemy.sql.expression import literal_column
|
|
||||||
|
|
||||||
from ironic.common import exception
|
|
||||||
from ironic.openstack.common.db import exception as db_exc
|
|
||||||
from ironic.openstack.common.db.sqlalchemy import session as db_session
|
|
||||||
from ironic.openstack.common import log as logging
|
|
||||||
from ironic.openstack.common import timeutils
|
|
||||||
from ironic.openstack.common import uuidutils
|
|
||||||
from ironic.db.sqlalchemy import models
|
|
||||||
|
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
get_engine = db_session.get_engine
|
|
||||||
get_session = db_session.get_session
|
|
||||||
|
|
||||||
|
|
||||||
def get_backend():
|
|
||||||
"""The backend is this module itself."""
|
|
||||||
return sys.modules[__name__]
|
|
||||||
|
|
||||||
|
|
||||||
def model_query(context, model, *args, **kwargs):
|
|
||||||
"""Query helper that accounts for context's `read_deleted` field.
|
|
||||||
|
|
||||||
:param context: context to query under
|
|
||||||
:param session: if present, the session to use
|
|
||||||
:param read_deleted: if present, overrides context's read_deleted field.
|
|
||||||
:param base_model: Where model_query is passed a "model" parameter which is
|
|
||||||
not a subclass of IronicBase, we should pass an extra base_model
|
|
||||||
parameter that is a subclass of IronicBase and corresponds to the
|
|
||||||
model parameter.
|
|
||||||
"""
|
|
||||||
session = kwargs.get('session') or get_session()
|
|
||||||
read_deleted = kwargs.get('read_deleted') or context.read_deleted
|
|
||||||
|
|
||||||
def issubclassof_ironic_base(obj):
|
|
||||||
return isinstance(obj, type) and issubclass(obj, models.IronicBase)
|
|
||||||
|
|
||||||
base_model = model
|
|
||||||
if not issubclassof_ironic_base(base_model):
|
|
||||||
base_model = kwargs.get('base_model', None)
|
|
||||||
if not issubclassof_nova_base(base_model):
|
|
||||||
raise Exception(_("model or base_model parameter should be "
|
|
||||||
"subclass of IronicBase"))
|
|
||||||
|
|
||||||
query = session.query(model, *args)
|
|
||||||
|
|
||||||
default_deleted_value = base_model.__mapper__.c.deleted.default.arg
|
|
||||||
if read_deleted == 'no':
|
|
||||||
query = query.filter(base_model.deleted == default_deleted_value)
|
|
||||||
elif read_deleted == 'yes':
|
|
||||||
pass # omit the filter to include deleted and active
|
|
||||||
elif read_deleted == 'only':
|
|
||||||
query = query.filter(base_model.deleted != default_deleted_value)
|
|
||||||
else:
|
|
||||||
raise Exception(_("Unrecognized read_deleted value '%s'")
|
|
||||||
% read_deleted)
|
|
||||||
|
|
||||||
return query
|
|
||||||
|
|
||||||
|
|
||||||
def _build_node_order_by(query):
|
|
||||||
query = query.order_by(asc(models.BareMetalNode.memory_mb))
|
|
||||||
query = query.order_by(asc(models.BareMetalNode.cpus))
|
|
||||||
query = query.order_by(asc(models.BareMetalNode.local_gb))
|
|
||||||
return query
|
|
||||||
|
|
||||||
|
|
||||||
def bm_node_get_all(context, service_host=None):
|
|
||||||
query = model_query(context, models.BareMetalNode, read_deleted="no")
|
|
||||||
if service_host:
|
|
||||||
query = query.filter_by(service_host=service_host)
|
|
||||||
return query.all()
|
|
||||||
|
|
||||||
|
|
||||||
def bm_node_get_associated(context, service_host=None):
|
|
||||||
query = model_query(context, models.BareMetalNode, read_deleted="no").\
|
|
||||||
filter(models.BareMetalNode.instance_uuid != None)
|
|
||||||
if service_host:
|
|
||||||
query = query.filter_by(service_host=service_host)
|
|
||||||
return query.all()
|
|
||||||
|
|
||||||
|
|
||||||
def bm_node_get_unassociated(context, service_host=None):
|
|
||||||
query = model_query(context, models.BareMetalNode, read_deleted="no").\
|
|
||||||
filter(models.BareMetalNode.instance_uuid == None)
|
|
||||||
if service_host:
|
|
||||||
query = query.filter_by(service_host=service_host)
|
|
||||||
return query.all()
|
|
||||||
|
|
||||||
|
|
||||||
def bm_node_find_free(context, service_host=None,
|
|
||||||
cpus=None, memory_mb=None, local_gb=None):
|
|
||||||
query = model_query(context, models.BareMetalNode, read_deleted="no")
|
|
||||||
query = query.filter(models.BareMetalNode.instance_uuid == None)
|
|
||||||
if service_host:
|
|
||||||
query = query.filter_by(service_host=service_host)
|
|
||||||
if cpus is not None:
|
|
||||||
query = query.filter(models.BareMetalNode.cpus >= cpus)
|
|
||||||
if memory_mb is not None:
|
|
||||||
query = query.filter(models.BareMetalNode.memory_mb >= memory_mb)
|
|
||||||
if local_gb is not None:
|
|
||||||
query = query.filter(models.BareMetalNode.local_gb >= local_gb)
|
|
||||||
query = _build_node_order_by(query)
|
|
||||||
return query.first()
|
|
||||||
|
|
||||||
|
|
||||||
def bm_node_get(context, bm_node_id):
|
|
||||||
# bm_node_id may be passed as a string. Convert to INT to improve DB perf.
|
|
||||||
bm_node_id = int(bm_node_id)
|
|
||||||
result = model_query(context, models.BareMetalNode, read_deleted="no").\
|
|
||||||
filter_by(id=bm_node_id).\
|
|
||||||
first()
|
|
||||||
|
|
||||||
if not result:
|
|
||||||
raise exception.NodeNotFound(node_id=bm_node_id)
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
def bm_node_get_by_instance_uuid(context, instance_uuid):
|
|
||||||
if not uuidutils.is_uuid_like(instance_uuid):
|
|
||||||
raise exception.InstanceNotFound(instance_id=instance_uuid)
|
|
||||||
|
|
||||||
result = model_query(context, models.BareMetalNode, read_deleted="no").\
|
|
||||||
filter_by(instance_uuid=instance_uuid).\
|
|
||||||
first()
|
|
||||||
|
|
||||||
if not result:
|
|
||||||
raise exception.InstanceNotFound(instance_id=instance_uuid)
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
def bm_node_get_by_node_uuid(context, bm_node_uuid):
|
|
||||||
result = model_query(context, models.BareMetalNode, read_deleted="no").\
|
|
||||||
filter_by(uuid=bm_node_uuid).\
|
|
||||||
first()
|
|
||||||
|
|
||||||
if not result:
|
|
||||||
raise exception.NodeNotFoundByUUID(node_uuid=bm_node_uuid)
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
def bm_node_create(context, values):
|
|
||||||
if not values.get('uuid'):
|
|
||||||
values['uuid'] = str(uuid.uuid4())
|
|
||||||
bm_node_ref = models.BareMetalNode()
|
|
||||||
bm_node_ref.update(values)
|
|
||||||
bm_node_ref.save()
|
|
||||||
return bm_node_ref
|
|
||||||
|
|
||||||
|
|
||||||
def bm_node_update(context, bm_node_id, values):
|
|
||||||
rows = model_query(context, models.BareMetalNode, read_deleted="no").\
|
|
||||||
filter_by(id=bm_node_id).\
|
|
||||||
update(values)
|
|
||||||
|
|
||||||
if not rows:
|
|
||||||
raise exception.NodeNotFound(node_id=bm_node_id)
|
|
||||||
|
|
||||||
|
|
||||||
def bm_node_associate_and_update(context, node_uuid, values):
|
|
||||||
"""Associate an instance to a node safely
|
|
||||||
|
|
||||||
Associate an instance to a node only if that node is not yet assocated.
|
|
||||||
Allow the caller to set any other fields they require in the same
|
|
||||||
operation. For example, this is used to set the node's task_state to
|
|
||||||
BUILDING at the beginning of driver.spawn().
|
|
||||||
|
|
||||||
"""
|
|
||||||
if 'instance_uuid' not in values:
|
|
||||||
raise exception.NovaException(_(
|
|
||||||
"instance_uuid must be supplied to bm_node_associate_and_update"))
|
|
||||||
|
|
||||||
session = db_session.get_session()
|
|
||||||
with session.begin():
|
|
||||||
query = model_query(context, models.BareMetalNode,
|
|
||||||
session=session, read_deleted="no").\
|
|
||||||
filter_by(uuid=node_uuid)
|
|
||||||
|
|
||||||
count = query.filter_by(instance_uuid=None).\
|
|
||||||
update(values, synchronize_session=False)
|
|
||||||
if count != 1:
|
|
||||||
raise exception.NovaException(_(
|
|
||||||
"Failed to associate instance %(i_uuid)s to baremetal node "
|
|
||||||
"%(n_uuid)s.") % {'i_uuid': values['instance_uuid'],
|
|
||||||
'n_uuid': node_uuid})
|
|
||||||
ref = query.first()
|
|
||||||
return ref
|
|
||||||
|
|
||||||
|
|
||||||
def bm_node_destroy(context, bm_node_id):
|
|
||||||
# First, delete all interfaces belonging to the node.
|
|
||||||
# Delete physically since these have unique columns.
|
|
||||||
session = db_session.get_session()
|
|
||||||
with session.begin():
|
|
||||||
model_query(context, models.BareMetalInterface, read_deleted="no").\
|
|
||||||
filter_by(bm_node_id=bm_node_id).\
|
|
||||||
delete()
|
|
||||||
rows = model_query(context, models.BareMetalNode, read_deleted="no").\
|
|
||||||
filter_by(id=bm_node_id).\
|
|
||||||
update({'deleted': True,
|
|
||||||
'deleted_at': timeutils.utcnow(),
|
|
||||||
'updated_at': literal_column('updated_at')})
|
|
||||||
|
|
||||||
if not rows:
|
|
||||||
raise exception.NodeNotFound(node_id=bm_node_id)
|
|
||||||
|
|
||||||
|
|
||||||
def bm_pxe_ip_get_all(context):
|
|
||||||
query = model_query(context, models.BareMetalPxeIp, read_deleted="no")
|
|
||||||
return query.all()
|
|
||||||
|
|
||||||
|
|
||||||
def bm_pxe_ip_create(context, address, server_address):
|
|
||||||
ref = models.BareMetalPxeIp()
|
|
||||||
ref.address = address
|
|
||||||
ref.server_address = server_address
|
|
||||||
ref.save()
|
|
||||||
return ref
|
|
||||||
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
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()
|
|
||||||
|
|
||||||
|
|
||||||
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()
|
|
||||||
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
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})
|
|
||||||
|
|
||||||
|
|
||||||
def bm_interface_get(context, if_id):
|
|
||||||
result = model_query(context, models.BareMetalInterface,
|
|
||||||
read_deleted="no").\
|
|
||||||
filter_by(id=if_id).\
|
|
||||||
first()
|
|
||||||
|
|
||||||
if not result:
|
|
||||||
raise exception.NovaException(_("Baremetal interface %s "
|
|
||||||
"not found") % if_id)
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
def bm_interface_get_all(context):
|
|
||||||
query = model_query(context, models.BareMetalInterface,
|
|
||||||
read_deleted="no")
|
|
||||||
return query.all()
|
|
||||||
|
|
||||||
|
|
||||||
def bm_interface_destroy(context, if_id):
|
|
||||||
# Delete physically since it has unique columns
|
|
||||||
model_query(context, models.BareMetalInterface, read_deleted="no").\
|
|
||||||
filter_by(id=if_id).\
|
|
||||||
delete()
|
|
||||||
|
|
||||||
|
|
||||||
def bm_interface_create(context, bm_node_id, address, datapath_id, port_no):
|
|
||||||
ref = models.BareMetalInterface()
|
|
||||||
ref.bm_node_id = bm_node_id
|
|
||||||
ref.address = address
|
|
||||||
ref.datapath_id = datapath_id
|
|
||||||
ref.port_no = port_no
|
|
||||||
ref.save()
|
|
||||||
return ref.id
|
|
||||||
|
|
||||||
|
|
||||||
def bm_interface_set_vif_uuid(context, if_id, vif_uuid):
|
|
||||||
session = db_session.get_session()
|
|
||||||
with session.begin():
|
|
||||||
bm_interface = model_query(context, models.BareMetalInterface,
|
|
||||||
read_deleted="no", session=session).\
|
|
||||||
filter_by(id=if_id).\
|
|
||||||
with_lockmode('update').\
|
|
||||||
first()
|
|
||||||
if not bm_interface:
|
|
||||||
raise exception.NovaException(_("Baremetal interface %s "
|
|
||||||
"not found") % if_id)
|
|
||||||
|
|
||||||
bm_interface.vif_uuid = vif_uuid
|
|
||||||
try:
|
|
||||||
session.add(bm_interface)
|
|
||||||
session.flush()
|
|
||||||
except db_exc.DBError as e:
|
|
||||||
# TODO(deva): clean up when db layer raises DuplicateKeyError
|
|
||||||
if str(e).find('IntegrityError') != -1:
|
|
||||||
raise exception.NovaException(_("Baremetal interface %s "
|
|
||||||
"already in use") % vif_uuid)
|
|
||||||
else:
|
|
||||||
raise e
|
|
||||||
|
|
||||||
|
|
||||||
def bm_interface_get_by_vif_uuid(context, vif_uuid):
|
|
||||||
result = model_query(context, models.BareMetalInterface,
|
|
||||||
read_deleted="no").\
|
|
||||||
filter_by(vif_uuid=vif_uuid).\
|
|
||||||
first()
|
|
||||||
|
|
||||||
if not result:
|
|
||||||
raise exception.NovaException(_("Baremetal virtual interface %s "
|
|
||||||
"not found") % vif_uuid)
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
def bm_interface_get_all_by_bm_node_id(context, bm_node_id):
|
|
||||||
result = model_query(context, models.BareMetalInterface,
|
|
||||||
read_deleted="no").\
|
|
||||||
filter_by(bm_node_id=bm_node_id).\
|
|
||||||
all()
|
|
||||||
|
|
||||||
if not result:
|
|
||||||
raise exception.NodeNotFound(node_id=bm_node_id)
|
|
||||||
|
|
||||||
return result
|
|
|
@ -1,14 +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.
|
|
|
@ -1,20 +0,0 @@
|
||||||
[db_settings]
|
|
||||||
# Used to identify which repository this database is versioned under.
|
|
||||||
# You can use the name of your project.
|
|
||||||
repository_id=nova_bm
|
|
||||||
|
|
||||||
# The name of the database table used to track the schema version.
|
|
||||||
# This name shouldn't already be used by your project.
|
|
||||||
# If this is changed once a database is under version control, you'll need to
|
|
||||||
# change the table name in each database too.
|
|
||||||
version_table=migrate_version
|
|
||||||
|
|
||||||
# When committing a change script, Migrate will attempt to generate the
|
|
||||||
# sql for all supported databases; normally, if one of them fails - probably
|
|
||||||
# because you don't have that database installed - it is ignored and the
|
|
||||||
# commit continues, perhaps ending successfully.
|
|
||||||
# Databases in this list MUST compile successfully during a commit, or the
|
|
||||||
# entire commit will fail. List the databases your application will actually
|
|
||||||
# be using to ensure your updates to that database work properly.
|
|
||||||
# This must be a list; example: ['postgres','sqlite']
|
|
||||||
required_dbs=[]
|
|
|
@ -1,119 +0,0 @@
|
||||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
|
||||||
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
from sqlalchemy import Boolean, Column, DateTime
|
|
||||||
from sqlalchemy import Index, Integer, MetaData, String, Table
|
|
||||||
|
|
||||||
|
|
||||||
def upgrade(migrate_engine):
|
|
||||||
meta = MetaData()
|
|
||||||
meta.bind = migrate_engine
|
|
||||||
|
|
||||||
bm_nodes = Table('bm_nodes', 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('cpus', Integer),
|
|
||||||
Column('memory_mb', Integer),
|
|
||||||
Column('local_gb', Integer),
|
|
||||||
Column('pm_address', String(length=255)),
|
|
||||||
Column('pm_user', String(length=255)),
|
|
||||||
Column('pm_password', String(length=255)),
|
|
||||||
Column('service_host', String(length=255)),
|
|
||||||
Column('prov_mac_address', String(length=255)),
|
|
||||||
Column('instance_uuid', String(length=36)),
|
|
||||||
Column('registration_status', String(length=16)),
|
|
||||||
Column('task_state', String(length=255)),
|
|
||||||
Column('prov_vlan_id', Integer),
|
|
||||||
Column('terminal_port', Integer),
|
|
||||||
mysql_engine='InnoDB',
|
|
||||||
#mysql_charset='utf8'
|
|
||||||
)
|
|
||||||
|
|
||||||
bm_interfaces = Table('bm_interfaces', 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('bm_node_id', Integer),
|
|
||||||
Column('address', String(length=255), unique=True),
|
|
||||||
Column('datapath_id', String(length=255)),
|
|
||||||
Column('port_no', Integer),
|
|
||||||
Column('vif_uuid', String(length=36), unique=True),
|
|
||||||
mysql_engine='InnoDB',
|
|
||||||
#mysql_charset='utf8'
|
|
||||||
)
|
|
||||||
|
|
||||||
bm_pxe_ips = Table('bm_pxe_ips', 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',
|
|
||||||
#mysql_charset='utf8'
|
|
||||||
)
|
|
||||||
|
|
||||||
bm_deployments = Table('bm_deployments', 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('bm_node_id', Integer),
|
|
||||||
Column('key', String(length=255)),
|
|
||||||
Column('image_path', String(length=255)),
|
|
||||||
Column('pxe_config_path', String(length=255)),
|
|
||||||
Column('root_mb', Integer),
|
|
||||||
Column('swap_mb', Integer),
|
|
||||||
mysql_engine='InnoDB',
|
|
||||||
#mysql_charset='utf8'
|
|
||||||
)
|
|
||||||
|
|
||||||
bm_nodes.create()
|
|
||||||
bm_interfaces.create()
|
|
||||||
bm_pxe_ips.create()
|
|
||||||
bm_deployments.create()
|
|
||||||
|
|
||||||
Index('idx_bm_nodes_service_host_deleted',
|
|
||||||
bm_nodes.c.service_host, bm_nodes.c.deleted)\
|
|
||||||
.create(migrate_engine)
|
|
||||||
Index('idx_bm_nodes_instance_uuid_deleted',
|
|
||||||
bm_nodes.c.instance_uuid, bm_nodes.c.deleted)\
|
|
||||||
.create(migrate_engine)
|
|
||||||
Index('idx_bm_nodes_hmcld',
|
|
||||||
bm_nodes.c.service_host, bm_nodes.c.memory_mb, bm_nodes.c.cpus,
|
|
||||||
bm_nodes.c.local_gb, bm_nodes.c.deleted)\
|
|
||||||
.create(migrate_engine)
|
|
||||||
|
|
||||||
Index('idx_bm_interfaces_bm_node_id_deleted',
|
|
||||||
bm_interfaces.c.bm_node_id, bm_interfaces.c.deleted)\
|
|
||||||
.create(migrate_engine)
|
|
||||||
|
|
||||||
Index('idx_bm_pxe_ips_bm_node_id_deleted',
|
|
||||||
bm_pxe_ips.c.bm_node_id, bm_pxe_ips.c.deleted)\
|
|
||||||
.create(migrate_engine)
|
|
||||||
|
|
||||||
|
|
||||||
def downgrade(migrate_engine):
|
|
||||||
raise NotImplementedError('Downgrade from 001_init is unsupported.')
|
|
|
@ -1,68 +0,0 @@
|
||||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
|
||||||
|
|
||||||
# Copyright 2013 Hewlett-Packard Development Company, L.P.
|
|
||||||
# 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 Column, Index, MetaData, Table
|
|
||||||
from sqlalchemy import Integer, String, DateTime, Boolean
|
|
||||||
|
|
||||||
|
|
||||||
def upgrade(migrate_engine):
|
|
||||||
meta = MetaData()
|
|
||||||
meta.bind = migrate_engine
|
|
||||||
|
|
||||||
bm_nodes = Table('bm_nodes', meta, autoload=True)
|
|
||||||
|
|
||||||
image_path = Column('image_path', String(length=255))
|
|
||||||
pxe_config_path = Column('pxe_config_path', String(length=255))
|
|
||||||
deploy_key = Column('deploy_key', String(length=255))
|
|
||||||
root_mb = Column('root_mb', Integer())
|
|
||||||
swap_mb = Column('swap_mb', Integer())
|
|
||||||
|
|
||||||
for c in [image_path, pxe_config_path, deploy_key, root_mb, swap_mb]:
|
|
||||||
bm_nodes.create_column(c)
|
|
||||||
|
|
||||||
deploy_key_idx = Index('deploy_key_idx', bm_nodes.c.deploy_key)
|
|
||||||
deploy_key_idx.create(migrate_engine)
|
|
||||||
|
|
||||||
bm_deployments = Table('bm_deployments', meta, autoload=True)
|
|
||||||
bm_deployments.drop()
|
|
||||||
|
|
||||||
|
|
||||||
def downgrade(migrate_engine):
|
|
||||||
meta = MetaData()
|
|
||||||
meta.bind = migrate_engine
|
|
||||||
|
|
||||||
bm_nodes = Table('bm_nodes', meta, autoload=True)
|
|
||||||
|
|
||||||
for c in ['image_path', 'pxe_config_path', 'deploy_key', 'root_mb',
|
|
||||||
'swap_mb']:
|
|
||||||
bm_nodes.drop_column(c)
|
|
||||||
|
|
||||||
bm_deployments = Table('bm_deployments', 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('bm_node_id', Integer),
|
|
||||||
Column('key', String(length=255)),
|
|
||||||
Column('image_path', String(length=255)),
|
|
||||||
Column('pxe_config_path', String(length=255)),
|
|
||||||
Column('root_mb', Integer),
|
|
||||||
Column('swap_mb', Integer),
|
|
||||||
mysql_engine='InnoDB',
|
|
||||||
)
|
|
||||||
bm_deployments.create()
|
|
|
@ -1,39 +0,0 @@
|
||||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
|
||||||
|
|
||||||
# Copyright 2013 Hewlett-Packard Development Company, L.P.
|
|
||||||
# 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 Column, MetaData, String, Table, Index
|
|
||||||
|
|
||||||
|
|
||||||
def upgrade(migrate_engine):
|
|
||||||
meta = MetaData()
|
|
||||||
meta.bind = migrate_engine
|
|
||||||
|
|
||||||
t = Table('bm_nodes', meta, autoload=True)
|
|
||||||
uuid_col = Column('uuid', String(36))
|
|
||||||
t.create_column(uuid_col)
|
|
||||||
|
|
||||||
uuid_ux = Index('uuid_ux', t.c.uuid, unique=True)
|
|
||||||
uuid_ux.create(migrate_engine)
|
|
||||||
|
|
||||||
|
|
||||||
def downgrade(migrate_engine):
|
|
||||||
meta = MetaData()
|
|
||||||
meta.bind = migrate_engine
|
|
||||||
|
|
||||||
t = Table('bm_nodes', meta, autoload=True)
|
|
||||||
|
|
||||||
t.drop_column('uuid')
|
|
|
@ -1,35 +0,0 @@
|
||||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
|
||||||
|
|
||||||
# Copyright 2013 Hewlett-Packard Development Company, L.P.
|
|
||||||
# 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 Column, MetaData, String, Table
|
|
||||||
|
|
||||||
|
|
||||||
def upgrade(migrate_engine):
|
|
||||||
meta = MetaData()
|
|
||||||
meta.bind = migrate_engine
|
|
||||||
|
|
||||||
t = Table('bm_nodes', meta, autoload=True)
|
|
||||||
name_col = Column('instance_name', String(255))
|
|
||||||
t.create_column(name_col)
|
|
||||||
|
|
||||||
|
|
||||||
def downgrade(migrate_engine):
|
|
||||||
meta = MetaData()
|
|
||||||
meta.bind = migrate_engine
|
|
||||||
|
|
||||||
t = Table('bm_nodes', meta, autoload=True)
|
|
||||||
t.drop_column('instance_name')
|
|
|
@ -1,35 +0,0 @@
|
||||||
# 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 sqlalchemy import Column, String, Integer, MetaData, Table
|
|
||||||
|
|
||||||
|
|
||||||
def upgrade(migrate_engine):
|
|
||||||
meta = MetaData()
|
|
||||||
meta.bind = migrate_engine
|
|
||||||
|
|
||||||
nodes = Table('bm_nodes', meta, autoload=True)
|
|
||||||
nodes.drop_column('prov_vlan_id')
|
|
||||||
nodes.drop_column('registration_status')
|
|
||||||
|
|
||||||
|
|
||||||
def downgrade(migrate_engine):
|
|
||||||
meta = MetaData()
|
|
||||||
meta.bind = migrate_engine
|
|
||||||
|
|
||||||
nodes = Table('bm_nodes', meta, autoload=True)
|
|
||||||
nodes.create_column(Column('prov_vlan_id', Integer))
|
|
||||||
nodes.create_column(Column('registration_status', String(length=16)))
|
|
|
@ -1,84 +0,0 @@
|
||||||
# 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.
|
|
|
@ -1,14 +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.
|
|
|
@ -1,80 +0,0 @@
|
||||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
|
||||||
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
"""
|
|
||||||
SQLAlchemy models for baremetal data.
|
|
||||||
"""
|
|
||||||
|
|
||||||
from sqlalchemy import Column, Boolean, Integer, String
|
|
||||||
from sqlalchemy.ext.declarative import declarative_base
|
|
||||||
from sqlalchemy import ForeignKey, Text, DateTime, Float
|
|
||||||
|
|
||||||
from ironic.openstack.common.db.sqlalchemy import models
|
|
||||||
|
|
||||||
BASE = declarative_base()
|
|
||||||
|
|
||||||
|
|
||||||
class IronicBase(models.SoftDeleteMixin,
|
|
||||||
models.TimestampMixin,
|
|
||||||
models.ModelBase):
|
|
||||||
metadata = None
|
|
||||||
|
|
||||||
|
|
||||||
class BareMetalNode(BASE, IronicBase):
|
|
||||||
"""Represents a bare metal node."""
|
|
||||||
|
|
||||||
__tablename__ = 'bm_nodes'
|
|
||||||
id = Column(Integer, primary_key=True)
|
|
||||||
deleted = Column(Boolean, default=False)
|
|
||||||
uuid = Column(String(36))
|
|
||||||
service_host = Column(String(255))
|
|
||||||
instance_uuid = Column(String(36), nullable=True)
|
|
||||||
instance_name = Column(String(255), nullable=True)
|
|
||||||
cpus = Column(Integer)
|
|
||||||
memory_mb = Column(Integer)
|
|
||||||
local_gb = Column(Integer)
|
|
||||||
pm_address = Column(Text)
|
|
||||||
pm_user = Column(Text)
|
|
||||||
pm_password = Column(Text)
|
|
||||||
prov_mac_address = Column(Text)
|
|
||||||
task_state = Column(String(255))
|
|
||||||
terminal_port = Column(Integer)
|
|
||||||
image_path = Column(String(255), nullable=True)
|
|
||||||
pxe_config_path = Column(String(255), nullable=True)
|
|
||||||
deploy_key = Column(String(255), nullable=True)
|
|
||||||
root_mb = Column(Integer)
|
|
||||||
swap_mb = Column(Integer)
|
|
||||||
|
|
||||||
|
|
||||||
class BareMetalPxeIp(BASE, IronicBase):
|
|
||||||
__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, IronicBase):
|
|
||||||
__tablename__ = 'bm_interfaces'
|
|
||||||
id = Column(Integer, primary_key=True)
|
|
||||||
deleted = Column(Boolean, default=False)
|
|
||||||
bm_node_id = Column(Integer, ForeignKey('bm_nodes.id'), nullable=True)
|
|
||||||
address = Column(String(255), unique=True)
|
|
||||||
datapath_id = Column(String(255))
|
|
||||||
port_no = Column(Integer)
|
|
||||||
vif_uuid = Column(String(36), unique=True)
|
|
Loading…
Reference in New Issue