diff --git a/dolphin/db/__init__.py b/dolphin/db/__init__.py index fc4da9c61..12908fed3 100644 --- a/dolphin/db/__init__.py +++ b/dolphin/db/__init__.py @@ -16,5 +16,4 @@ """ DB abstraction for Dolphin """ - -# from dolphin.db.api import * # noqa +from dolphin.db.api import * # noqa diff --git a/dolphin/db/api.py b/dolphin/db/api.py new file mode 100755 index 000000000..c96d56a2a --- /dev/null +++ b/dolphin/db/api.py @@ -0,0 +1,106 @@ +# 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 dolphin.db namespace. Call these +functions from dolphin.db namespace, not the dolphin.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** + +:backend: string to lookup in the list of LazyPluggable backends. + `sqlalchemy` is the only supported backend right now. + +:connection: string specifying the sqlalchemy connection to use, like: + `sqlite:///var/lib/dolphin/dolphin.sqlite`. + +:enable_new_services: when adding a new service to the database, is it in the + pool of available hardware (Default: True) + +""" +from oslo_config import cfg +from oslo_db import api as db_api + +db_opts = [ + cfg.StrOpt('db_backend', + default='sqlalchemy', + help='The backend to use for database.'), + +] + +CONF = cfg.CONF +CONF.register_opts(db_opts) + +_BACKEND_MAPPING = {'sqlalchemy': 'dolphin.db.sqlalchemy.api'} +IMPL = db_api.DBAPI.from_config(cfg.CONF, backend_mapping=_BACKEND_MAPPING, + lazy=True) + + +def register_db(): + IMPL.register_db() + + +def storage_get(storage_id): + return IMPL.storage_get(storage_id) + + +def storage_create(storage): + IMPL.storage_create(storage) + + +def volume_create(volume, storage_id): + IMPL.volume_create(volume) + + +def volume_get(volume_id, storage_id): + IMPL.volume_get(volume_id, storage_id) + + +def volume_get_all(storage_id): + IMPL.volume_get_all(storage_id) + + +def pool_create(pool, storage_id): + IMPL.pool_create(pool) + + +def pool_get(pool_id, storage_id): + IMPL.pool_get(pool_id, storage_id) + + +def pool_get_all(storage_id): + IMPL.pool_get_all(storage_id) + + +def registry_context_create(register_info): + return IMPL.registry_context_create(register_info) + + +def registry_context_get(storage_id): + return IMPL.registry_context_get(storage_id) + + +def registry_context_get_all(): + return IMPL.registry_context_get_all() \ No newline at end of file diff --git a/dolphin/db/sqlalchemy/__init__.py b/dolphin/db/sqlalchemy/__init__.py new file mode 100755 index 000000000..e69de29bb diff --git a/dolphin/db/sqlalchemy/api.py b/dolphin/db/sqlalchemy/api.py new file mode 100755 index 000000000..0f5c6c01a --- /dev/null +++ b/dolphin/db/sqlalchemy/api.py @@ -0,0 +1,123 @@ +# 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. +# Copyright (c) 2014 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. + +"""Implementation of SQLAlchemy backend.""" + +from functools import wraps +import sys +from oslo_config import cfg +from oslo_db import options as db_options +from oslo_db.sqlalchemy import session +from oslo_log import log +from sqlalchemy import create_engine +from dolphin.db.sqlalchemy import models +from dolphin.db.sqlalchemy.models import Storage, RegistryContext + +CONF = cfg.CONF +LOG = log.getLogger(__name__) +_FACADE = None + +_DEFAULT_SQL_CONNECTION = 'sqlite:///' +db_options.set_defaults(cfg.CONF, + connection=_DEFAULT_SQL_CONNECTION) + + +def get_engine(): + facade = _create_facade_lazily() + return facade.get_engine() + + +def get_session(**kwargs): + facade = _create_facade_lazily() + return facade.get_session(**kwargs) + + +def _create_facade_lazily(): + global _FACADE + if _FACADE is None: + _FACADE = session.EngineFacade.from_config(cfg.CONF) + return _FACADE + + +def get_backend(): + """The backend is this module itself.""" + return sys.modules[__name__] + + +def register_db(): + engine = create_engine(_DEFAULT_SQL_CONNECTION, echo=False) + models = (Storage, + RegistryContext + ) + engine = create_engine(CONF.database.connection, echo=False) + for model in models: + model.metadata.create_all(engine) + + +def registry_context_create(register_info): + register_ref = models.RegistryContext() + register_ref.storage_id = register_info.storage_id + register_ref.username = register_info.username + register_ref.hostname = register_info.hostname + register_ref.password = register_info.password + register_ref.extra_attributes = register_info.extra_attributes + this_session = get_session() + this_session.begin() + this_session.add(register_ref) + this_session.commit() + return register_ref + + +def registry_context_get(storage_id): + this_session = get_session() + this_session.begin() + registry_context = this_session.query(RegistryContext) \ + .filter(RegistryContext.storage_id == storage_id) \ + .first() + return registry_context + + +def registry_context_get_all(): + this_session = get_session() + this_session.begin() + registry_context = this_session.query(RegistryContext).all() + return registry_context + + +def storage_create(storage): + storage_ref = models.Storage() + storage_ref.id = storage.id + storage_ref.name = storage.name + storage_ref.model = storage.model + storage_ref.vendor = storage.vendor + storage_ref.description = storage.description + storage_ref.location = storage.location + this_session = get_session() + this_session.begin() + this_session.add(storage_ref) + this_session.commit() + return storage_ref + + +def storage_get(storage_id): + this_session = get_session() + this_session.begin() + storage_by_id = this_session.query(Storage) \ + .filter(Storage.id == storage_id) \ + .first() + return storage_by_id diff --git a/dolphin/db/sqlalchemy/models.py b/dolphin/db/sqlalchemy/models.py new file mode 100755 index 000000000..9ee45b437 --- /dev/null +++ b/dolphin/db/sqlalchemy/models.py @@ -0,0 +1,94 @@ +# 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. +# Copyright 2011 Piston Cloud Computing, 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 Dolphin data. +""" +import json + +from oslo_config import cfg +from oslo_db.sqlalchemy import models +from oslo_db.sqlalchemy.types import JsonEncodedDict +from sqlalchemy import Column, Integer, String, Numeric +from sqlalchemy.ext.declarative import declarative_base + +CONF = cfg.CONF +BASE = declarative_base() + + +class DolphinBase(models.ModelBase, + models.TimestampMixin): + """Base class for Dolphin Models.""" + __table_args__ = {'mysql_engine': 'InnoDB'} + metadata = None + + +class RegistryContext(BASE, DolphinBase): + """Represent registration parameters required for storage object.""" + __tablename__ = "registry_contexts" + storage_id = Column(String(36), primary_key=True) + hostname = Column(String(36), default='False') + username = Column(String(255)) + password = Column(String(255)) + vendor = Column(String(255)) + model = Column(String(255)) + extra_attributes = Column(JsonEncodedDict) + + +class Storage(BASE, DolphinBase): + """Represents a storage object.""" + + __tablename__ = 'storages' + id = Column(String(36), primary_key=True) + name = Column(String(255)) + vendor = Column(String(255)) + description = Column(String(255)) + model = Column(String(255)) + status = Column(String(255)) + serial_number = Column(String(255)) + location = Column(String(255)) + total_capacity = Column(Numeric) + used_capacity = Column(Numeric) + free_capacity = Column(Numeric) + + + +class Volume(BASE, DolphinBase): + """Represents a volume object.""" + __tablename__ = 'volumes' + id = Column(Integer, primary_key=True) + name = Column(String(255)) + storage_id = Column(String(255)) + pool_id = Column(String(255)) + description = Column(String(255)) + status = Column(String(255)) + total_capacity = Column(Numeric) + used_capacity = Column(Numeric) + free_capacity = Column(Numeric) + + +class Pool(BASE, DolphinBase): + """Represents a pool object.""" + __tablename__ = 'pools' + id = Column(Integer, primary_key=True) + name = Column(String(255)) + storage_id = Column(String(255)) + description = Column(String(255)) + status = Column(String(255)) + total_capacity = Column(Numeric) + used_capacity = Column(Numeric) + free_capacity = Column(Numeric) diff --git a/etc/dolphin/dolphin.conf b/etc/dolphin/dolphin.conf index 85a005a1e..14311d3bc 100644 --- a/etc/dolphin/dolphin.conf +++ b/etc/dolphin/dolphin.conf @@ -1,3 +1,5 @@ [DEFAULT] api_paste_config = C:\pythonpath\dolphin\etc\dolphin\api-paste.ini +[database] +connection = sqlite:////var/lib/dolphin/dolphin.sqlite \ No newline at end of file