
This patch enables Consistency Groups support in Cinder. It will be implemented for snapshots for CGs in phase 1. Design ------------------------------------------------ The workflow is as follows: 1) Create a CG, specifying all volume types that can be supported by this CG. The scheduler chooses a backend that supports all specified volume types. The CG will be empty when it is first created. Backend needs to report consistencygroup_support = True. Volume type can have the following in extra specs: {'capabilities:consistencygroup_support': '<is> True'}. If consistencygroup_support is not in volume type extra specs, it will be added to filter_properties by the scheduler to make sure that the scheduler will select the backend which reports consistency group support capability. Create CG CLI: cinder consisgroup-create --volume-type type1,type2 mycg1 This will add a CG entry in the new consistencygroups table. 2) After the CG is created, create a new volume and add to the CG. Repeat until all volumes are created for the CG. Create volume CLI (with CG): cinder create --volume-type type1 --consisgroup-id <CG uuid> 10 This will add a consistencygroup_id foreign key in the new volume entry in the db. 3) Create a snapshot of the CG (cgsnapshot). Create cgsnapshot CLI: cinder cgsnapshot-create <CG uuid> This will add a cgsnapshot entry in the new cgsnapshots table, create snapshot for each volume in the CG, and add a cgsnapshot_id foreign key in each newly created snapshot entry in the db. DocImpact Implements: blueprint consistency-groups Change-Id: Ic105698aaad86ee30ef57ecf5107c224fdadf724
897 lines
29 KiB
Python
897 lines
29 KiB
Python
# 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 cinder.db namespace. Call these
|
|
functions from cinder.db namespace, not the cinder.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/cinder/cinder.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 concurrency as db_concurrency
|
|
from oslo.db import options as db_options
|
|
|
|
|
|
db_opts = [
|
|
# TODO(rpodolyaka): this option is deprecated but still passed to
|
|
# LazyPluggable class which doesn't support retrieving
|
|
# of options put into groups. Nova's version of this
|
|
# class supports this. Perhaps, we should put it to Oslo
|
|
# and then reuse here.
|
|
cfg.StrOpt('db_backend',
|
|
default='sqlalchemy',
|
|
help='The backend to use for db'),
|
|
cfg.BoolOpt('enable_new_services',
|
|
default=True,
|
|
help='Services to be added to the available pool on create'),
|
|
cfg.StrOpt('volume_name_template',
|
|
default='volume-%s',
|
|
help='Template string to be used to generate volume names'),
|
|
cfg.StrOpt('snapshot_name_template',
|
|
default='snapshot-%s',
|
|
help='Template string to be used to generate snapshot names'),
|
|
cfg.StrOpt('backup_name_template',
|
|
default='backup-%s',
|
|
help='Template string to be used to generate backup names'), ]
|
|
|
|
|
|
CONF = cfg.CONF
|
|
CONF.register_opts(db_opts)
|
|
db_options.set_defaults(CONF)
|
|
CONF.set_default('sqlite_db', 'cinder.sqlite', group='database')
|
|
|
|
_BACKEND_MAPPING = {'sqlalchemy': 'cinder.db.sqlalchemy.api'}
|
|
|
|
|
|
IMPL = db_concurrency.TpoolDbapiWrapper(CONF, _BACKEND_MAPPING)
|
|
|
|
|
|
###################
|
|
|
|
|
|
def service_destroy(context, service_id):
|
|
"""Destroy the service or raise if it does not exist."""
|
|
return IMPL.service_destroy(context, service_id)
|
|
|
|
|
|
def service_get(context, service_id):
|
|
"""Get a service or raise if it does not exist."""
|
|
return IMPL.service_get(context, service_id)
|
|
|
|
|
|
def service_get_by_host_and_topic(context, host, topic):
|
|
"""Get a service by host it's on and topic it listens to."""
|
|
return IMPL.service_get_by_host_and_topic(context, host, topic)
|
|
|
|
|
|
def service_get_all(context, disabled=None):
|
|
"""Get all services."""
|
|
return IMPL.service_get_all(context, disabled)
|
|
|
|
|
|
def service_get_all_by_topic(context, topic, disabled=None):
|
|
"""Get all services for a given topic."""
|
|
return IMPL.service_get_all_by_topic(context, topic, disabled=disabled)
|
|
|
|
|
|
def service_get_all_by_host(context, host):
|
|
"""Get all services for a given host."""
|
|
return IMPL.service_get_all_by_host(context, host)
|
|
|
|
|
|
def service_get_all_volume_sorted(context):
|
|
"""Get all volume services sorted by volume count.
|
|
|
|
:returns: a list of (Service, volume_count) tuples.
|
|
|
|
"""
|
|
return IMPL.service_get_all_volume_sorted(context)
|
|
|
|
|
|
def service_get_by_args(context, host, binary):
|
|
"""Get the state of an service by node name and binary."""
|
|
return IMPL.service_get_by_args(context, host, binary)
|
|
|
|
|
|
def service_create(context, values):
|
|
"""Create a service from the values dictionary."""
|
|
return IMPL.service_create(context, values)
|
|
|
|
|
|
def service_update(context, service_id, values):
|
|
"""Set the given properties on an service and update it.
|
|
|
|
Raises NotFound if service does not exist.
|
|
|
|
"""
|
|
return IMPL.service_update(context, service_id, values)
|
|
|
|
|
|
###################
|
|
|
|
|
|
def iscsi_target_count_by_host(context, host):
|
|
"""Return count of export devices."""
|
|
return IMPL.iscsi_target_count_by_host(context, host)
|
|
|
|
|
|
def iscsi_target_create_safe(context, values):
|
|
"""Create an iscsi_target from the values dictionary.
|
|
|
|
The device is not returned. If the create violates the unique
|
|
constraints because the iscsi_target and host already exist,
|
|
no exception is raised.
|
|
|
|
"""
|
|
return IMPL.iscsi_target_create_safe(context, values)
|
|
|
|
|
|
###############
|
|
|
|
def volume_allocate_iscsi_target(context, volume_id, host):
|
|
"""Atomically allocate a free iscsi_target from the pool."""
|
|
return IMPL.volume_allocate_iscsi_target(context, volume_id, host)
|
|
|
|
|
|
def volume_attached(context, volume_id, instance_id, host_name, mountpoint):
|
|
"""Ensure that a volume is set as attached."""
|
|
return IMPL.volume_attached(context, volume_id, instance_id, host_name,
|
|
mountpoint)
|
|
|
|
|
|
def volume_create(context, values):
|
|
"""Create a volume from the values dictionary."""
|
|
return IMPL.volume_create(context, values)
|
|
|
|
|
|
def volume_data_get_for_host(context, host, count_only=False):
|
|
"""Get (volume_count, gigabytes) for project."""
|
|
return IMPL.volume_data_get_for_host(context,
|
|
host,
|
|
count_only)
|
|
|
|
|
|
def volume_data_get_for_project(context, project_id):
|
|
"""Get (volume_count, gigabytes) for project."""
|
|
return IMPL.volume_data_get_for_project(context, project_id)
|
|
|
|
|
|
def finish_volume_migration(context, src_vol_id, dest_vol_id):
|
|
"""Perform database updates upon completion of volume migration."""
|
|
return IMPL.finish_volume_migration(context, src_vol_id, dest_vol_id)
|
|
|
|
|
|
def volume_destroy(context, volume_id):
|
|
"""Destroy the volume or raise if it does not exist."""
|
|
return IMPL.volume_destroy(context, volume_id)
|
|
|
|
|
|
def volume_detached(context, volume_id):
|
|
"""Ensure that a volume is set as detached."""
|
|
return IMPL.volume_detached(context, volume_id)
|
|
|
|
|
|
def volume_get(context, volume_id):
|
|
"""Get a volume or raise if it does not exist."""
|
|
return IMPL.volume_get(context, volume_id)
|
|
|
|
|
|
def volume_get_all(context, marker, limit, sort_key, sort_dir,
|
|
filters=None):
|
|
"""Get all volumes."""
|
|
return IMPL.volume_get_all(context, marker, limit, sort_key, sort_dir,
|
|
filters=filters)
|
|
|
|
|
|
def volume_get_all_by_host(context, host):
|
|
"""Get all volumes belonging to a host."""
|
|
return IMPL.volume_get_all_by_host(context, host)
|
|
|
|
|
|
def volume_get_all_by_group(context, group_id):
|
|
"""Get all volumes belonging to a consistency group."""
|
|
return IMPL.volume_get_all_by_group(context, group_id)
|
|
|
|
|
|
def volume_get_all_by_project(context, project_id, marker, limit, sort_key,
|
|
sort_dir, filters=None):
|
|
"""Get all volumes belonging to a project."""
|
|
return IMPL.volume_get_all_by_project(context, project_id, marker, limit,
|
|
sort_key, sort_dir, filters=filters)
|
|
|
|
|
|
def volume_get_iscsi_target_num(context, volume_id):
|
|
"""Get the target num (tid) allocated to the volume."""
|
|
return IMPL.volume_get_iscsi_target_num(context, volume_id)
|
|
|
|
|
|
def volume_update(context, volume_id, values):
|
|
"""Set the given properties on an volume and update it.
|
|
|
|
Raises NotFound if volume does not exist.
|
|
|
|
"""
|
|
return IMPL.volume_update(context, volume_id, values)
|
|
|
|
|
|
####################
|
|
|
|
|
|
def snapshot_create(context, values):
|
|
"""Create a snapshot from the values dictionary."""
|
|
return IMPL.snapshot_create(context, values)
|
|
|
|
|
|
def snapshot_destroy(context, snapshot_id):
|
|
"""Destroy the snapshot or raise if it does not exist."""
|
|
return IMPL.snapshot_destroy(context, snapshot_id)
|
|
|
|
|
|
def snapshot_get(context, snapshot_id):
|
|
"""Get a snapshot or raise if it does not exist."""
|
|
return IMPL.snapshot_get(context, snapshot_id)
|
|
|
|
|
|
def snapshot_get_all(context):
|
|
"""Get all snapshots."""
|
|
return IMPL.snapshot_get_all(context)
|
|
|
|
|
|
def snapshot_get_all_by_project(context, project_id):
|
|
"""Get all snapshots belonging to a project."""
|
|
return IMPL.snapshot_get_all_by_project(context, project_id)
|
|
|
|
|
|
def snapshot_get_all_for_cgsnapshot(context, project_id):
|
|
"""Get all snapshots belonging to a cgsnapshot."""
|
|
return IMPL.snapshot_get_all_for_cgsnapshot(context, project_id)
|
|
|
|
|
|
def snapshot_get_all_for_volume(context, volume_id):
|
|
"""Get all snapshots for a volume."""
|
|
return IMPL.snapshot_get_all_for_volume(context, volume_id)
|
|
|
|
|
|
def snapshot_update(context, snapshot_id, values):
|
|
"""Set the given properties on an snapshot and update it.
|
|
|
|
Raises NotFound if snapshot does not exist.
|
|
|
|
"""
|
|
return IMPL.snapshot_update(context, snapshot_id, values)
|
|
|
|
|
|
def snapshot_data_get_for_project(context, project_id, volume_type_id=None):
|
|
"""Get count and gigabytes used for snapshots for specified project."""
|
|
return IMPL.snapshot_data_get_for_project(context,
|
|
project_id,
|
|
volume_type_id)
|
|
|
|
|
|
def snapshot_get_active_by_window(context, begin, end=None, project_id=None):
|
|
"""Get all the snapshots inside the window.
|
|
|
|
Specifying a project_id will filter for a certain project.
|
|
"""
|
|
return IMPL.snapshot_get_active_by_window(context, begin, end, project_id)
|
|
|
|
|
|
####################
|
|
|
|
|
|
def snapshot_metadata_get(context, snapshot_id):
|
|
"""Get all metadata for a snapshot."""
|
|
return IMPL.snapshot_metadata_get(context, snapshot_id)
|
|
|
|
|
|
def snapshot_metadata_delete(context, snapshot_id, key):
|
|
"""Delete the given metadata item."""
|
|
return IMPL.snapshot_metadata_delete(context, snapshot_id, key)
|
|
|
|
|
|
def snapshot_metadata_update(context, snapshot_id, metadata, delete):
|
|
"""Update metadata if it exists, otherwise create it."""
|
|
return IMPL.snapshot_metadata_update(context, snapshot_id,
|
|
metadata, delete)
|
|
|
|
|
|
####################
|
|
|
|
|
|
def volume_metadata_get(context, volume_id):
|
|
"""Get all metadata for a volume."""
|
|
return IMPL.volume_metadata_get(context, volume_id)
|
|
|
|
|
|
def volume_metadata_delete(context, volume_id, key):
|
|
"""Delete the given metadata item."""
|
|
return IMPL.volume_metadata_delete(context, volume_id, key)
|
|
|
|
|
|
def volume_metadata_update(context, volume_id, metadata, delete):
|
|
"""Update metadata if it exists, otherwise create it."""
|
|
return IMPL.volume_metadata_update(context, volume_id, metadata, delete)
|
|
|
|
|
|
##################
|
|
|
|
|
|
def volume_admin_metadata_get(context, volume_id):
|
|
"""Get all administration metadata for a volume."""
|
|
return IMPL.volume_admin_metadata_get(context, volume_id)
|
|
|
|
|
|
def volume_admin_metadata_delete(context, volume_id, key):
|
|
"""Delete the given metadata item."""
|
|
return IMPL.volume_admin_metadata_delete(context, volume_id, key)
|
|
|
|
|
|
def volume_admin_metadata_update(context, volume_id, metadata, delete):
|
|
"""Update metadata if it exists, otherwise create it."""
|
|
return IMPL.volume_admin_metadata_update(context, volume_id, metadata,
|
|
delete)
|
|
|
|
|
|
##################
|
|
|
|
|
|
def volume_type_create(context, values):
|
|
"""Create a new volume type."""
|
|
return IMPL.volume_type_create(context, values)
|
|
|
|
|
|
def volume_type_get_all(context, inactive=False):
|
|
"""Get all volume types."""
|
|
return IMPL.volume_type_get_all(context, inactive)
|
|
|
|
|
|
def volume_type_get(context, id, inactive=False):
|
|
"""Get volume type by id."""
|
|
return IMPL.volume_type_get(context, id, inactive)
|
|
|
|
|
|
def volume_type_get_by_name(context, name):
|
|
"""Get volume type by name."""
|
|
return IMPL.volume_type_get_by_name(context, name)
|
|
|
|
|
|
def volume_types_get_by_name_or_id(context, volume_type_list):
|
|
"""Get volume types by name or id."""
|
|
return IMPL.volume_types_get_by_name_or_id(context, volume_type_list)
|
|
|
|
|
|
def volume_type_qos_associations_get(context, qos_specs_id, inactive=False):
|
|
"""Get volume types that are associated with specific qos specs."""
|
|
return IMPL.volume_type_qos_associations_get(context,
|
|
qos_specs_id,
|
|
inactive)
|
|
|
|
|
|
def volume_type_qos_associate(context, type_id, qos_specs_id):
|
|
"""Associate a volume type with specific qos specs."""
|
|
return IMPL.volume_type_qos_associate(context, type_id, qos_specs_id)
|
|
|
|
|
|
def volume_type_qos_disassociate(context, qos_specs_id, type_id):
|
|
"""Disassociate a volume type from specific qos specs."""
|
|
return IMPL.volume_type_qos_disassociate(context, qos_specs_id, type_id)
|
|
|
|
|
|
def volume_type_qos_disassociate_all(context, qos_specs_id):
|
|
"""Disassociate all volume types from specific qos specs."""
|
|
return IMPL.volume_type_qos_disassociate_all(context,
|
|
qos_specs_id)
|
|
|
|
|
|
def volume_type_qos_specs_get(context, type_id):
|
|
"""Get all qos specs for given volume type."""
|
|
return IMPL.volume_type_qos_specs_get(context, type_id)
|
|
|
|
|
|
def volume_type_destroy(context, id):
|
|
"""Delete a volume type."""
|
|
return IMPL.volume_type_destroy(context, id)
|
|
|
|
|
|
def volume_get_active_by_window(context, begin, end=None, project_id=None):
|
|
"""Get all the volumes inside the window.
|
|
|
|
Specifying a project_id will filter for a certain project.
|
|
"""
|
|
return IMPL.volume_get_active_by_window(context, begin, end, project_id)
|
|
|
|
|
|
####################
|
|
|
|
|
|
def volume_type_extra_specs_get(context, volume_type_id):
|
|
"""Get all extra specs for a volume type."""
|
|
return IMPL.volume_type_extra_specs_get(context, volume_type_id)
|
|
|
|
|
|
def volume_type_extra_specs_delete(context, volume_type_id, key):
|
|
"""Delete the given extra specs item."""
|
|
return IMPL.volume_type_extra_specs_delete(context, volume_type_id, key)
|
|
|
|
|
|
def volume_type_extra_specs_update_or_create(context,
|
|
volume_type_id,
|
|
extra_specs):
|
|
"""Create or update volume type extra specs. This adds or modifies the
|
|
key/value pairs specified in the extra specs dict argument
|
|
"""
|
|
return IMPL.volume_type_extra_specs_update_or_create(context,
|
|
volume_type_id,
|
|
extra_specs)
|
|
|
|
|
|
###################
|
|
|
|
|
|
def volume_type_encryption_get(context, volume_type_id, session=None):
|
|
return IMPL.volume_type_encryption_get(context, volume_type_id, session)
|
|
|
|
|
|
def volume_type_encryption_delete(context, volume_type_id):
|
|
return IMPL.volume_type_encryption_delete(context, volume_type_id)
|
|
|
|
|
|
def volume_type_encryption_create(context, volume_type_id, encryption_specs):
|
|
return IMPL.volume_type_encryption_create(context, volume_type_id,
|
|
encryption_specs)
|
|
|
|
|
|
def volume_type_encryption_update(context, volume_type_id, encryption_specs):
|
|
return IMPL.volume_type_encryption_update(context, volume_type_id,
|
|
encryption_specs)
|
|
|
|
|
|
def volume_type_encryption_volume_get(context, volume_type_id, session=None):
|
|
return IMPL.volume_type_encryption_volume_get(context, volume_type_id,
|
|
session)
|
|
|
|
|
|
def volume_encryption_metadata_get(context, volume_id, session=None):
|
|
return IMPL.volume_encryption_metadata_get(context, volume_id, session)
|
|
|
|
|
|
###################
|
|
|
|
|
|
def qos_specs_create(context, values):
|
|
"""Create a qos_specs."""
|
|
return IMPL.qos_specs_create(context, values)
|
|
|
|
|
|
def qos_specs_get(context, qos_specs_id):
|
|
"""Get all specification for a given qos_specs."""
|
|
return IMPL.qos_specs_get(context, qos_specs_id)
|
|
|
|
|
|
def qos_specs_get_all(context, inactive=False, filters=None):
|
|
"""Get all qos_specs."""
|
|
return IMPL.qos_specs_get_all(context, inactive, filters)
|
|
|
|
|
|
def qos_specs_get_by_name(context, name):
|
|
"""Get all specification for a given qos_specs."""
|
|
return IMPL.qos_specs_get_by_name(context, name)
|
|
|
|
|
|
def qos_specs_associations_get(context, qos_specs_id):
|
|
"""Get all associated volume types for a given qos_specs."""
|
|
return IMPL.qos_specs_associations_get(context, qos_specs_id)
|
|
|
|
|
|
def qos_specs_associate(context, qos_specs_id, type_id):
|
|
"""Associate qos_specs from volume type."""
|
|
return IMPL.qos_specs_associate(context, qos_specs_id, type_id)
|
|
|
|
|
|
def qos_specs_disassociate(context, qos_specs_id, type_id):
|
|
"""Disassociate qos_specs from volume type."""
|
|
return IMPL.qos_specs_disassociate(context, qos_specs_id, type_id)
|
|
|
|
|
|
def qos_specs_disassociate_all(context, qos_specs_id):
|
|
"""Disassociate qos_specs from all entities."""
|
|
return IMPL.qos_specs_disassociate_all(context, qos_specs_id)
|
|
|
|
|
|
def qos_specs_delete(context, qos_specs_id):
|
|
"""Delete the qos_specs."""
|
|
return IMPL.qos_specs_delete(context, qos_specs_id)
|
|
|
|
|
|
def qos_specs_item_delete(context, qos_specs_id, key):
|
|
"""Delete specified key in the qos_specs."""
|
|
return IMPL.qos_specs_item_delete(context, qos_specs_id, key)
|
|
|
|
|
|
def qos_specs_update(context, qos_specs_id, specs):
|
|
"""Update qos specs.
|
|
|
|
This adds or modifies the key/value pairs specified in the
|
|
specs dict argument for a given qos_specs.
|
|
"""
|
|
return IMPL.qos_specs_update(context, qos_specs_id, specs)
|
|
|
|
|
|
###################
|
|
|
|
|
|
def volume_glance_metadata_create(context, volume_id, key, value):
|
|
"""Update the Glance metadata for the specified volume."""
|
|
return IMPL.volume_glance_metadata_create(context,
|
|
volume_id,
|
|
key,
|
|
value)
|
|
|
|
|
|
def volume_glance_metadata_get_all(context):
|
|
"""Return the glance metadata for all volumes."""
|
|
return IMPL.volume_glance_metadata_get_all(context)
|
|
|
|
|
|
def volume_glance_metadata_get(context, volume_id):
|
|
"""Return the glance metadata for a volume."""
|
|
return IMPL.volume_glance_metadata_get(context, volume_id)
|
|
|
|
|
|
def volume_snapshot_glance_metadata_get(context, snapshot_id):
|
|
"""Return the Glance metadata for the specified snapshot."""
|
|
return IMPL.volume_snapshot_glance_metadata_get(context, snapshot_id)
|
|
|
|
|
|
def volume_glance_metadata_copy_to_snapshot(context, snapshot_id, volume_id):
|
|
"""Update the Glance metadata for a snapshot.
|
|
|
|
This will copy all of the key:value pairs from the originating volume,
|
|
to ensure that a volume created from the snapshot will retain the
|
|
original metadata.
|
|
"""
|
|
return IMPL.volume_glance_metadata_copy_to_snapshot(context, snapshot_id,
|
|
volume_id)
|
|
|
|
|
|
def volume_glance_metadata_copy_to_volume(context, volume_id, snapshot_id):
|
|
"""Update the Glance metadata from a volume (created from a snapshot).
|
|
|
|
This will copy all of the key:value pairs from the originating snapshot,
|
|
to ensure that the Glance metadata from the original volume is retained.
|
|
"""
|
|
return IMPL.volume_glance_metadata_copy_to_volume(context, volume_id,
|
|
snapshot_id)
|
|
|
|
|
|
def volume_glance_metadata_delete_by_volume(context, volume_id):
|
|
"""Delete the glance metadata for a volume."""
|
|
return IMPL.volume_glance_metadata_delete_by_volume(context, volume_id)
|
|
|
|
|
|
def volume_glance_metadata_delete_by_snapshot(context, snapshot_id):
|
|
"""Delete the glance metadata for a snapshot."""
|
|
return IMPL.volume_glance_metadata_delete_by_snapshot(context, snapshot_id)
|
|
|
|
|
|
def volume_glance_metadata_copy_from_volume_to_volume(context,
|
|
src_volume_id,
|
|
volume_id):
|
|
"""Update the Glance metadata for a volume by copying all of the key:value
|
|
pairs from the originating volume.
|
|
|
|
This is so that a volume created from the volume (clone) will retain the
|
|
original metadata.
|
|
"""
|
|
return IMPL.volume_glance_metadata_copy_from_volume_to_volume(
|
|
context,
|
|
src_volume_id,
|
|
volume_id)
|
|
|
|
|
|
###################
|
|
|
|
|
|
def quota_create(context, project_id, resource, limit):
|
|
"""Create a quota for the given project and resource."""
|
|
return IMPL.quota_create(context, project_id, resource, limit)
|
|
|
|
|
|
def quota_get(context, project_id, resource):
|
|
"""Retrieve a quota or raise if it does not exist."""
|
|
return IMPL.quota_get(context, project_id, resource)
|
|
|
|
|
|
def quota_get_all_by_project(context, project_id):
|
|
"""Retrieve all quotas associated with a given project."""
|
|
return IMPL.quota_get_all_by_project(context, project_id)
|
|
|
|
|
|
def quota_update(context, project_id, resource, limit):
|
|
"""Update a quota or raise if it does not exist."""
|
|
return IMPL.quota_update(context, project_id, resource, limit)
|
|
|
|
|
|
def quota_destroy(context, project_id, resource):
|
|
"""Destroy the quota or raise if it does not exist."""
|
|
return IMPL.quota_destroy(context, project_id, resource)
|
|
|
|
|
|
###################
|
|
|
|
|
|
def quota_class_create(context, class_name, resource, limit):
|
|
"""Create a quota class for the given name and resource."""
|
|
return IMPL.quota_class_create(context, class_name, resource, limit)
|
|
|
|
|
|
def quota_class_get(context, class_name, resource):
|
|
"""Retrieve a quota class or raise if it does not exist."""
|
|
return IMPL.quota_class_get(context, class_name, resource)
|
|
|
|
|
|
def quota_class_get_default(context):
|
|
"""Retrieve all default quotas."""
|
|
return IMPL.quota_class_get_default(context)
|
|
|
|
|
|
def quota_class_get_all_by_name(context, class_name):
|
|
"""Retrieve all quotas associated with a given quota class."""
|
|
return IMPL.quota_class_get_all_by_name(context, class_name)
|
|
|
|
|
|
def quota_class_update(context, class_name, resource, limit):
|
|
"""Update a quota class or raise if it does not exist."""
|
|
return IMPL.quota_class_update(context, class_name, resource, limit)
|
|
|
|
|
|
def quota_class_destroy(context, class_name, resource):
|
|
"""Destroy the quota class or raise if it does not exist."""
|
|
return IMPL.quota_class_destroy(context, class_name, resource)
|
|
|
|
|
|
def quota_class_destroy_all_by_name(context, class_name):
|
|
"""Destroy all quotas associated with a given quota class."""
|
|
return IMPL.quota_class_destroy_all_by_name(context, class_name)
|
|
|
|
|
|
###################
|
|
|
|
|
|
def quota_usage_get(context, project_id, resource):
|
|
"""Retrieve a quota usage or raise if it does not exist."""
|
|
return IMPL.quota_usage_get(context, project_id, resource)
|
|
|
|
|
|
def quota_usage_get_all_by_project(context, project_id):
|
|
"""Retrieve all usage associated with a given resource."""
|
|
return IMPL.quota_usage_get_all_by_project(context, project_id)
|
|
|
|
|
|
###################
|
|
|
|
|
|
def quota_reserve(context, resources, quotas, deltas, expire,
|
|
until_refresh, max_age, project_id=None):
|
|
"""Check quotas and create appropriate reservations."""
|
|
return IMPL.quota_reserve(context, resources, quotas, deltas, expire,
|
|
until_refresh, max_age, project_id=project_id)
|
|
|
|
|
|
def reservation_commit(context, reservations, project_id=None):
|
|
"""Commit quota reservations."""
|
|
return IMPL.reservation_commit(context, reservations,
|
|
project_id=project_id)
|
|
|
|
|
|
def reservation_rollback(context, reservations, project_id=None):
|
|
"""Roll back quota reservations."""
|
|
return IMPL.reservation_rollback(context, reservations,
|
|
project_id=project_id)
|
|
|
|
|
|
def quota_destroy_all_by_project(context, project_id):
|
|
"""Destroy all quotas associated with a given project."""
|
|
return IMPL.quota_destroy_all_by_project(context, project_id)
|
|
|
|
|
|
def reservation_expire(context):
|
|
"""Roll back any expired reservations."""
|
|
return IMPL.reservation_expire(context)
|
|
|
|
|
|
###################
|
|
|
|
|
|
def backup_get(context, backup_id):
|
|
"""Get a backup or raise if it does not exist."""
|
|
return IMPL.backup_get(context, backup_id)
|
|
|
|
|
|
def backup_get_all(context, filters=None):
|
|
"""Get all backups."""
|
|
return IMPL.backup_get_all(context, filters=filters)
|
|
|
|
|
|
def backup_get_all_by_host(context, host):
|
|
"""Get all backups belonging to a host."""
|
|
return IMPL.backup_get_all_by_host(context, host)
|
|
|
|
|
|
def backup_create(context, values):
|
|
"""Create a backup from the values dictionary."""
|
|
return IMPL.backup_create(context, values)
|
|
|
|
|
|
def backup_get_all_by_project(context, project_id, filters=None):
|
|
"""Get all backups belonging to a project."""
|
|
return IMPL.backup_get_all_by_project(context, project_id,
|
|
filters=filters)
|
|
|
|
|
|
def backup_update(context, backup_id, values):
|
|
"""Set the given properties on a backup and update it.
|
|
|
|
Raises NotFound if backup does not exist.
|
|
"""
|
|
return IMPL.backup_update(context, backup_id, values)
|
|
|
|
|
|
def backup_destroy(context, backup_id):
|
|
"""Destroy the backup or raise if it does not exist."""
|
|
return IMPL.backup_destroy(context, backup_id)
|
|
|
|
|
|
###################
|
|
|
|
|
|
def transfer_get(context, transfer_id):
|
|
"""Get a volume transfer record or raise if it does not exist."""
|
|
return IMPL.transfer_get(context, transfer_id)
|
|
|
|
|
|
def transfer_get_all(context):
|
|
"""Get all volume transfer records."""
|
|
return IMPL.transfer_get_all(context)
|
|
|
|
|
|
def transfer_get_all_by_project(context, project_id):
|
|
"""Get all volume transfer records for specified project."""
|
|
return IMPL.transfer_get_all_by_project(context, project_id)
|
|
|
|
|
|
def transfer_create(context, values):
|
|
"""Create an entry in the transfers table."""
|
|
return IMPL.transfer_create(context, values)
|
|
|
|
|
|
def transfer_destroy(context, transfer_id):
|
|
"""Destroy a record in the volume transfer table."""
|
|
return IMPL.transfer_destroy(context, transfer_id)
|
|
|
|
|
|
def transfer_accept(context, transfer_id, user_id, project_id):
|
|
"""Accept a volume transfer."""
|
|
return IMPL.transfer_accept(context, transfer_id, user_id, project_id)
|
|
|
|
|
|
###################
|
|
|
|
|
|
def consistencygroup_get(context, consistencygroup_id):
|
|
"""Get a consistencygroup or raise if it does not exist."""
|
|
return IMPL.consistencygroup_get(context, consistencygroup_id)
|
|
|
|
|
|
def consistencygroup_get_all(context):
|
|
"""Get all consistencygroups."""
|
|
return IMPL.consistencygroup_get_all(context)
|
|
|
|
|
|
def consistencygroup_get_all_by_host(context, host):
|
|
"""Get all consistencygroups belonging to a host."""
|
|
return IMPL.consistencygroup_get_all_by_host(context, host)
|
|
|
|
|
|
def consistencygroup_create(context, values):
|
|
"""Create a consistencygroup from the values dictionary."""
|
|
return IMPL.consistencygroup_create(context, values)
|
|
|
|
|
|
def consistencygroup_get_all_by_project(context, project_id):
|
|
"""Get all consistencygroups belonging to a project."""
|
|
return IMPL.consistencygroup_get_all_by_project(context, project_id)
|
|
|
|
|
|
def consistencygroup_update(context, consistencygroup_id, values):
|
|
"""Set the given properties on a consistencygroup and update it.
|
|
|
|
Raises NotFound if consistencygroup does not exist.
|
|
"""
|
|
return IMPL.consistencygroup_update(context, consistencygroup_id, values)
|
|
|
|
|
|
def consistencygroup_destroy(context, consistencygroup_id):
|
|
"""Destroy the consistencygroup or raise if it does not exist."""
|
|
return IMPL.consistencygroup_destroy(context, consistencygroup_id)
|
|
|
|
|
|
###################
|
|
|
|
|
|
def cgsnapshot_get(context, cgsnapshot_id):
|
|
"""Get a cgsnapshot or raise if it does not exist."""
|
|
return IMPL.cgsnapshot_get(context, cgsnapshot_id)
|
|
|
|
|
|
def cgsnapshot_get_all(context):
|
|
"""Get all cgsnapshots."""
|
|
return IMPL.cgsnapshot_get_all(context)
|
|
|
|
|
|
def cgsnapshot_get_all_by_host(context, host):
|
|
"""Get all cgsnapshots belonging to a host."""
|
|
return IMPL.cgsnapshot_get_all_by_host(context, host)
|
|
|
|
|
|
def cgsnapshot_create(context, values):
|
|
"""Create a cgsnapshot from the values dictionary."""
|
|
return IMPL.cgsnapshot_create(context, values)
|
|
|
|
|
|
def cgsnapshot_get_all_by_group(context, group_id):
|
|
"""Get all cgsnapshots belonging to a consistency group."""
|
|
return IMPL.cgsnapshot_get_all_by_group(context, group_id)
|
|
|
|
|
|
def cgsnapshot_get_all_by_project(context, project_id):
|
|
"""Get all cgsnapshots belonging to a project."""
|
|
return IMPL.cgsnapshot_get_all_by_project(context, project_id)
|
|
|
|
|
|
def cgsnapshot_update(context, cgsnapshot_id, values):
|
|
"""Set the given properties on a cgsnapshot and update it.
|
|
|
|
Raises NotFound if cgsnapshot does not exist.
|
|
"""
|
|
return IMPL.cgsnapshot_update(context, cgsnapshot_id, values)
|
|
|
|
|
|
def cgsnapshot_destroy(context, cgsnapshot_id):
|
|
"""Destroy the cgsnapshot or raise if it does not exist."""
|
|
return IMPL.cgsnapshot_destroy(context, cgsnapshot_id)
|