Implement skeleton for a new DB backend.
This commit is contained in:
parent
6102857bd9
commit
aee8142fb4
@ -39,9 +39,8 @@ def get_pecan_config():
|
||||
|
||||
|
||||
def setup_app(pecan_config=None, extra_hooks=None):
|
||||
# FIXME: Replace DBHook with a hooks.TransactionHook
|
||||
app_hooks = [hooks.ConfigHook()]
|
||||
# hooks.DBHook()]
|
||||
app_hooks = [hooks.ConfigHook(),
|
||||
hooks.DBHook()]
|
||||
if extra_hooks:
|
||||
app_hooks.extend(extra_hooks)
|
||||
|
||||
@ -62,6 +61,7 @@ def setup_app(pecan_config=None, extra_hooks=None):
|
||||
force_canonical=getattr(pecan_config.app, 'force_canonical', True),
|
||||
hooks=app_hooks,
|
||||
)
|
||||
# TODO: add this back in
|
||||
# wrap_app=middleware.ParsableErrorMiddleware,
|
||||
|
||||
if pecan_config.app.enable_acl:
|
||||
|
@ -61,9 +61,10 @@ class Interface(Base):
|
||||
node_id = int
|
||||
address = wtypes.text
|
||||
|
||||
def __init__(self, node_id=None, address=None):
|
||||
self.node_id = node_id
|
||||
self.address = address
|
||||
def __init__(self, **kwargs):
|
||||
self.fields = list(kwargs)
|
||||
for k, v in kwargs.iteritems():
|
||||
setattr(self, k, v)
|
||||
|
||||
@classmethod
|
||||
def sample(cls):
|
||||
@ -108,19 +109,15 @@ class Node(Base):
|
||||
"""A representation of a bare metal node"""
|
||||
|
||||
uuid = wtypes.text
|
||||
cpus = int
|
||||
memory_mb = int
|
||||
|
||||
def __init__(self, uuid=None, cpus=None, memory_mb=None):
|
||||
self.uuid = uuid
|
||||
self.cpus = cpus
|
||||
self.memory_mb = memory_mb
|
||||
def __init__(self, **kwargs):
|
||||
self.fields = list(kwargs)
|
||||
for k, v in kwargs.iteritems():
|
||||
setattr(self, k, v)
|
||||
|
||||
@classmethod
|
||||
def sample(cls):
|
||||
return cls(uuid='1be26c0b-03f2-4d2e-ae87-c02d7f33c123',
|
||||
cpus=2,
|
||||
memory_mb=1024,
|
||||
)
|
||||
|
||||
|
||||
@ -141,9 +138,8 @@ class NodesController(rest.RestController):
|
||||
@wsme_pecan.wsexpose(Node, unicode)
|
||||
def get_one(self, node_id):
|
||||
"""Retrieve information about the given node."""
|
||||
one = Node.sample()
|
||||
one.uuid = node_id
|
||||
return one
|
||||
r = pecan.request.dbapi.get_node_by_id(node_id)
|
||||
return r
|
||||
|
||||
@wsme_pecan.wsexpose()
|
||||
def delete(self, node_id):
|
||||
|
@ -19,7 +19,7 @@
|
||||
from oslo.config import cfg
|
||||
from pecan import hooks
|
||||
|
||||
from ironic import db
|
||||
from ironic.db import api as dbapi
|
||||
|
||||
|
||||
class ConfigHook(hooks.PecanHook):
|
||||
@ -34,12 +34,4 @@ class ConfigHook(hooks.PecanHook):
|
||||
class DBHook(hooks.PecanHook):
|
||||
|
||||
def before(self, state):
|
||||
# FIXME
|
||||
storage_engine = storage.get_engine(state.request.cfg)
|
||||
state.request.storage_engine = storage_engine
|
||||
state.request.storage_conn = storage_engine.get_connection(
|
||||
state.request.cfg)
|
||||
|
||||
# def after(self, state):
|
||||
# print 'method:', state.request.method
|
||||
# print 'response:', state.response.status
|
||||
state.request.dbapi = dbapi.get_instance()
|
||||
|
38
ironic/cmd/dbsync.py
Normal file
38
ironic/cmd/dbsync.py
Normal file
@ -0,0 +1,38 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- encoding: utf-8 -*-
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""
|
||||
Run storage database migration.
|
||||
"""
|
||||
|
||||
import sys
|
||||
|
||||
from oslo.config import cfg
|
||||
|
||||
from ironic.common import service
|
||||
from ironic.db import migration
|
||||
|
||||
CONF = cfg.CONF
|
||||
CONF.import_opt('db_backend',
|
||||
'ironic.openstack.common.db.api')
|
||||
|
||||
def main():
|
||||
service.prepare_service(sys.argv)
|
||||
migration.db_sync()
|
122
ironic/db/api.py
Normal file
122
ironic/db/api.py
Normal file
@ -0,0 +1,122 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
# -*- encoding: utf-8 -*-
|
||||
#
|
||||
# Copyright 2013 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# 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.
|
||||
"""
|
||||
Base classes for storage engines
|
||||
"""
|
||||
|
||||
import abc
|
||||
|
||||
from ironic.openstack.common.db import api as db_api
|
||||
|
||||
_BACKEND_MAPPING = {'sqlalchemy': 'ironic.db.sqlalchemy.api'}
|
||||
|
||||
|
||||
def get_instance():
|
||||
"""Return a DB API instance."""
|
||||
IMPL = db_api.DBAPI(backend_mapping=_BACKEND_MAPPING)
|
||||
return IMPL
|
||||
|
||||
|
||||
class Connection(object):
|
||||
"""Base class for storage system connections."""
|
||||
|
||||
__metaclass__ = abc.ABCMeta
|
||||
|
||||
@abc.abstractmethod
|
||||
def __init__(self):
|
||||
"""Constructor."""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_nodes(self, columns):
|
||||
"""Return a list of dicts of all nodes.
|
||||
|
||||
:param columns: List of columns to return.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_associated_nodes(self):
|
||||
"""Return a list of ids of all associated nodes."""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_unassociated_nodes(self):
|
||||
"""Return a list of ids of all unassociated nodes."""
|
||||
|
||||
@abc.abstractmethod
|
||||
def reserve_node(self, *args, **kwargs):
|
||||
"""Find a free node and associate it.
|
||||
|
||||
TBD
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def create_node(self, *args, **kwargs):
|
||||
"""Create a new node."""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_node_by_id(self, node_id):
|
||||
"""Return a node.
|
||||
|
||||
:param node_id: The id or uuid of a node.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_node_by_instance_id(self, instance_id):
|
||||
"""Return a node.
|
||||
|
||||
:param instance_id: The instance id or uuid of a node.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def destroy_node(self, node_id):
|
||||
"""Destroy a node.
|
||||
|
||||
:param node_id: The id or uuid of a node.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def update_node(self, node_id, *args, **kwargs):
|
||||
"""Update properties of a node.
|
||||
|
||||
:param node_id: The id or uuid of a node.
|
||||
TBD
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_iface(self, iface_id):
|
||||
"""Return an interface.
|
||||
|
||||
:param iface_id: The id or MAC of an interface.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def create_iface(self, *args, **kwargs):
|
||||
"""Create a new iface."""
|
||||
|
||||
@abc.abstractmethod
|
||||
def update_iface(self, iface_id, *args, **kwargs):
|
||||
"""Update properties of an iface.
|
||||
|
||||
:param iface_id: The id or MAC of an interface.
|
||||
TBD
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def destroy_iface(self, iface_id):
|
||||
"""Destroy an iface.
|
||||
|
||||
:param iface_id: The id or MAC of an interface.
|
||||
"""
|
69
ironic/db/models.py
Normal file
69
ironic/db/models.py
Normal file
@ -0,0 +1,69 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
#
|
||||
# Copyright © 2013 New Dream Network, LLC (DreamHost)
|
||||
#
|
||||
# Author: Doug Hellmann <doug.hellmann@dreamhost.com>
|
||||
#
|
||||
# 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.
|
||||
"""
|
||||
Model classes for use in the storage API.
|
||||
"""
|
||||
|
||||
|
||||
class Model(object):
|
||||
"""Base class for storage API models.
|
||||
"""
|
||||
|
||||
def __init__(self, **kwds):
|
||||
self.fields = list(kwds)
|
||||
for k, v in kwds.iteritems():
|
||||
setattr(self, k, v)
|
||||
|
||||
def as_dict(self):
|
||||
d = {}
|
||||
for f in self.fields:
|
||||
v = getattr(self, f)
|
||||
if isinstance(v, Model):
|
||||
v = v.as_dict()
|
||||
elif isinstance(v, list) and v and isinstance(v[0], Model):
|
||||
v = [sub.as_dict() for sub in v]
|
||||
d[f] = v
|
||||
return d
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.as_dict() == other.as_dict()
|
||||
|
||||
|
||||
class Node(Model):
|
||||
"""Representation of a bare metal node."""
|
||||
|
||||
def __init__(self, uuid, power_info, task_state, image_path,
|
||||
instance_uuid, instance_name, extra):
|
||||
Model.__init__(uuid=uuid,
|
||||
power_info=power_info,
|
||||
task_state=task_state,
|
||||
image_path=image_path,
|
||||
instance_uuid=instance_uuid,
|
||||
instance_name=instance_name,
|
||||
extra=extra,
|
||||
)
|
||||
|
||||
|
||||
class Iface(Model):
|
||||
"""Representation of a NIC."""
|
||||
|
||||
def __init__(self, mac, node_id, extra):
|
||||
Model.__init__(mac=mac,
|
||||
node_id=node_id,
|
||||
extra=extra,
|
||||
)
|
0
ironic/db/sqlalchemy/__init__.py
Normal file
0
ironic/db/sqlalchemy/__init__.py
Normal file
195
ironic/db/sqlalchemy/api.py
Normal file
195
ironic/db/sqlalchemy/api.py
Normal file
@ -0,0 +1,195 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
# -*- encoding: utf-8 -*-
|
||||
#
|
||||
# Copyright 2013 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# 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 storage backend."""
|
||||
|
||||
import sys
|
||||
import uuid
|
||||
|
||||
from oslo.config import cfg
|
||||
|
||||
from sqlalchemy.orm.exc import NoResultFound
|
||||
from sqlalchemy.orm.exc import MultipleResultsFound
|
||||
|
||||
from ironic.common import exception
|
||||
from ironic.db import api
|
||||
from ironic.db.sqlalchemy.models import Node, Iface
|
||||
from ironic.openstack.common.db.sqlalchemy import session as db_session
|
||||
from ironic.openstack.common import log
|
||||
from ironic.openstack.common import uuidutils
|
||||
|
||||
CONF = cfg.CONF
|
||||
CONF.import_opt('sql_connection',
|
||||
'ironic.openstack.common.db.sqlalchemy.session')
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
get_engine = db_session.get_engine
|
||||
get_session = db_session.get_session
|
||||
|
||||
def get_backend():
|
||||
"""The backend is this module itself."""
|
||||
return Connection()
|
||||
|
||||
|
||||
# - nodes
|
||||
# - { id: AUTO_INC INTEGER
|
||||
# uuid: node uuid
|
||||
# power_info: JSON of power mgmt information
|
||||
# task_state: current task
|
||||
# image_path: URL of associated image
|
||||
# instance_uuid: uuid of associated instance
|
||||
# instance_name: name of associated instance
|
||||
# hw_spec_id: hw specification id (->hw_specs.id)
|
||||
# inst_spec_id: instance specification id (->inst_specs.id)
|
||||
# extra: JSON blob of extra data
|
||||
# }
|
||||
# - ifaces
|
||||
# - { id: AUTO_INC INTEGER
|
||||
# mac: MAC address of this iface
|
||||
# node_id: associated node (->nodes.id)
|
||||
# ?datapath_id
|
||||
# ?port_no
|
||||
# ?model
|
||||
# extra: JSON blob of extra data
|
||||
# }
|
||||
# - hw_specs
|
||||
# - { id: AUTO_INC INTEGER
|
||||
# cpu_arch:
|
||||
# n_cpu:
|
||||
# n_disk:
|
||||
# ram_mb:
|
||||
# storage_gb:
|
||||
# }
|
||||
# - inst_specs
|
||||
# - { id: AUTO_INC INTEGER
|
||||
# root_mb:
|
||||
# swap_mb:
|
||||
# image_path:
|
||||
# }
|
||||
|
||||
|
||||
def model_query(model, *args, **kwargs):
|
||||
"""Query helper for simpler session usage.
|
||||
|
||||
:param session: if present, the session to use
|
||||
"""
|
||||
|
||||
session = kwargs.get('session') or get_session()
|
||||
query = session.query(model, *args)
|
||||
return query
|
||||
|
||||
|
||||
class Connection(api.Connection):
|
||||
"""SqlAlchemy connection."""
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def get_nodes(self, columns):
|
||||
"""Return a list of dicts of all nodes.
|
||||
|
||||
:param columns: List of columns to return.
|
||||
"""
|
||||
pass
|
||||
|
||||
def get_associated_nodes(self):
|
||||
"""Return a list of ids of all associated nodes."""
|
||||
pass
|
||||
|
||||
def get_unassociated_nodes(self):
|
||||
"""Return a list of ids of all unassociated nodes."""
|
||||
pass
|
||||
|
||||
def reserve_node(self, *args, **kwargs):
|
||||
"""Find a free node and associate it.
|
||||
|
||||
TBD
|
||||
"""
|
||||
pass
|
||||
|
||||
def create_node(self, *args, **kwargs):
|
||||
"""Create a new node."""
|
||||
node = Node()
|
||||
|
||||
def get_node_by_id(self, node_id):
|
||||
"""Return a node.
|
||||
|
||||
:param node_id: The id or uuid of a node.
|
||||
"""
|
||||
query = model_query(Node)
|
||||
if uuidutils.is_uuid_like(node_id):
|
||||
query.filter_by(uuid=node_id)
|
||||
else:
|
||||
query.filter_by(id=node_id)
|
||||
|
||||
try:
|
||||
result = query.one()
|
||||
except NoResultFound:
|
||||
raise
|
||||
except MultipleResultsFound:
|
||||
raise
|
||||
return result
|
||||
|
||||
|
||||
def get_node_by_instance_id(self, instance_id):
|
||||
"""Return a node.
|
||||
|
||||
:param instance_id: The instance id or uuid of a node.
|
||||
"""
|
||||
pass
|
||||
|
||||
def destroy_node(self, node_id):
|
||||
"""Destroy a node.
|
||||
|
||||
:param node_id: The id or uuid of a node.
|
||||
"""
|
||||
pass
|
||||
|
||||
def update_node(self, node_id, *args, **kwargs):
|
||||
"""Update properties of a node.
|
||||
|
||||
:param node_id: The id or uuid of a node.
|
||||
TBD
|
||||
"""
|
||||
pass
|
||||
|
||||
def get_iface(self, iface_id):
|
||||
"""Return an interface.
|
||||
|
||||
:param iface_id: The id or MAC of an interface.
|
||||
"""
|
||||
pass
|
||||
|
||||
def create_iface(self, *args, **kwargs):
|
||||
"""Create a new iface."""
|
||||
pass
|
||||
|
||||
def update_iface(self, iface_id, *args, **kwargs):
|
||||
"""Update properties of an iface.
|
||||
|
||||
:param iface_id: The id or MAC of an interface.
|
||||
TBD
|
||||
"""
|
||||
pass
|
||||
|
||||
def destroy_iface(self, iface_id):
|
||||
"""Destroy an iface.
|
||||
|
||||
:param iface_id: The id or MAC of an interface.
|
||||
"""
|
||||
pass
|
0
ironic/db/sqlalchemy/migrate_repo/__init__.py
Normal file
0
ironic/db/sqlalchemy/migrate_repo/__init__.py
Normal file
22
ironic/db/sqlalchemy/migrate_repo/manage.py
Normal file
22
ironic/db/sqlalchemy/migrate_repo/manage.py
Normal file
@ -0,0 +1,22 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
# -*- encoding: utf-8 -*-
|
||||
#
|
||||
# Copyright 2013 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# 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 migrate.versioning.shell import main
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main(debug='False', repository='.')
|
20
ironic/db/sqlalchemy/migrate_repo/migrate.cfg
Normal file
20
ironic/db/sqlalchemy/migrate_repo/migrate.cfg
Normal file
@ -0,0 +1,20 @@
|
||||
[db_settings]
|
||||
# Used to identify which repository this database is versioned under.
|
||||
# You can use the name of your project.
|
||||
repository_id=ironic
|
||||
|
||||
# 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=[]
|
81
ironic/db/sqlalchemy/migrate_repo/versions/001_init.py
Normal file
81
ironic/db/sqlalchemy/migrate_repo/versions/001_init.py
Normal file
@ -0,0 +1,81 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
# -*- encoding: utf-8 -*-
|
||||
#
|
||||
# Copyright 2013 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# 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 migrate.changeset import UniqueConstraint
|
||||
from sqlalchemy import Table, Column, Index, ForeignKey, MetaData
|
||||
from sqlalchemy import Boolean, DateTime, Float, Integer, String, Text
|
||||
|
||||
from ironic.openstack.common import log as logging
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
ENGINE='InnoDB'
|
||||
CHARSET='utf8'
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
meta = MetaData()
|
||||
meta.bind = migrate_engine
|
||||
|
||||
nodes = Table('nodes', meta,
|
||||
Column('id', Integer, primary_key=True, nullable=False),
|
||||
Column('uuid', String(length=26)),
|
||||
Column('power_info', Text),
|
||||
Column('task_state', String(length=255)),
|
||||
Column('image_path', String(length=255), nullable=True),
|
||||
Column('instance_uuid', String(length=255), nullable=True),
|
||||
Column('instance_name', String(length=255), nullable=True),
|
||||
Column('extra', Text),
|
||||
Column('created_at', DateTime),
|
||||
Column('updated_at', DateTime),
|
||||
mysql_engine=ENGINE,
|
||||
mysql_charset=CHARSET,
|
||||
)
|
||||
|
||||
ifaces = Table('ifaces', meta,
|
||||
Column('id', Integer, primary_key=True, nullable=False),
|
||||
Column('uuid', String(length=26)),
|
||||
Column('node_id', Integer, ForeignKey('nodes.id'),
|
||||
nullable=True),
|
||||
Column('extra', Text),
|
||||
Column('created_at', DateTime),
|
||||
Column('updated_at', DateTime),
|
||||
mysql_engine=ENGINE,
|
||||
mysql_charset=CHARSET,
|
||||
)
|
||||
|
||||
tables = [nodes, ifaces]
|
||||
for table in tables:
|
||||
try:
|
||||
table.create()
|
||||
except Exception:
|
||||
LOG.info(repr(table))
|
||||
LOG.Exception(_('Exception while creating table.'))
|
||||
raise
|
||||
|
||||
indexes = [
|
||||
Index('uuid', nodes.c.uuid),
|
||||
Index('uuid', ifaces.c.uuid),
|
||||
]
|
||||
|
||||
if migrate_engine.name == 'mysql' or migrate_engine.name == 'postgresql':
|
||||
for index in indexes:
|
||||
index.create(migrate_engine)
|
||||
|
||||
def downgrade(migrate_engine):
|
||||
raise NotImplementedError('Downgrade from Folsom is unsupported.')
|
@ -19,15 +19,14 @@
|
||||
import distutils.version as dist_version
|
||||
import os
|
||||
|
||||
from ironic.common import exception
|
||||
from ironic.db import migration
|
||||
from ironic.openstack.common.db.sqlalchemy import session as db_session
|
||||
|
||||
|
||||
import migrate
|
||||
from migrate.versioning import util as migrate_util
|
||||
import sqlalchemy
|
||||
|
||||
from ironic.common import exception
|
||||
from ironic.db import migration
|
||||
from ironic.openstack.common.db.sqlalchemy import session as db_session
|
||||
|
||||
|
||||
@migrate_util.decorator
|
||||
def patched_with_engine(f, *a, **kw):
|
||||
|
102
ironic/db/sqlalchemy/models.py
Normal file
102
ironic/db/sqlalchemy/models.py
Normal file
@ -0,0 +1,102 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
# -*- encoding: utf-8 -*-
|
||||
#
|
||||
# Copyright 2013 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# 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.
|
||||
"""
|
||||
|
||||
import urlparse
|
||||
|
||||
from oslo.config import cfg
|
||||
|
||||
from sqlalchemy import Table, Column, Index, ForeignKey
|
||||
from sqlalchemy import Boolean, DateTime, Float, Integer, String, Text
|
||||
from sqlalchemy.ext.declarative import declarative_base
|
||||
|
||||
from ironic.openstack.common.db.sqlalchemy import models
|
||||
|
||||
sql_opts = [
|
||||
cfg.StrOpt('mysql_engine',
|
||||
default='InnoDB',
|
||||
help='MySQL engine')
|
||||
]
|
||||
|
||||
cfg.CONF.register_opts(sql_opts)
|
||||
|
||||
|
||||
def table_args():
|
||||
engine_name = urlparse.urlparse(cfg.CONF.database_connection).scheme
|
||||
if engine_name == 'mysql':
|
||||
return {'mysql_engine': cfg.CONF.mysql_engine,
|
||||
'mysql_charset': "utf8"}
|
||||
return None
|
||||
|
||||
class IronicBase(models.TimestampMixin,
|
||||
models.ModelBase):
|
||||
metadata = None
|
||||
|
||||
|
||||
Base = declarative_base(cls=IronicBase)
|
||||
|
||||
|
||||
class Node(Base):
|
||||
"""Represents a bare metal node."""
|
||||
|
||||
__tablename__ = 'nodes'
|
||||
id = Column(Integer, primary_key=True)
|
||||
uuid = Column(String(36))
|
||||
power_info = Column(Text)
|
||||
task_state = Column(String(255))
|
||||
image_path = Column(String(255), nullable=True)
|
||||
instance_uuid = Column(String(36), nullable=True)
|
||||
instance_name = Column(String(255), nullable=True)
|
||||
extra = Column(Text)
|
||||
|
||||
|
||||
class Iface(Base):
|
||||
"""Represents a NIC in a bare metal node."""
|
||||
|
||||
__tablename__ = 'ifaces'
|
||||
id = Column(Integer, primary_key=True)
|
||||
mac = Column(String(255), unique=True)
|
||||
node_id = Column(Integer, ForeignKey('nodes.id'), nullable=True)
|
||||
extra = Column(Text)
|
||||
|
||||
|
||||
class HwSpec(Base):
|
||||
"""Represents a unique hardware class."""
|
||||
|
||||
__tablename__ = 'hw_specs'
|
||||
id = Column(Integer, primary_key=True)
|
||||
uuid = Column(String(36))
|
||||
cpu_arch = Column(String(255))
|
||||
n_cpu = Column(Integer)
|
||||
ram_mb = Column(Integer)
|
||||
storage_gb = Column(Integer)
|
||||
name = Column(String(255), nullable=True)
|
||||
n_disk = Column(Integer, nullable=True)
|
||||
|
||||
|
||||
class InstSpec(Base):
|
||||
"""Represents a unique instance class."""
|
||||
|
||||
__tablename__ = 'inst_specs'
|
||||
id = Column(Integer, primary_key=True)
|
||||
uuid = Column(String(36))
|
||||
root_mb = Column(Integer)
|
||||
swap_mb = Column(Integer)
|
||||
name = Column(String(255), nullable=True)
|
@ -29,6 +29,7 @@ packages =
|
||||
[entry_points]
|
||||
console_scripts =
|
||||
ironic-api = ironic.cmd.api:main
|
||||
ironic-dbsync = ironic.cmd.dbsync:main
|
||||
ironic-manager = ironic.cmd.manager:main
|
||||
|
||||
[build_sphinx]
|
||||
|
21
setup.py
21
setup.py
@ -16,6 +16,25 @@
|
||||
|
||||
import setuptools
|
||||
|
||||
from ironic.openstack.common import setup as common_setup
|
||||
|
||||
project = 'ironic'
|
||||
|
||||
setuptools.setup(
|
||||
name=project,
|
||||
version=common_setup.get_version(project, '2013.1'),
|
||||
description='Bare Metal controller',
|
||||
classifiers=[
|
||||
'Environment :: OpenStack',
|
||||
'Intended Audience :: Information Technology',
|
||||
'Intended Audience :: System Administrators',
|
||||
'License :: OSI Approved :: Apache Software License',
|
||||
'Operating System :: POSIX :: Linux',
|
||||
'Programming Language :: Python',
|
||||
'Programming Language :: Python :: 2',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
],
|
||||
include_package_data=True,
|
||||
setup_requires=['d2to1>=0.2.10,<0.3', 'pbr>=0.5,<0.6'],
|
||||
d2to1=True)
|
||||
d2to1=True,
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user