From 61b4b533c055e98737d8a5f75426c83945383a83 Mon Sep 17 00:00:00 2001 From: Kevin Zhao Date: Mon, 17 Jul 2017 22:43:47 +0800 Subject: [PATCH] Add the capsule DB method Part of blueprint introduce-compose Change-Id: I3908ae25ad54f69b29731c2bce0c1e3840887df3 Signed-off-by: Kevin Zhao --- zun/db/api.py | 77 ++++++++++++++++++++++++++++++++++++++++ zun/db/sqlalchemy/api.py | 72 +++++++++++++++++++++++++++++++++++++ 2 files changed, 149 insertions(+) diff --git a/zun/db/api.py b/zun/db/api.py index 07f163690..97b9ff362 100644 --- a/zun/db/api.py +++ b/zun/db/api.py @@ -651,3 +651,80 @@ def update_compute_node(context, node_uuid, values): """ return _get_dbdriver_instance().update_compute_node( context, node_uuid, values) + + +@profiler.trace("db") +def list_capsules(context, filters=None, limit=None, marker=None, + sort_key=None, sort_dir=None): + """List matching capsules. + + Return a list of the specified columns for all capsules that match + the specified filters. + :param context: The security context + :param filters: Filters to apply. Defaults to None. + :param limit: Maximum number of capsules to return. + :param marker: the last item of the previous page; we return the next + result set. + :param sort_key: Attribute by which results should be sorted. + :param sort_dir: Direction in which results should be sorted. + (asc, desc) + :returns: A list of tuples of the specified columns. + """ + return _get_dbdriver_instance().list_capsules( + context, filters, limit, marker, sort_key, sort_dir) + + +@profiler.trace("db") +def create_capsule(context, values): + """Create a new capsule. + + :param context: The security context + :param values: A dict containing several items used to identify + and track the container, and several dicts which are + passed into the Drivers when managing this container. + For example: + :: + { + 'uuid': uuidutils.generate_uuid(), + 'restart_policy': 'always', + 'project_id': '***' + } + :returns: A capsule. + """ + return _get_dbdriver_instance().create_capsule(context, values) + + +@profiler.trace("db") +def get_capsule_by_uuid(context, capsule_uuid): + """Return a container. + + :param context: The security context + :param capsule_uuid: The uuid of a capsule. + :returns: A capsule. + """ + return _get_dbdriver_instance().get_capsule_by_uuid( + context, capsule_uuid) + + +@profiler.trace("db") +def destroy_capsule(context, capsule_id): + """Destroy a container and all associated interfaces. + + :param context: Request context + :param capsule_id: The id or uuid of a capsule. + """ + return _get_dbdriver_instance().destroy_capsule(context, capsule_id) + + +@profiler.trace("db") +def update_capsule(context, capsule_id, values): + """Update properties of a container. + + :context: Request context + :param container_id: The id or uuid of a capsule. + :values: The properties to be updated + :returns: A capsule. + :raises: CapsuleNotFound + """ + return _get_dbdriver_instance().update_capsule( + context, capsule_id, values) diff --git a/zun/db/sqlalchemy/api.py b/zun/db/sqlalchemy/api.py index 8bcc2d0d3..61f96b5b4 100644 --- a/zun/db/sqlalchemy/api.py +++ b/zun/db/sqlalchemy/api.py @@ -744,3 +744,75 @@ class Connection(object): ref.update(values) return ref + + def list_capsules(self, context, filters=None, limit=None, + marker=None, sort_key=None, sort_dir=None): + query = model_query(models.Capsule) + query = self._add_tenant_filters(context, query) + query = self._add_capsules_filters(query, filters) + return _paginate_query(models.Capsule, limit, marker, + sort_key, sort_dir, query) + + def create_capsule(self, context, values): + # ensure defaults are present for new capsules + # here use the infra container uuid as the capsule uuid + if not values.get('uuid'): + values['uuid'] = uuidutils.generate_uuid() + capsule = models.Capsule() + capsule.update(values) + try: + capsule.save() + except db_exc.DBDuplicateEntry: + raise exception.CapsuleAlreadyExists(field='UUID', + value=values['uuid']) + return capsule + + def get_capsule_by_uuid(self, context, capsule_uuid): + query = model_query(models.Capsule) + query = self._add_tenant_filters(context, query) + query = query.filter_by(uuid=capsule_uuid) + try: + return query.one() + except NoResultFound: + raise exception.CapsuleNotFound(capsule=capsule_uuid) + + def destroy_capsule(self, context, capsule_id): + session = get_session() + with session.begin(): + query = model_query(models.Capsule, session=session) + query = add_identity_filter(query, capsule_id) + count = query.delete() + if count != 1: + raise exception.CapsuleNotFound(capsule_id) + + def update_capsule(self, context, capsule_id, values): + if 'uuid' in values: + msg = _("Cannot overwrite UUID for an existing Capsule.") + raise exception.InvalidParameterValue(err=msg) + + return self._do_update_capsule_id(capsule_id, values) + + def _do_update_capsule_id(self, capsule_id, values): + session = get_session() + with session.begin(): + query = model_query(models.Capsule, session=session) + query = add_identity_filter(query, capsule_id) + try: + ref = query.with_lockmode('update').one() + except NoResultFound: + raise exception.CapsuleNotFound(capsule=capsule_id) + + ref.update(values) + return ref + + def _add_capsules_filters(self, query, filters): + if filters is None: + filters = {} + + # filter_names = ['uuid', 'project_id', 'user_id', 'containers'] + filter_names = ['uuid', 'project_id', 'user_id'] + for name in filter_names: + if name in filters: + query = query.filter_by(**{name: filters[name]}) + + return query