
Placement uses alembic to manage the DB version for schema changes. However, changes with data manupulation should be separated from the schema changes since the table can be locked and in the worst case it breaks the service for backward incompatible changes. We could handle them as a task that is done in a service down time. However, to minimize the down time, it is better to have the concepts of online data migration which has been a traditional way to handle those data manipulation changes in nova. This patch adds online data migration command to placement to enable operators to manipulate DB data while the service is running: placement-manage db online_data_migrations [--max-count] where --max-count controls the maximum number of objects to migrate in a given call. If not specified, migration will occur in batches of 50 until fully complete. Change-Id: I9cef6829513d9a54d110426baf6bcc312554e3e7
57 lines
2.4 KiB
Python
57 lines
2.4 KiB
Python
# 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 oslo_context import context
|
|
from oslo_db.sqlalchemy import enginefacade
|
|
|
|
from placement import exception
|
|
from placement import policy
|
|
|
|
|
|
@enginefacade.transaction_context_provider
|
|
class RequestContext(context.RequestContext):
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
self.config = kwargs.pop('config', None)
|
|
super(RequestContext, self).__init__(*args, **kwargs)
|
|
|
|
def can(self, action, target=None, fatal=True):
|
|
"""Verifies that the given action is valid on the target in this
|
|
context.
|
|
|
|
:param action: string representing the action to be checked.
|
|
:param target: As much information about the object being operated on
|
|
as possible. The target argument should be a dict instance or an
|
|
instance of a class that fully supports the Mapping abstract base
|
|
class and deep copying. For object creation this should be a
|
|
dictionary representing the location of the object e.g.
|
|
``{'project_id': context.project_id}``. If None, then this default
|
|
target will be considered::
|
|
|
|
{'project_id': self.project_id, 'user_id': self.user_id}
|
|
:param fatal: if False, will return False when an
|
|
exception.PolicyNotAuthorized occurs.
|
|
:raises placement.exception.PolicyNotAuthorized:
|
|
if verification fails and fatal is True.
|
|
:return: returns a non-False value (not necessarily "True") if
|
|
authorized and False if not authorized and fatal is False.
|
|
"""
|
|
if target is None:
|
|
target = {'project_id': self.project_id,
|
|
'user_id': self.user_id}
|
|
try:
|
|
return policy.authorize(self, action, target)
|
|
except exception.PolicyNotAuthorized:
|
|
if fatal:
|
|
raise
|
|
return False
|