<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0"><channel><title>Cinder Specs</title><link>http://specs.openstack.org/openstack/cinder-specs</link><description /><language>en</language><copyright>2026, OpenStack Cinder Team</copyright><item><title>Standardize Image Encryption and Decryption</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/2026.1/LUKS-image-encryption.html</link><description>

&lt;p&gt;OpenStack already supports encrypted volumes and ephemeral storage to ensure
the confidentiality of block data. Even though it is already possible to store
encrypted images, there is only one service (Cinder) that utilizes this option,
but it is only indirectly usable by Nova (a user must create a volume from the
image first), and thus users do not have an intuitive way to create and upload
encrypted images. In addition, all metadata needed to detect and use encrypted
images is either not present or specifically scoped for Cinder right now. In
conclusion, support for encrypted images does exist to some extent but only in
a non-explicit and non-standardized way. To establish a consistent approach to
image encryption for all OpenStack services as well as users, several
adjustments need to be implemented in Glance, Cinder, and OSC.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;An image, when uploaded to Glance or created through Nova from an existing
server (VM), may contain sensitive information. The already provided signature
functionality only protects images against alteration. Images may be stored on
several hosts over long periods of time. First and foremost this includes the
image storage hosts of Glance itself. Furthermore it might also involve caches
on systems like compute hosts. In conclusion, the images are exposed to a
multitude of potential scenarios involving different hosts with different
access patterns and attack surfaces. The OpenStack components involved in those
scenarios do not protect the confidentiality of image data.&lt;/p&gt;
&lt;p&gt;Using encrypted storage backends for volume and compute hosts in conjunction
with direct data transfer from/to encrypted images can enable workflows that
never expose an image’s data on a host’s filesystem. Storage of encryption keys
on a dedicated key manager host ensures isolation and access control for the
keys as well.&lt;/p&gt;
&lt;p&gt;As stated in the introduction above, some disk image encryption implementations
for ephemeral disks in Nova and volumes in Cinder already touch on this topic
but not always in a standardized and interoperable way. For example, the way of
handling image metadata and encryption keys can differ. Furthermore, users
are not easily able to make use of these implementations when supplying their
own images in a way that encryption can work the same across services.&lt;/p&gt;
&lt;p&gt;That’s why we propose the introduction of a streamlined encrypted image format
along with well-defined metadata specifications which will be supported across
OpenStack services for the existing encryption implementations and increase
interoperability as well as usability for users. Additionally we require, that
encrypted images will always result in encrypted volumes to avoid decryption.&lt;/p&gt;
&lt;section id="use-cases"&gt;
&lt;h3&gt;Use Cases&lt;/h3&gt;
&lt;p&gt;1. A user wants to create a new volume based on an encrypted image. The
corresponding volume host has to be enabled to detect that the image is
encrypted.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ol class="loweralpha simple"&gt;
&lt;li&gt;&lt;p&gt;If an encrypted image is the base for a new volume the used volume type
should always have an encryption type. If the given volume type or
default volume type does not have an encryption type the operation
should result in an ERROR.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There are two possible types of encrypted images: qcow2 images with
encryption (qcow2+LUKS) and raw LUKS images. Cinder can already handle
raw LUKS-encrypted images. Encrypted qcow2+LUKS images may need to be
converted to raw LUKS before transforming them into volumes.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;2. Whenever an encrypted image is converted to an encrypted volume the secret
should be copied to give Cinder full control over the lifecycle of the secret.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ol class="loweralpha simple"&gt;
&lt;li&gt;&lt;p&gt;There is only one secret per image and it can be either a key or a
passphrase. The secret type classification in the Key Manager will
determine the key handling (“symmetric” vs “passphrase”). In case of
“passphrase”, the secret is passed directly as the passphrase to the
encryption layer. In any othercase, it is interpreted as binary and
converted to a suitable string representation before being passed to the
encryption. Currently, Cinder is only able to handle “symmetric” keys,
i.e., the latter binary case. Support for “passphrase” (like used in
Nova) has to be added.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;3. A user wants to create an image from a volume with an encrypted volume type
The target image will reuse the LUKS encryption and key. This use case is
already implemented as part of the default behavior of Cinder.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ol class="loweralpha simple"&gt;
&lt;li&gt;&lt;p&gt;Creating an encrypted image from an unencrypted volume will not be part
of this spec, but may be implemented later on.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Creating an unencrypted image from an encrypted volume is not possible
right now. The volume encryption is transparently also used for the
image. This behavior will stay in place to optimize resource usage and
avoid costly conversion of the whole volume data on volume hosts.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;In Glance we propose the following additional metadata properties that should be
carried by encrypted images:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;‘os_encrypt_format’ - the specific mechanism used, e.g. ‘LUKSv1’&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;‘os_encrypt_key_id’ - reference to key in the key manager&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;‘os_encrypt_key_deletion_policy’ - on image deletion indicates whether the
key should be deleted too&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;‘os_decrypt_size’ - size after payload decryption&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We propose to align the encryption with Nova and Cinder and use LUKS, which
will be allowed in combination with qcow2 and raw images. We use these two
variations for the following reasons:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Nova might be able to directly use qcow2+LUKS encrypted images when creating
a server. The qcow2 format is already familiar to Nova and used by it to
directly boot instances from. Currently, support for encrypted ephemeral
storage is not yet implemented in Nova, so qcow2+LUKS cannot be used by it
yet but since the LUKS encryption is a native feature of qcow2, this
will provide a good starting point for a lightweight future extension.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cinder allows the creation of images from encrypted volumes. These will
always result in LUKS-encrypted raw images. Those images can be converted
directly to volumes again. This behavior is already implemented and requires
no format conversion as the LUKS encryption is native to Cinder.
The intention is to keep this functionality and make the format usable
outside of Cinder and provide interoperability for it.
To better identify such an image, we propose the new ‘container_format’
‘luks’ to be set for these images.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In the latter case it is already possible to upload such an encrypted image to
another OpenStack deployment, upload the key as well and set the
corresponding metadata. After doing so the image can be used in the second
deployment to create an encrypted volume.&lt;/p&gt;
&lt;p&gt;We want to align the existing implementations between Nova and Cinder by
standardizing the used metadata parameters and adding interoperability where
applicable. This would in the case of Cinder mainly be a change in the naming
of the following image properties:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;‘cinder_encryption_key_deletion_policy’ to ‘os_encrypt_key_deletion_policy’&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;‘cinder_encryption_key_id’ to ‘os_encrypt_key_id’&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A check in the volume creation flow will be added to look for encrypted
images proposed as a volume source. If an image is encrypted, another check is
added to determine, whether the volume type used to create the volume has an
encryption type. If that is not the case the volume creation will be aborted
early in the API. Since the encrypted data is always directly transferred over,
the volume would end up as unusable otherwise.&lt;/p&gt;
&lt;p&gt;The conversion of a qcow2+LUKS image should be handled when downloading the
image to a volume. The required volume size should be determined based on the
‘os_decrypt_size’ property of the image.&lt;/p&gt;
&lt;p&gt;The key management for creating an encrypted volume from an encrypted image
must include the cloning of the secret in Barbican. This way Cinder always
has the full control over the lifecycle of the secret and is similar to the
original creation of an encrypted volume. As secrets used for encrypted images
may be user-defined, Cinder cannot rely on the existence of the original secret
over time.&lt;/p&gt;
&lt;p&gt;In all places that implement image decryption within Cinder, an additional
check for the type of the secret needs to be added. Different key handling
needs to be triggered if the secret is a “passphrase”, because the way Cinder
currently treats keys to create a passphrase for the LUKS header of a volume
in way that always attempts to convert binary keys to an ASCII encoding first
and differs from Nova’s handling of images, that directly passes passphrases
only.&lt;/p&gt;
&lt;p&gt;The creation of an image from a volume just needs to be adjusted to use the new
properties.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;We also evaluated an image encryption implementation based on GPG. The downside
with such an implementation is, that every time such an image is used to create
a server or a volume the image has to be decrypted and maybe re-encrypted for
another encryption format as both Nova and Cinder use LUKS as an encryption
mechanism. This would not only have an impact on the performance of the
operation but it also would need free space for the encrypted image file, the
decrypted parts and the encrypted volume or server that is created.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;When creating a volume from an encrypted image there might occur a new ERROR
that is triggered when an image is encrypted but no encrypted volume type is
given.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;There are impacts on the security of OpenStack:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;confidentiality of data in images will be addressed in this spec&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;image encryption is introduced formally&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;cryptographic algorithms will be used in all involved components
(Nova, Cinder, OSC) that work with encrypted images&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="active-active-ha-impact"&gt;
&lt;h3&gt;Active/Active HA impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Users should be able to use encrypted images to create volumes in a
consistent way&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;The proposed checks for the Cinder API may have minimal impact on performance.&lt;/p&gt;
&lt;p&gt;When creating a volume or server from an encrypted image the only operation
that may be triggered is the conversion between qcow2+LUKS and raw LUKS blocks.&lt;/p&gt;
&lt;p&gt;Thus, any performance impact is only applicable to the newly introduced
encrypted image type where the processing of the image will have increased
computational costs and longer processing times than regular images. Impact
will vary depending on the individual host performance and supported CPU
extensions for cipher algorithms.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;For interoperability between the OpenStack services only the presence of a
key manager should decide, whether encryption can be used or not.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A key manager - like Barbican - is required, if encrypted images are to be
used.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Primary assignee: Markus Hentsch (IRC: mhen)&lt;/p&gt;
&lt;p&gt;Other contributors: Josephine Seifert (IRC: Luzi)&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add checks in the create volume API&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add cloning the secret for image encryption keys&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add dedicated handling of “passphrase” type secrets via os-brick&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add conversion of qcow2+LUKS images to raw LUKS encrypted block data&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the image creation from volume: change the
‘cinder_encryption_key_deletion_policy’ to ‘os_encrypt_key_deletion_policy’
and ‘cinder_encryption_key_id’ to ‘os_encrypt_key_id’&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add setting the ‘os_encrypt_format’ property when creating images from
encrypted volumes&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Handling of the new image encryption parameters and secret consumer usage
in Glance has to be implemented&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;os-brick implements a shared utility function for converting encryption keys
of different types, including ‘passphrase’ and ‘symmetric’&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Tempest tests will be added to the barbican-tempest-plugin in addition to its
existing scenario tests revolving around usage of secrets. These scenario
tests will create encrypted images in various permutations, including the
different image formats (qcow2+LUKS, raw LUKS) as well as the different secret
types influencing the key conversion. Each of the created images will be used
to create a volume from which a Nova instance will be booted and
health-checked.&lt;/p&gt;
&lt;p&gt;Another scenario will be added that specifically tests the creation of
encrypted images based on an encrypted volume by Cinder and the subsequent
use for a new encrypted volume to verify the correct production and
consumption of encrypted images as implemented by Cinder itself. This will act
as a regression test to make sure that the existing functionality of Cinder
being able to backup and restore encrypted volumes to/from images while
keeping the encryption intact through the whole chain stays functional.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;It should be documented for deployers, how to enable this feature in the
OpenStack configuration.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;[1] Barbican Secret Consumer Spec:
&lt;a class="reference external" href="https://review.opendev.org/#/c/662013/"&gt;https://review.opendev.org/#/c/662013/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[2] Glance Image Encryption Spec:
&lt;a class="reference external" href="https://review.opendev.org/c/openstack/glance-specs/+/964755"&gt;https://review.opendev.org/c/openstack/glance-specs/+/964755&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[3] Extended key to passphrase conversion outsourced to os-brick:
&lt;a class="reference external" href="https://review.opendev.org/c/openstack/os-brick/+/926293"&gt;https://review.opendev.org/c/openstack/os-brick/+/926293&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Fri, 24 Oct 2025 00:00:00 </pubDate></item><item><title>OpenAPI Schemas</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/2026.1/openapi.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/openapi"&gt;https://blueprints.launchpad.net/cinder/+spec/openapi&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;We would like to start documenting our APIs in an industry-standard,
machine-readable manner. Doing so opens up many opportunities for both
OpenStack developer and OpenStack users alike, notably the ability to both
auto-generate and auto-validate both client tooling and documentation alike.
Of the many API description languages available, OpenAPI (fka “Swagger”)
appears to be the one with both the largest developer mind share and the one
that would be the best fit for OpenStack due to the existing tooling used in
many OpenStack services, thus we would opt to use this format.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;The history of API description languages has been mainly a history of
half-baked ideas, unnecessary complication, and in general lots of failure.
This history has been reflected in OpenStack’s own history of attempting to
document APIs, starting with our early use of WADL through to our experiments
with Swagger 2.0 and RAML, leading to today’s use of our custom &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;os_api_ref&lt;/span&gt;&lt;/code&gt;
project, built on reStructuredText and Sphinx.&lt;/p&gt;
&lt;p&gt;It is only in recent years that things have started to stabilise somewhat, with
the development of widely used API description languages like OpenAPI, RAML and
API Blueprint, as well as supporting SaaS tools such as Postman and Apigee.
OpenAPI in particular has seen broad adoption across multiple sectors, with
sites as varied as &lt;a class="reference external" href="https://blog.cloudflare.com/open-api-transition"&gt;CloudFlare&lt;/a&gt; and &lt;a class="reference external" href="https://github.com/github/rest-api-description"&gt;GitHub&lt;/a&gt; providing OpenAPI schemas for
their APIs. OpenAPI has evolved significantly in recent years and now supports
a wide variety of API patterns including things like webhooks. Even more
beneficial for OpenStack, OpenAPI 3.1 is a full superset of JSON Schema meaning
we have the ability to re-use much of the validation we already have.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;As an end user, I would like to have access to machine-readable, fully
validated documentation for the APIs I will be interacting with.&lt;/p&gt;
&lt;p&gt;As an end user, I want statically viewable documentation hosted as part of the
existing docs site without requiring a running instance of Cinder.&lt;/p&gt;
&lt;p&gt;As an SDK/client developer, I would like to be able to auto-generate bindings
and clients, promoting consistency and minimising the amount of manual work
needed to develop and maintain these.&lt;/p&gt;
&lt;p&gt;As a Cinder developer, I would like to have a verified API specification that I
can use should I need to replace the web framework/libraries we use in the
event they are no longer maintained.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;This effort can be broken into a number of distinct steps:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Add missing request body and query string schemas&lt;/p&gt;
&lt;p&gt;These schemas will merely validate what is already allowed, which means
extensive use of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;"additionalProperties":&lt;/span&gt; &lt;span class="pre"&gt;true&lt;/span&gt;&lt;/code&gt; or empty schemas.&lt;/p&gt;
&lt;p&gt;Once these are added, tests will be added to ensure all API resource have
appropriate schemas.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add response body schemas&lt;/p&gt;
&lt;p&gt;These will be sourced from both existing OpenAPI schemas, currently published
at &lt;a class="reference external" href="https://opendev.org/openstack/codegenerator"&gt;opendev.org/openstack/codegenerator&lt;/a&gt;, and from new schemas
auto-generated from JSON response bodies generated in tests and manually
modified handle things like enum values.&lt;/p&gt;
&lt;p&gt;Once these are added, tests will be added to ensure all API resource have
appropriate response body schemas. In addition, we will add a new
configuration option that will control how we do verification at
the API layer, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;[api]&lt;/span&gt; &lt;span class="pre"&gt;response_validation&lt;/span&gt;&lt;/code&gt;. This will be an enum value with
three options:&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;error&lt;/span&gt;&lt;/code&gt;&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Raise a HTTP 500 (Server Error) in the event that an API returns an
“invalid” response.&lt;/p&gt;
&lt;p&gt;This will be the default in CI i.e. for our unit, functional and
integration tests. Eventually this could be the default for production
also (but probably not).&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;warn&lt;/span&gt;&lt;/code&gt;&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Log a warning about an “invalid” response, prompting operations to file a
bug report against Cinder.&lt;/p&gt;
&lt;p&gt;This will be initial (and likely forever) default in production.&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ignore&lt;/span&gt;&lt;/code&gt;&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Disable API response body validation entirely. This is an escape hatch in
case we mess up.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;The development of tooling required to gather these JSON Schema schemas and
generate an OpenAPI schema will not be developed inside Cinder and is
therefore not covered by this spec. Cinder will merely consume the
resulting tooling for use in documentation.&lt;/p&gt;
&lt;/div&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Use a different tool&lt;/p&gt;
&lt;p&gt;OpenAPI has been chosen because it is the most widely used API description
language available and matches well with our existing use of JSON Schema for
API validation.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Maintain these specs out-of-tree&lt;/p&gt;
&lt;p&gt;This prevents us testing these on each commit to Cinder and means work that
could be spread across multiple teams is instead focused on one small team.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;There will be no direct REST API impact. Users will see HTTP 500 error if they
set &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;[api]&lt;/span&gt; &lt;span class="pre"&gt;response_validation&lt;/span&gt; &lt;span class="pre"&gt;=&lt;/span&gt; &lt;span class="pre"&gt;error&lt;/span&gt;&lt;/code&gt; and encounter an invalid response,
however, we will not encourage use of this option in production and will
instead focus on validating this ourselves in CI.&lt;/p&gt;
&lt;p&gt;We may wish to address issues that are uncovered as we add schemas, but this
work is considered secondary to this effort and can be tackled separately.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="active-active-ha-impact"&gt;
&lt;h3&gt;Active/Active HA impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;This should be very beneficial for users who are interested in developing
client and bindings for OpenStack. In particular, this should (after an initial
effort in code generation) reduce the workload of the SDK team as well as teams
outside of OpenStack that work on client tooling such as the Gophercloud team.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;There will be a minimal impact on API performance when validation is enabled as
we will now verify both requests and responses for all API resources. Given our
existing extensive use of JSON Schema for API validation, it is expected that
this should not be a significant issue. In addition, we will not recommend
enabling this option in production.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;As noted previously, there will be one new config option, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;[api]&lt;/span&gt;
&lt;span class="pre"&gt;response_validation&lt;/span&gt;&lt;/code&gt;. Operators may see increased warnings in their logs due
to incomplete schemas, but most if not all of these issues should be ironed out
by our CI coverage.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Developers working on the API microversions will now be encouraged to provide
JSON Schema schemas for both requests and responses.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;stephenfinucane&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;gtema&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add missing request body schemas&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add tests to validate existence of request body schemas&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add missing query string schemas&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add tests to validate existence of query string schemas&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add response body schemas&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add decorator to validate response body schemas against response&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add tests to validate existence of response body schemas&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;doc/source/contributor/api_microversion_dev.rst&lt;/span&gt;&lt;/code&gt; to include
the requirement that anyone contributing a change that requires a new
microversion is expected to provide request and response schemas&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;The actual generation of an OpenAPI documentation will be achieved via a
separate tool. It is not yet determined if this tool will live inside an
existing project, such as &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;os_api_ref&lt;/span&gt;&lt;/code&gt; or &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;openstacksdk&lt;/span&gt;&lt;/code&gt;, or inside a
wholly new project. In any case, it is envisaged that this tool will handle
OpenStack-specific nuances like microversions that don’t map 1:1 to OpenAPI
concepts in a consistent and documented fashion.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit tests will ensure that schemas eventually exist for request bodies, query
strings, and response bodies.&lt;/p&gt;
&lt;p&gt;Unit, functional and integration tests will all work together to ensure that
response body schemas match real responses by setting &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;[api]&lt;/span&gt;
&lt;span class="pre"&gt;response_validation&lt;/span&gt;&lt;/code&gt; to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;error&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Initially there should be no impact as we will continue to use &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;os_api_ref&lt;/span&gt;&lt;/code&gt;
as-is for our &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;api-ref&lt;/span&gt;&lt;/code&gt; docs. Eventually we will replace or extend this
extension to generate documentation from our OpenAPI schema.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="history"&gt;
&lt;h2&gt;History&lt;/h2&gt;
&lt;table class="docutils align-default" id="id4"&gt;
&lt;caption&gt;&lt;span class="caption-text"&gt;Revisions&lt;/span&gt;&lt;/caption&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Release Name&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;2025.01&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Introduced&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;2026.01&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Re-proposed&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/section&gt;
</description><pubDate>Tue, 14 Oct 2025 00:00:00 </pubDate></item><item><title>No specs have yet been approved.</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/2026.1/remove-me.html</link><description>

</description><pubDate>Fri, 26 Sep 2025 00:00:00 </pubDate></item><item><title>Restrict new container creation for Cinder Backup</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/2026.1/restrict-backup-container-creation.html</link><description>

&lt;p&gt;The URL of launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/restrict-backup-container-creation"&gt;https://blueprints.launchpad.net/cinder/+spec/restrict-backup-container-creation&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This spec is designed to allow operators to restrict new container creation
by users during backup creation, when a non-existent container is passed as
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;container&lt;/span&gt;&lt;/code&gt; argument with a POST &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/v3/{project_id}/backups&lt;/span&gt;&lt;/code&gt; request.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;While creating Cinder backups, users are able to supply an arbitrary container
name, where the backup will be stored. While this behavior makes total sense
with the Swift driver and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;backup_swift_auth=per_user&lt;/span&gt;&lt;/code&gt;, as this will utilize
tenant quota and data will be accounted properly, using arbitrary containers
might be unwanted by operators while using other drivers.&lt;/p&gt;
&lt;p&gt;Current behavior may cause various negative side-effects when users use
arbitrary container names, for example: being unable to enforce storage policies,
going out of designed quota for backups, complications for accounting of
consumed disk space and billing, etc.&lt;/p&gt;
&lt;p&gt;At the moment container creation is supported by the following drivers:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Swift&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;S3&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;GCS&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;POSIX&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;For instance, with the S3/GCS driver, as an operator, I want to pre-create a
series of buckets with different policies like object locking with various
retention rules or different storage classes. While current behavior might
work, ability for users to create new buckets will result in an approach that
is not error-prone, as due to typos backups may end in unexpected locations.&lt;/p&gt;
&lt;p&gt;With the POSIX driver as example, as operator I want to have different mounts and
underlying storages per “container”. With current behavior this approach is
impossible as users may bypass the defined mount boundaries by creating a new
path with an arbitrary container name.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;It is proposed to introduce a new configuration option
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;backup_create_containers&lt;/span&gt;&lt;/code&gt;, which will control whether Cinder Backup will
attempt to create a new container when a user has supplied a non-existing
container name in request or fail such request.&lt;/p&gt;
&lt;p&gt;When this option is set to False, duty of creating all containers, including
the default one, falls under operator responsibility. This means that all
containers, including the default one, must be pre-created before any backup
can be done.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Alternative approach would be to introduce a separate policy, which may allow
users with required privileges to create containers with backups.
However, implementation of this approach is more complex while not providing
much more benefits for the use case, given that operators are usually not
executing backup creation on their own.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;No data model impact&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;No direct impact on REST API.&lt;/p&gt;
&lt;p&gt;POST requests to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/v3/{project_id}/backups&lt;/span&gt;&lt;/code&gt; supplying &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;container&lt;/span&gt;&lt;/code&gt;
parameter that is not found on backends with
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;backup_create_containers=False&lt;/span&gt;&lt;/code&gt; will result in backup creation failures,
with the corresponding reason being recorded in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;fail_reason&lt;/span&gt;&lt;/code&gt; column of
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;backups&lt;/span&gt;&lt;/code&gt; table.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;This change should positively impact overall security of Cinder Backup,
as it allows restricting potentially too open possibilities of container
creation, which depending on deployment design and driver may lead to
unexpected behavior or even denial of service.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="active-active-ha-impact"&gt;
&lt;h3&gt;Active/Active HA impact&lt;/h3&gt;
&lt;p&gt;Not applicable for Cinder Backup service&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;No impact&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;When &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;backup_create_containers=False&lt;/span&gt;&lt;/code&gt; users will be able to create backups
only in a predefined set of container names provided by the cloud provider and
will not be able to use arbitrary container names.&lt;/p&gt;
&lt;p&gt;A disadvantage of the approach, is that check for container existence is
performed asynchronously by cinder-backup service, so user will not receive
an error on issuing API request, but will see a 404 error as a reason for
backup creation failure instead.
The error will be shown in backup failure reason and not in the API response
to the request, as API does not wait for RPC messaging with the backup
service to happen.&lt;/p&gt;
&lt;p&gt;There is also no discoverability mechanism if this property is enabled or not, so user
is not able to know in advance if &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;backup_create_containers&lt;/span&gt;&lt;/code&gt; is enabled or
not. It is the cloud provider responsibility to inform users about cases, where
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;backup_create_containers&lt;/span&gt;&lt;/code&gt; is set to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;False&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;No performance impact&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;Default value of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;backup_create_containers&lt;/span&gt;&lt;/code&gt; is proposed to be set to
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;True&lt;/span&gt;&lt;/code&gt;, to preserve existing behavior.
Therefore, no deployer impact is expected.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;No impact&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Dmitriy Rabotyagov &amp;lt;noonedeadpunk&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Introduce new configuration parameter for cinder-backup globally&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add support to S3 backup driver&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add support to GCS backup driver&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add support to Swift backup driver&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add support to POSIX backup driver&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;No dependencies&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit testing of this option will be introduced, to ensure that cinder-backup
will not call for new container creation to the backend, when
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;backup_create_containers&lt;/span&gt;&lt;/code&gt; is set to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;False&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;New option will be documented as part of the Cinder Backup configuration
guide.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Reference implementation: &lt;a class="reference external" href="https://review.opendev.org/c/openstack/cinder/+/959425"&gt;https://review.opendev.org/c/openstack/cinder/+/959425&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Fri, 29 Aug 2025 00:00:00 </pubDate></item><item><title>Show migration_progress in volume details</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/2025.1/migration-progress-in-volume-details.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/migration-progress-in-volume-details"&gt;https://blueprints.launchpad.net/cinder/+spec/migration-progress-in-volume-details&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This spec proposes adding a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;migration_progress&lt;/span&gt;&lt;/code&gt; field to the volume
details API response when a volume is migrating.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Volume migration might be facilitated by the backend driver, but often
requires cinder or nova to copy data from the source to the new volume.  For
large volumes this can take a long time to complete (multiple hours, even
days). Currently there’s no way to track the copy operation’s progress, which
makes it difficult to predict when the migration will complete.&lt;/p&gt;
&lt;section id="use-cases"&gt;
&lt;h3&gt;Use Cases&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;As a cloud admin who is migrating a volume, I need to know it isn’t taking
so much time to complete that I fear the operation is stuck.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;As a cloud admin who is migrating a volume, I would like to track the
migration progress in order to gauge how much longer it might take for the
operation to complete.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;The API code for showing a volume’s details would use a microversion to
optionally include a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;migration_progress&lt;/span&gt;&lt;/code&gt; field. The field would be included
in the API response only when the volume is migrating, and when permitted by
the microversion. As the existing &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;migration_status&lt;/span&gt;&lt;/code&gt; field is admin-only,
the new field would also be admin-only.&lt;/p&gt;
&lt;p&gt;The value would be obtained via an RPC that fetches a response from either the
volume service associated with the volume, or from nova when the volume is
attached and nova is copying the data. See the references for the proposed nova
feature. The RPC to the volume service or nova would be executed only when the
following criteria are met:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The context is admin&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The volume’s &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;migration_status&lt;/span&gt;&lt;/code&gt; is “migrating”&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The API request satisfies the new microversion&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The volume service handling the RPC will determine how the volume is migrating
in order to provide the proper response.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;When a migration requires cinder to copy the data then the RPC response will
be a string representing a percent completion (e.g. “42” for 42%
complete). This is the same response that nova returns when it provides a
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;swap_progress&lt;/span&gt;&lt;/code&gt; response when its swapping a volume attachment.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When a migration is handled by the volume’s driver then the RPC response
will be a TBD string to indicate the migration is driver-assisted. The
subset of cinder drivers that support driver-assisted migration do not
expose an API for reporting migration progress, and the expectation is
drivers complete the migration fast enough to provide a satisfactory user
experience (i.e. the use cases are covered).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If the migration has completed by the time the RPC is received, the response
will be &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;None&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;At the API layer, the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;migration_progress&lt;/span&gt;&lt;/code&gt; field will be included in the
volume details response only when the RPC response is a non-empty string. For
attached volumes, nova’s &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;swap_progress&lt;/span&gt;&lt;/code&gt; will be reported as the volume’s
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;migration_status&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;An earlier idea was to enhance cinder so it tried to use “driver assisted
volume migration” on attached volumes. The hope was that cinder drivers would
be capable of migrating data fast enough to alleviate concerns about the
process taking too long. This idea was rejected for multiple reasons:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Not all cinder drivers support driver-assisted migration, and most of them
explicitly disallow migrating attached volumes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Interactions between cinder and nova would be complicated. Cinder would need
to tell nova to pause IO prior to migrating the volume, and then unpause
after migration completes.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;TBD, but hopefully none. It may be necessary to add a DB field to facilitate
obtaining the proper RPC response. This will be carefully considered during
the design phase, with a goal of minimizing impact on the DB.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;Add a new microversion to the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;GET&lt;/span&gt; &lt;span class="pre"&gt;/v3/volumes/{volume_id}&lt;/span&gt;&lt;/code&gt; API to include
an optional &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;migration_progress&lt;/span&gt;&lt;/code&gt; field in the response when the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;migration_status&lt;/span&gt;&lt;/code&gt; field is &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;migrating&lt;/span&gt;&lt;/code&gt;, and the API context is for an
admin.&lt;/p&gt;
&lt;div class="highlight-json notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"volume"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"attachments"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"availability_zone"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"nova"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"bootable"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"false"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"consistencygroup_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"created_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2018-11-29T06:50:07.770785"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"encrypted"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"f7223234-1afc-4d19-bfa3-d19deb6235ef"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"links"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="nt"&gt;"href"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http://127.0.0.1:45839/v3/89afd400-b646-4bbc-b12b-c0a4d63e5bd3/volumes/f7223234-1afc-4d19-bfa3-d19deb6235ef"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="nt"&gt;"rel"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"self"&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="nt"&gt;"href"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http://127.0.0.1:45839/89afd400-b646-4bbc-b12b-c0a4d63e5bd3/volumes/f7223234-1afc-4d19-bfa3-d19deb6235ef"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="nt"&gt;"rel"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bookmark"&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"metadata"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"migration_status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"migrating"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"multiattach"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"os-vol-host-attr:host"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"os-vol-mig-status-attr:migstat"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"os-vol-mig-status-attr:name_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"os-vol-tenant-attr:tenant_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"89afd400-b646-4bbc-b12b-c0a4d63e5bd3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"replication_status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"size"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"snapshot_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"source_volid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"creating"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"updated_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"user_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"c853ca26-e8ea-4797-8a52-ee124a013d0e"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"volume_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"__DEFAULT__"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"provider_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"service_uuid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"shared_targets"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"cluster_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"volume_type_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"5fed9d7c-401d-46e2-8e80-f30c70cb7e1d"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"consumes_quota"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"migration_progress"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"42"&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None. The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;migration_progress&lt;/span&gt;&lt;/code&gt; will be admin-only.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="active-active-ha-impact"&gt;
&lt;h3&gt;Active/Active HA impact&lt;/h3&gt;
&lt;p&gt;None, I presume.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;Both the openstack and cinder cli will automatically show the new
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;migration_progress&lt;/span&gt;&lt;/code&gt; field if it’s present in the API response.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;There will be no performance impact unless the volume is migrating. When it
is migrating, an RPC is requred to fetch the migration progress data, either
from nova (when the volume is attached) or from the volume service.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="upgrade-impact"&gt;
&lt;h3&gt;Upgrade impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&amp;lt;&lt;a class="reference external" href="mailto:abishop%40redhat.com"&gt;abishop&lt;span&gt;@&lt;/span&gt;redhat&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add a new microversion in cinder and bump the MAX in python-cinderclient&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a new field to the volume details response in a new microversion&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add an RPC to fetch the migration progress from the volume service&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update the API code to invoke the appropriate (cinder or nova) RPC&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Extend existing unit and functional tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update API documentation&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;Tracking the migration progress of an attached volume requires a nova feature.
See the references for the nova feature spec.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;TBD. The tricky part for incorporating something into a tempest test is
catching a migration operation during the time it’s copying the volume data,
which is the only time when the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;migration_progress&lt;/span&gt;&lt;/code&gt; field will be present
in the volume details response.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;The Block Storage API reference documentation will need to be updated, but
there should be no impact on other user or admin facing documentation.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.opendev.org/c/openstack/nova-specs/+/937485"&gt;https://review.opendev.org/c/openstack/nova-specs/+/937485&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Mon, 16 Dec 2024 00:00:00 </pubDate></item><item><title>OpenAPI Schemas</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/2025.1/openapi.html</link><description>

&lt;p&gt;Include the URL of your launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/openapi"&gt;https://blueprints.launchpad.net/cinder/+spec/openapi&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;We would like to start documenting our APIs in an industry-standard,
machine-readable manner. Doing so opens up many opportunities for both
OpenStack developer and OpenStack users alike, notably the ability to both
auto-generate and auto-validate both client tooling and documentation alike.
Of the many API description languages available, OpenAPI (fka “Swagger”)
appears to be the one with both the largest developer mind share and the one
that would be the best fit for OpenStack due to the existing tooling used in
many OpenStack services, thus we would opt to use this format.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;The history of API description languages has been mainly a history of
half-baked ideas, unnecessary complication, and in general lots of failure.
This history has been reflected in OpenStack’s own history of attempting to
document APIs, starting with our early use of WADL through to our experiments
with Swagger 2.0 and RAML, leading to today’s use of our custom &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;os_api_ref&lt;/span&gt;&lt;/code&gt;
project, built on reStructuredText and Sphinx.&lt;/p&gt;
&lt;p&gt;It is only in recent years that things have started to stabilise somewhat, with
the development of widely used API description languages like OpenAPI, RAML and
API Blueprint, as well as supporting SaaS tools such as Postman and Apigee.
OpenAPI in particular has seen broad adoption across multiple sectors, with
sites as varied as &lt;a class="reference external" href="https://blog.cloudflare.com/open-api-transition"&gt;CloudFlare&lt;/a&gt; and &lt;a class="reference external" href="https://github.com/github/rest-api-description"&gt;GitHub&lt;/a&gt; providing OpenAPI schemas for
their APIs. OpenAPI has evolved significantly in recent years and now supports
a wide variety of API patterns including things like webhooks. Even more
beneficial for OpenStack, OpenAPI 3.1 is a full superset of JSON Schema meaning
we have the ability to re-use much of the validation we already have.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;As an end user, I would like to have access to machine-readable, fully
validated documentation for the APIs I will be interacting with.&lt;/p&gt;
&lt;p&gt;As an end user, I want statically viewable documentation hosted as part of the
existing docs site without requiring a running instance of Cinder.&lt;/p&gt;
&lt;p&gt;As an SDK/client developer, I would like to be able to auto-generate bindings
and clients, promoting consistency and minimising the amount of manual work
needed to develop and maintain these.&lt;/p&gt;
&lt;p&gt;As a Cinder developer, I would like to have a verified API specification that I
can use should I need to replace the web framework/libraries we use in the
event they are no longer maintained.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;This effort can be broken into a number of distinct steps:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Add missing request body and query string schemas&lt;/p&gt;
&lt;p&gt;These schemas will merely validate what is already allowed, which means
extensive use of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;"additionalProperties":&lt;/span&gt; &lt;span class="pre"&gt;true&lt;/span&gt;&lt;/code&gt; or empty schemas.&lt;/p&gt;
&lt;p&gt;Once these are added, tests will be added to ensure all API resource have
appropriate schemas.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add response body schemas&lt;/p&gt;
&lt;p&gt;These will be sourced from both existing OpenAPI schemas, currently published
at &lt;a class="reference external" href="https://opendev.org/openstack/codegenerator"&gt;opendev.org/openstack/codegenerator&lt;/a&gt;, and from new schemas
auto-generated from JSON response bodies generated in tests and manually
modified handle things like enum values.&lt;/p&gt;
&lt;p&gt;Once these are added, tests will be added to ensure all API resource have
appropriate response body schemas. In addition, we will add a new
configuration option that will control how we do verification at
the API layer, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;[api]&lt;/span&gt; &lt;span class="pre"&gt;response_validation&lt;/span&gt;&lt;/code&gt;. This will be an enum value with
three options:&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;error&lt;/span&gt;&lt;/code&gt;&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Raise a HTTP 500 (Server Error) in the event that an API returns an
“invalid” response.&lt;/p&gt;
&lt;p&gt;This will be the default in CI i.e. for our unit, functional and
integration tests. Eventually this could be the default for production
also (but probably not).&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;warn&lt;/span&gt;&lt;/code&gt;&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Log a warning about an “invalid” response, prompting operations to file a
bug report against Cinder.&lt;/p&gt;
&lt;p&gt;This will be initial (and likely forever) default in production.&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ignore&lt;/span&gt;&lt;/code&gt;&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Disable API response body validation entirely. This is an escape hatch in
case we mess up.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;The development of tooling required to gather these JSON Schema schemas and
generate an OpenAPI schema will not be developed inside Cinder and is
therefore not covered by this spec. Cinder will merely consume the
resulting tooling for use in documentation.&lt;/p&gt;
&lt;/div&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Use a different tool&lt;/p&gt;
&lt;p&gt;OpenAPI has been chosen because it is the most widely used API description
language available and matches well with our existing use of JSON Schema for
API validation.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Maintain these specs out-of-tree&lt;/p&gt;
&lt;p&gt;This prevents us testing these on each commit to Cinder and means work that
could be spread across multiple teams is instead focused on one small team.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;There will be no direct REST API impact. Users will see HTTP 500 error if they
set &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;[api]&lt;/span&gt; &lt;span class="pre"&gt;response_validation&lt;/span&gt; &lt;span class="pre"&gt;=&lt;/span&gt; &lt;span class="pre"&gt;error&lt;/span&gt;&lt;/code&gt; and encounter an invalid response,
however, we will not encourage use of this option in production and will
instead focus on validating this ourselves in CI.&lt;/p&gt;
&lt;p&gt;We may wish to address issues that are uncovered as we add schemas, but this
work is considered secondary to this effort and can be tackled separately.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="active-active-ha-impact"&gt;
&lt;h3&gt;Active/Active HA impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;This should be very beneficial for users who are interested in developing
client and bindings for OpenStack. In particular, this should (after an initial
effort in code generation) reduce the workload of the SDK team as well as teams
outside of OpenStack that work on client tooling such as the Gophercloud team.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;There will be a minimal impact on API performance when validation is enabled as
we will now verify both requests and responses for all API resources. Given our
existing extensive use of JSON Schema for API validation, it is expected that
this should not be a significant issue. In addition, we will not recommend
enabling this option in production.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;As noted previously, there will be one new config option, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;[api]&lt;/span&gt;
&lt;span class="pre"&gt;response_validation&lt;/span&gt;&lt;/code&gt;. Operators may see increased warnings in their logs due
to incomplete schemas, but most if not all of these issues should be ironed out
by our CI coverage.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Developers working on the API microversions will now be encouraged to provide
JSON Schema schemas for both requests and responses.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;stephenfinucane&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;gtema&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add missing request body schemas&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add tests to validate existence of request body schemas&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add missing query string schemas&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add tests to validate existence of query string schemas&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add response body schemas&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add decorator to validate response body schemas against response&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add tests to validate existence of response body schemas&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;doc/source/contributor/api_microversion_dev.rst&lt;/span&gt;&lt;/code&gt; to include
the requirement that anyone contributing a change that requires a new
microversion is expected to provide request and response schemas&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;The actual generation of an OpenAPI documentation will be achieved via a
separate tool. It is not yet determined if this tool will live inside an
existing project, such as &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;os_api_ref&lt;/span&gt;&lt;/code&gt; or &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;openstacksdk&lt;/span&gt;&lt;/code&gt;, or inside a
wholly new project. In any case, it is envisaged that this tool will handle
OpenStack-specific nuances like microversions that don’t map 1:1 to OpenAPI
concepts in a consistent and documented fashion.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit tests will ensure that schemas eventually exist for request bodies, query
strings, and response bodies.&lt;/p&gt;
&lt;p&gt;Unit, functional and integration tests will all work together to ensure that
response body schemas match real responses by setting &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;[api]&lt;/span&gt;
&lt;span class="pre"&gt;response_validation&lt;/span&gt;&lt;/code&gt; to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;error&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Initially there should be no impact as we will continue to use &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;os_api_ref&lt;/span&gt;&lt;/code&gt;
as-is for our &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;api-ref&lt;/span&gt;&lt;/code&gt; docs. Eventually we will replace or extend this
extension to generate documentation from our OpenAPI schema.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="history"&gt;
&lt;h2&gt;History&lt;/h2&gt;
&lt;table class="docutils align-default" id="id4"&gt;
&lt;caption&gt;&lt;span class="caption-text"&gt;Revisions&lt;/span&gt;&lt;/caption&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Release Name&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;2025.01&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Introduced&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/section&gt;
</description><pubDate>Fri, 15 Nov 2024 00:00:00 </pubDate></item><item><title>Rootwrap daemon mode</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/liberty/rootwrap-daemon-mode.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/rootwrap-daemon-mode"&gt;https://blueprints.launchpad.net/cinder/+spec/rootwrap-daemon-mode&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Cinder is one of projects that require root privileges. Currently this
is achieved with oslo.rootwrap that has to be run with sudo. Both sudo
and rootwrap produce significant performance overhead. This blueprint
is one of the series of blueprints that would cover mitigating rootwrap
part of the overhead using new mode of operations for rootwrap - daemon
mode. These blueprints will be created in several projects starting
with oslo.rootwrap &lt;a class="footnote-reference brackets" href="#rw-bp" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;As you can see in &lt;a class="footnote-reference brackets" href="#ne-ml" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; rootwrap presents big performance overhead for
Neutron. Impact on Cinder is not as significant but it is still there.
Details of the overhead are covered in &lt;a class="footnote-reference brackets" href="#rw-bp" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;This will eliminate bottleneck in large number of concurrent executed
operations.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;This blueprint proposes implement changes that allow to run oslo.rootwrap
daemon. The daemon works just as a usual rootwrap but accepts commands to
be run over authenticated UNIX domain socket instead of command line and
run continuously in background.&lt;/p&gt;
&lt;p&gt;Note that this is not usual RPC over some message queue. It uses UNIX socket,
so no remote connections are available. It also uses digest authentication
with key shared over stdout (pipe) with parent process, so no other processes
will have access to the daemon. Further details of rootwrap daemon are covered
in &lt;a class="footnote-reference brackets" href="#rw-bp" id="id4" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;use_rootwrap_daemon&lt;/span&gt;&lt;/code&gt; configuration option should be added that will make
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;utils.execute&lt;/span&gt;&lt;/code&gt; use daemon instead of usual rootwrap.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Alternative approaches have been discussed in &lt;a class="footnote-reference brackets" href="#rw-eth" id="id5" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;5&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;This change requires additional endpoint to be available to run as root -
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cinder-rootwrap-daemon&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;All security issues with using client+daemon instead of plain rootwrap are
covered in &lt;a class="footnote-reference brackets" href="#rw-bp" id="id6" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;This change introduces performance boost for disk operations that are
required to be run with root privileges. Current state of rootwrap daemon
in Neutron shows over 10x speedup comparing to usual &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;sudo&lt;/span&gt; &lt;span class="pre"&gt;rootwrap&lt;/span&gt;&lt;/code&gt; call.
Total speedup for Cinder shows impressive results too &lt;a class="footnote-reference brackets" href="#rw-perf" id="id7" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;:
test scenario CinderVolumes.create_and_delete_volume
Current performance :&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;action&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;min (sec)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;avg (sec)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;max (sec)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;count&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;cinder.create_volume
cinder.delete_volume
total&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;2.779
13.535
16.314&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;5.76
24.958
30.718&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;14.375
32.959
35.96&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;8
8
8&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Load duration: 131.423681974
Full duration: 135.794852018&lt;/p&gt;
&lt;p&gt;With use_rootwrap_daemon enabled:&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;action&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;min (sec)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;avg (sec)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;max (sec)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;count&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;cinder.create_volume
cinder.delete_volume
total&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;2.49
2.183
4.673&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;2.619
2.226
4.845&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;3.086
2.353
5.3&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;8
8
8&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Load duration: 19.7548749447
Full duration: 22.2729279995&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;This change introduces new config variable &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;use_rootwrap_daemon&lt;/span&gt;&lt;/code&gt; that
switches on new behavior. Note that by default &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;use_rootwrap_daemon&lt;/span&gt;&lt;/code&gt; will be
turned off so to get the speedup one will have to turn it on. With it
turned on &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cinder-rootwrap-daemon&lt;/span&gt;&lt;/code&gt; is used to run commands that require root
privileges.&lt;/p&gt;
&lt;p&gt;This change also introduces new binary &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cinder-rootwrap-daemon&lt;/span&gt;&lt;/code&gt; that should
be deployed beside &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cinder-rootwrap&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Anton Arefiev(aarefiev)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;The only work item here is to implement new config variable and run rootwrap
in daemon mode with it.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;rootwrap-daemon-mode blueprint in oslo.rootwrap &lt;a class="footnote-reference brackets" href="#rw-bp" id="id8" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Rootwrap has it’s own functional testing for the rootwrap client/daemon
pieces &lt;a class="footnote-reference brackets" href="#rw-func" id="id9" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, Cinder part will be covered by unit tests.&lt;/p&gt;
&lt;p&gt;Cinder has an unusual usecase where tens/hundreds of mb are passed over
stdin/out (sheepdog backup) - that test case should be covered in the
functional tests.&lt;/p&gt;
&lt;p&gt;Also we can add new Tempest job with turned on use rootwrap daemon flag.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Set &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;use_rootwrap_daemon=True&lt;/span&gt;&lt;/code&gt; configuration option in cinder.conf to make
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;utils.execute&lt;/span&gt;&lt;/code&gt; use daemon instead of usual rootwrap.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="rw-bp" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id3"&gt;2&lt;/a&gt;,&lt;a role="doc-backlink" href="#id4"&gt;3&lt;/a&gt;,&lt;a role="doc-backlink" href="#id6"&gt;4&lt;/a&gt;,&lt;a role="doc-backlink" href="#id8"&gt;5&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;oslo.rootwrap blueprint:
&lt;a class="reference external" href="https://blueprints.launchpad.net/oslo.rootwrap/+spec/rootwrap-daemon-mode"&gt;https://blueprints.launchpad.net/oslo.rootwrap/+spec/rootwrap-daemon-mode&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="ne-ml" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;Original mailing list thread:
&lt;a class="reference external" href="http://lists.openstack.org/pipermail/openstack-dev/2014-March/029017.html"&gt;http://lists.openstack.org/pipermail/openstack-dev/2014-March/029017.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="rw-func" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id9"&gt;3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;Rootwrap daemon functional testing
&lt;a class="reference external" href="https://github.com/openstack/oslo.rootwrap/blob/master/tests/test_functional.py"&gt;https://github.com/openstack/oslo.rootwrap/blob/master/tests/test_functional.py&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="rw-perf" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id7"&gt;4&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;Cinder performance testing results
&lt;a class="reference external" href="http://paste.openstack.org/show/160890/"&gt;http://paste.openstack.org/show/160890/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="rw-eth" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id5"&gt;5&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;Alternative approaches
&lt;a class="reference external" href="https://etherpad.openstack.org/p/neutron-agent-exec-performance"&gt;https://etherpad.openstack.org/p/neutron-agent-exec-performance&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Mon, 04 Nov 2024 00:00:00 </pubDate></item><item><title>No specs have yet been approved.</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/2025.1/remove-me.html</link><description>

</description><pubDate>Wed, 28 Aug 2024 00:00:00 </pubDate></item><item><title>rbd: Add snapshot mirroring support</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/untargeted/rbd-snapshot-mirroring.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/rbd-snapshot-mirroring"&gt;https://blueprints.launchpad.net/cinder/+spec/rbd-snapshot-mirroring&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This would be a good small project for someone interested in learning
about rbd and setting up an rbd test environment.  The blueprint was
proposed back in 2021 and has code proposed, but the original author
decided not to pursue it.  You can make yourself a co-author and complete
the patch.&lt;/p&gt;
&lt;p&gt;This was a small change, so it doesn’t have a full spec, just a blueprint
in Launchpad outlining the change.&lt;/p&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/rbd-snapshot-mirroring"&gt;https://blueprints.launchpad.net/cinder/+spec/rbd-snapshot-mirroring&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.opendev.org/c/openstack/cinder/+/784945"&gt;https://review.opendev.org/c/openstack/cinder/+/784945&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Wed, 14 Aug 2024 00:00:00 </pubDate></item><item><title>Add extend volume completion action</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/2024.2/extend-volume-completion-action.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/extend-volume-completion-action"&gt;https://blueprints.launchpad.net/cinder/+spec/extend-volume-completion-action&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This blueprint proposes a new volume action that can be used by Nova to notify
Cinder on success or failure when handling &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volume-extended&lt;/span&gt;&lt;/code&gt; external server
events.
The new volume action is used to add support for extending attached volumes to
the NFS, NetApp NFS, Powerstore NFS, and Quobyte volume drivers.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Many remotefs-based volume drivers in Cinder use the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;qemu-img&lt;/span&gt; &lt;span class="pre"&gt;resize&lt;/span&gt;&lt;/code&gt;
command to extend volume files.
However, when the volume is attached to a guest, QEMU will lock the file and
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;qemu-img&lt;/span&gt;&lt;/code&gt; will be unable to resize it.&lt;/p&gt;
&lt;p&gt;In this case, only the QEMU process holding the lock can resize the volume,
which can be triggered through the QEMU monitor command &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;block-resize&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;There is currently no adequate way for Cinder to use this feature, so the NFS,
NetApp NFS, Powerstore NFS, and Quobyte volume drivers all disable extending
attached volumes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;As a user, I want to extend a NFS/NetApp NFS/Powerstore NFS/Quobyte volume
while it is attached to an instance and I want the volume size and status to
reflect the success or failure of the operation.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Nova’s libvirt driver uses the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;block-resize&lt;/span&gt;&lt;/code&gt; command when handling the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volume-extended&lt;/span&gt;&lt;/code&gt; external server event, to inform QEMU that the size of an
attached volume has changed.
It is in principle also capable of extending a volume file, but is currently
unable to provide feedback to Cinder on the success of the operation.&lt;/p&gt;
&lt;p&gt;Currently, Cinder will send the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volume-extended&lt;/span&gt;&lt;/code&gt; external server event to
Nova only after it has finalized the extend operation and reset the volume
status from &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;extending&lt;/span&gt;&lt;/code&gt; back to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;in-use&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This spec proposes to give volume drivers a mechanism to hold off finalizing
the extend operation until after the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volume-extended&lt;/span&gt;&lt;/code&gt; event has been sent
and Cinder has received feedback from Nova that it was handled successfully.&lt;/p&gt;
&lt;p&gt;This spec also proposes a new volume action that Nova will use to provide this
feedback to Cinder.&lt;/p&gt;
&lt;section id="api"&gt;
&lt;h3&gt;API&lt;/h3&gt;
&lt;p&gt;A new API microversion is introduced, adding the new
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;os-extend_volume_completion&lt;/span&gt;&lt;/code&gt; volume action.&lt;/p&gt;
&lt;p&gt;The volume action takes a boolean &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;error&lt;/span&gt;&lt;/code&gt; argument, indicating success or
failure to extend the attached volume.
It is intended to be used exclusively by Nova to notify Cinder, and an
appropriate policy will be added to enforce this.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-extend-volume-completion"&gt;
&lt;h3&gt;API.extend_volume_completion&lt;/h3&gt;
&lt;p&gt;The new volume action will be handled by a new method in the volume API:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;extend_volume_completion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                             &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RequestContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                             &lt;span class="n"&gt;volume&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Volume&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                             &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The new method expects the volume to have status &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;extending&lt;/span&gt;&lt;/code&gt;, and to have the
keys &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;extend_reservations&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;extend_new_size&lt;/span&gt;&lt;/code&gt; in its admin metadata.
The first should hold a list of quota reservations, and the second should
contain an integer larger than the volume’s current size, representing the new
size after extending.&lt;/p&gt;
&lt;p&gt;If these conditions are not met, then an &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;InvalidVolume&lt;/span&gt;&lt;/code&gt; exception will be
raised, resulting in an HTTP response of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;400&lt;/span&gt; &lt;span class="pre"&gt;Bad&lt;/span&gt; &lt;span class="pre"&gt;Request&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If the conditions are met, it will remove size and reservations from the admin
metadata and call &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;VolumeManager.extend_volume_completion()&lt;/span&gt;&lt;/code&gt; via RPC,
passing both as arguments.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="volumemanager-extend-volume-completion"&gt;
&lt;h3&gt;VolumeManager.extend_volume_completion&lt;/h3&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;extend_volume_completion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                             &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RequestContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                             &lt;span class="n"&gt;volume&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Volume&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                             &lt;span class="n"&gt;new_size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                             &lt;span class="n"&gt;reservations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                             &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The behavior of this method depends heavily on the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;error&lt;/span&gt;&lt;/code&gt; argument:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;If &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;error&lt;/span&gt;&lt;/code&gt; is &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;True&lt;/span&gt;&lt;/code&gt;, the method will roll back the quota reservations,
set the volume status to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;error_extending&lt;/span&gt;&lt;/code&gt;, and log the error.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;error&lt;/span&gt;&lt;/code&gt; is &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;False&lt;/span&gt;&lt;/code&gt;, it will finalize the quota reservation, update
the size field of the volume to the new size, and reset the volume status to
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;available&lt;/span&gt;&lt;/code&gt; or &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;in-use&lt;/span&gt;&lt;/code&gt;, depending on the presence of attachments.
It will also update the pool stats and send a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;resize.end&lt;/span&gt;&lt;/code&gt; notification
with the new volume size.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is identical to how &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;VolumeManager.extend_volume()&lt;/span&gt;&lt;/code&gt; currently handles
success and failure of the volume driver’s &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;extend_volume()&lt;/span&gt;&lt;/code&gt; method, except
that this method will not notify Nova with the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volume-extended&lt;/span&gt;&lt;/code&gt; external
server event.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="volumedriver-extend-volume"&gt;
&lt;h3&gt;VolumeDriver.extend_volume&lt;/h3&gt;
&lt;p&gt;A mechanism will be introduced by which the driver’s &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;extend_volume()&lt;/span&gt;&lt;/code&gt;
method can signal to the volume manager that it has to wait for a response
from Nova before finishing the extend operation.
This could take the form of a return value or a new exception that the volume
manager will have to catch.&lt;/p&gt;
&lt;p&gt;The NFS, NetApp NFS, Powerstore NFS, and Quobyte volume drivers currently
have checks in their respective &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;extend_volume&lt;/span&gt;&lt;/code&gt; methods, that will raise an
exception if the volume to be resized is attached, causing the operation to
fail.
Those checks will be removed.&lt;/p&gt;
&lt;p&gt;Instead, the drivers will catch any exceptions resulting from the volume files
being locked (see the proposed change to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;nfs.py&lt;/span&gt;&lt;/code&gt; in &lt;a class="footnote-reference brackets" href="#id12" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; for an example on
how to do that), and notify the volume manager that feedback from Nova is
required.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="volumemanager-extend-volume"&gt;
&lt;h3&gt;VolumeManager.extend_volume&lt;/h3&gt;
&lt;p&gt;The call to the volume driver’s &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;extend_volume()&lt;/span&gt;&lt;/code&gt; method will be handled as
follows:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;If the call fails, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;extend_volume_completion&lt;/span&gt;&lt;/code&gt; will be called with
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;error=True&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If the call succeeds, but the volume is not attached,
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;extend_volume_completion&lt;/span&gt;&lt;/code&gt; will be called with &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;error=False&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If the call succeeds, and the volume is attached,
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;extend_volume_completion&lt;/span&gt;&lt;/code&gt; will be called with &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;error=False&lt;/span&gt;&lt;/code&gt; and Nova
will be notified with the external server event.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This matches the current inline behavior of the method, and covers offline
extend for all drivers, as well as online extend for the drivers that
previously supported it.&lt;/p&gt;
&lt;p&gt;To support remotefs-based drivers that have to rely on Nova for online extend,
two aditional cases will be handled:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;If the driver notifies the volume manager that a response from Nova is
required, but the volume is not attached, or the volume is attached to more
than one instance, it will be handled as failure and
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;extend_volume_completion&lt;/span&gt;&lt;/code&gt; will be called with &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;error=True&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;QEMU can not resize shared volume files, because they are locked read-only,
so adding multi-attach support for this feature is currently not worthwhile.
However, support may be added later if other drivers require it, e.g. by
enabling Cinder to handle multiple completion actions for the same volume.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If the driver notifies the volume manager that a response from Nova is
required, and the volume is attached to exactly one instance, then Cinder
will store the quota reservations and the target size in the in the admin
metadata with the keys &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;extend_reservations&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;extend_new_size&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;It will then attempt to send the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volume-extended&lt;/span&gt;&lt;/code&gt; external server event
with the new Nova API microversion proposed in &lt;a class="footnote-reference brackets" href="#id15" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, making sure that Nova
supports using the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;os-extend_volume_completion&lt;/span&gt;&lt;/code&gt; action.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;If the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volume-extended&lt;/span&gt;&lt;/code&gt; event has been submitted to Nova successfully,
this method will just return normally.
The volume will now be left in status &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;extending&lt;/span&gt;&lt;/code&gt;, which will signal to
Nova that it should respond with the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;os-extend_volume_completion&lt;/span&gt;&lt;/code&gt;
action, as described in the &lt;a class="reference internal" href="#nova"&gt;Nova&lt;/a&gt; subsection.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volume-extended&lt;/span&gt;&lt;/code&gt; event could not be submitted, the operation
will be rolled back by calling &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;extend_volume_completion&lt;/span&gt;&lt;/code&gt; with
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;error=True&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This can happen if Nova doesn’t support the required microversion yet, or
if the external event API responded with an error code such as &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;403&lt;/span&gt;&lt;/code&gt; or
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;404&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="visible-admin-metadata"&gt;
&lt;h3&gt;Visible Admin Metadata&lt;/h3&gt;
&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;extend_new_size&lt;/span&gt;&lt;/code&gt; has to be stored in the admin metadata, because the
regular volume metadata is editable by users.
A malicious user could otherwise edit the target size during the operation
to bypass their quota.&lt;/p&gt;
&lt;p&gt;Admin metadata of volumes is not visible to clients, but Cinder supports
mapping select keys to the regular metadata, shadowing any user-set values of
the same key.&lt;/p&gt;
&lt;p&gt;The key &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;extend_new_size&lt;/span&gt;&lt;/code&gt; will be added to the list of visible admin
metadata in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cinder/api/api_utils.py&lt;/span&gt;&lt;/code&gt;, so that Nova is able to read the
target size of the extend operation.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="openstack-sdk"&gt;
&lt;h3&gt;OpenStack SDK&lt;/h3&gt;
&lt;p&gt;Support for the new volume action will be added to the OpenStack SDK, which
Nova will use to call it.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="nova"&gt;
&lt;h3&gt;Nova&lt;/h3&gt;
&lt;p&gt;When the Nova API receives a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volume-extended&lt;/span&gt;&lt;/code&gt; external server event, and
the call used the new microversion proposed in &lt;a class="footnote-reference brackets" href="#id15" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, it will check the target
compute service version.
If a target compute agent is too old to support the feature, the API will
discard the event and call the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;os-extend_volume_completion&lt;/span&gt;&lt;/code&gt; volume action
with &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;"error":&lt;/span&gt; &lt;span class="pre"&gt;true&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Otherwise, the event will be forwarded to the compute agent.
When handling the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volume-extended&lt;/span&gt;&lt;/code&gt; external server event, compute will
check the volume status:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;If the volume status is &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;extending&lt;/span&gt;&lt;/code&gt;, then compute will attempt to read
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;extend_new_size&lt;/span&gt;&lt;/code&gt; from the volume’s metadata and use this value as the
new size of the volume, instead of the volume size field.&lt;/p&gt;
&lt;p&gt;After successfully extending the volume, it will call the extend volume
completion action of the volume, with &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;"error":&lt;/span&gt; &lt;span class="pre"&gt;false&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If anything goes wrong, including &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;extend_new_size&lt;/span&gt;&lt;/code&gt; being missing from the
metadata, or being smaller than the current size of the volume, compute will
log the error and call the extend volume completion action with
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;"error":&lt;/span&gt; &lt;span class="pre"&gt;true&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For any other volume status the event will be handled as before.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The changes in Nova are detailed in the current version of the Nova spec at
&lt;a class="footnote-reference brackets" href="#id15" id="id4" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="os-reset-status"&gt;
&lt;h3&gt;os-reset_status&lt;/h3&gt;
&lt;p&gt;When resetting from status &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;extending&lt;/span&gt;&lt;/code&gt;, the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;os-reset_status&lt;/span&gt;&lt;/code&gt; volume
action will check for the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;extend_reservations&lt;/span&gt;&lt;/code&gt; key in the admin metadata.
If it finds quota reservation keys, it will try to roll them back.&lt;/p&gt;
&lt;p&gt;This is done to avoid a pile up of quota reservations in case communication
between Cinder and Nova was lost and the status has to be reset to retry the
resize.&lt;/p&gt;
&lt;p&gt;The keys &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;extend_reservations&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;extend_new_size&lt;/span&gt;&lt;/code&gt; will then be removed
from the admin metadata.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A previous change tried to use the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volume-extended&lt;/span&gt;&lt;/code&gt; external server event
to support online extend for the NFS driver &lt;a class="footnote-reference brackets" href="#id12" id="id5" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, but did not rely on
feedback from Nova to Cinder at all.
Instead, it would just set the new size of the volume, change the status
back to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;in-use&lt;/span&gt;&lt;/code&gt;, notify Nova, and hope for the best.&lt;/p&gt;
&lt;p&gt;If anything went wrong on Nova’s side, this would still result in a volume
state indicating that the operation was successful, which is not acceptable.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The specs at &lt;a class="footnote-reference brackets" href="#id13" id="id6" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; and &lt;a class="footnote-reference brackets" href="#id14" id="id7" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; proposed a new synchronous API in Nova that can
be used to trigger an assisted resize operation.
This API would provide a single mechanism to trigger the resize operation,
communicate the new size to Nova, and get feedback on the success of the
operation.&lt;/p&gt;
&lt;p&gt;The problem with a synchronous API is, that RPC and API timeouts limit the
maximum time an extend operation can take.
For QEMU, this seemed to be acceptable, because storage preallocation is
hard disabled for the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;block-resize&lt;/span&gt;&lt;/code&gt; command, and because all currently
plausible file systems support sparse file operations.&lt;/p&gt;
&lt;p&gt;However, as reviewers in &lt;a class="footnote-reference brackets" href="#id13" id="id8" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; have pointed out,  this may not be true for
other volume or virt drivers that might require this API in the future.
It would also break with the established pattern of asynchronous
coordination between Nova and Cinder, which includes the assisted snapshot
and volume migration features.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Following this pattern, we could make the proposed API asynchronous and use
a new callback in Cinder, similar to Nova’s &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;os-assisted-volume-snapshots&lt;/span&gt;&lt;/code&gt;
API, which uses the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;os-update_snapshot_status&lt;/span&gt;&lt;/code&gt; snapshot action to provide
feedback to Cinder.&lt;/p&gt;
&lt;p&gt;The function of the new Nova API would then just be to trigger the operation
and to communicate the new size.
The question is then, whether that warrants adding a new API to Nova, since
there are existing mechanisms that could be used for either.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The existing mechanism for triggering the extend operation in Nova is, of
course, the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volume-extended&lt;/span&gt;&lt;/code&gt; external server event.
Using it for this purpose, as this spec proposes, requires the target size
to be transferred separately, because external server events only have a
single text field that is freely usable, which for &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volume-extended&lt;/span&gt;&lt;/code&gt;
is already used for the volume ID.&lt;/p&gt;
&lt;p&gt;Besides storing it in the admin metadata, as this spec proposes, there is
also the option of updating the size field of the volume, as &lt;a class="footnote-reference brackets" href="#id12" id="id9" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; was
essentially doing.&lt;/p&gt;
&lt;p&gt;This would require the volume size field to be reset on a failure.
If an error response from Nova was lost, the volume would just keep the new
size.
We would need to extend &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;os-reset_status&lt;/span&gt;&lt;/code&gt; to allow a size reset, or
something similar to clean up volumes like this.
This would be possible, but updating the size field only after the volume
was successfully extended seems like a cleaner solution.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We could also extend the external server event API to accept additional data
for events, and use this to communicate the new size to Nova.&lt;/p&gt;
&lt;p&gt;This option was judged favorably by reviewers on the previous version of
this spec, &lt;a class="footnote-reference brackets" href="#id13" id="id10" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, but it would be a more complex change to the Nova API.&lt;/p&gt;
&lt;p&gt;However, if additional data fields become available in a future version of
the external server event API, it would be a relatively minor change to use
those instead of the volume metadata.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;Starting with the new microversion, the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;POST&lt;/span&gt; &lt;span class="pre"&gt;/v3/{project_id}/volumes/{volume_id}/action&lt;/span&gt;&lt;/code&gt; API will accept request
bodies of the following form:&lt;/p&gt;
&lt;div class="highlight-json notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"os-extend_volume_completion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"error"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;with &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;error&lt;/span&gt;&lt;/code&gt; indicating success or failure of the resize operation.&lt;/p&gt;
&lt;p&gt;If the volume does not exist, the return code will be &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;404&lt;/span&gt; &lt;span class="pre"&gt;Not&lt;/span&gt; &lt;span class="pre"&gt;Found&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If the volume status and admin metadata do not indicate that Cinder was
waiting for an extend volume completion action, the return code will be
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;400&lt;/span&gt; &lt;span class="pre"&gt;Bad&lt;/span&gt; &lt;span class="pre"&gt;Request&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Otherwise the return code will be &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;202&lt;/span&gt; &lt;span class="pre"&gt;Accepted&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The new volume action is intended to only be used by Nova and will require
the caller to have admin permissions.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="active-active-ha-impact"&gt;
&lt;h3&gt;Active/Active HA impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;kgube&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Move extend completion code from &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;VolumeManager.extend_volume&lt;/span&gt;&lt;/code&gt; to new
method and add tests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create new volume action and add unit tests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a new microversion for the new &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;os-extend_volume_completion&lt;/span&gt;&lt;/code&gt; action.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add OpenStack SDK support.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add Nova support.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update drivers to use the feature.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Adapt the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;devstack-plugin-nfs-tempest&lt;/span&gt;&lt;/code&gt; CI-jobs to also test online volume
extend.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Nova support of the callback &lt;a class="footnote-reference brackets" href="#id15" id="id11" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit tests for the volume action will test the conditions all possible API
responses.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unit tests for &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;VolumeManager.extend_volume&lt;/span&gt;&lt;/code&gt; will test all the code paths
described in &lt;a class="reference internal" href="#volumemanager-extend-volume"&gt;VolumeManager.extend_volume&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The new volume action cannot be independently tested by Tempest, because it
requires the volume to be in a state that cannot be reproduced externally.
It is, however, covered by the existing tests for online volume extend when
they are run with one of the volume drivers that use this feature.
The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;devstack-plugin-nfs-tempest&lt;/span&gt;&lt;/code&gt; jobs that run as part of the Cinder and
Nova CI gates will be configured to enable online volume extend tests.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;The Block Storage API reference will be updated to include the new volume
action.&lt;/p&gt;
&lt;p&gt;The volume driver support matrix will be updated to show online resize support
for the affected drivers.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id12" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id5"&gt;2&lt;/a&gt;,&lt;a role="doc-backlink" href="#id9"&gt;3&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.opendev.org/c/openstack/cinder/+/739079"&gt;https://review.opendev.org/c/openstack/cinder/+/739079&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id13" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id6"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id8"&gt;2&lt;/a&gt;,&lt;a role="doc-backlink" href="#id10"&gt;3&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.opendev.org/c/openstack/nova-specs/+/855490/6"&gt;https://review.opendev.org/c/openstack/nova-specs/+/855490/6&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id14" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id7"&gt;3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.opendev.org/c/openstack/cinder-specs/+/864020"&gt;https://review.opendev.org/c/openstack/cinder-specs/+/864020&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id15" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id2"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id3"&gt;2&lt;/a&gt;,&lt;a role="doc-backlink" href="#id4"&gt;3&lt;/a&gt;,&lt;a role="doc-backlink" href="#id11"&gt;4&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.opendev.org/c/openstack/nova-specs/+/917133"&gt;https://review.opendev.org/c/openstack/nova-specs/+/917133&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Thu, 20 Jun 2024 00:00:00 </pubDate></item><item><title>Standardize Image Encryption and Decryption</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/2024.2/LUKS-image-encryption.html</link><description>

&lt;p&gt;OpenStack already has the ability to create encrypted volumes and ephemeral
storage to ensure the confidentiality of block data. Even though it is also
already possible to store encrypted images, there is only one service (Cinder)
that utilizes this option, but it is only indirectly usable by Nova (a user
must create a volume from the image first), and thus users don’t have an
intuitive way to create and upload encrypted images. In addition, all metadata
needed to detect and use encrypted images is either not present or specifically
scoped for Cinder right now. In conclusion, support for encrypted images does
exist to some extent but only in a non-explicit and non-standardized way. To
establish a consistent approach to image encryption for all OpenStack services
as well as users, several adjustments need to be implemented in Glance, Cinder
and OSC.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;An image, when uploaded to Glance or being created through Nova from an
existing server (VM), may contain sensitive information. The already provided
signature functionality only protects images against alteration. Images may be
stored on several hosts over long periods of time. First and foremost this
includes the image storage hosts of Glance itself. Furthermore it might also
involve caches on systems like compute hosts. In conclusion they are exposed to
a multitude of potential scenarios involving different hosts with different
access patterns and attack surfaces. The OpenStack components involved in those
scenarios do not protect the confidentiality of image data.&lt;/p&gt;
&lt;p&gt;Using encrypted storage backends for volume and compute hosts in conjunction
with direct data transfer from/to encrypted images can enable workflows that
never expose an image’s data on a host’s filesystem. Storage of encryption keys
on a dedicated key manager host ensures isolation and access control for the
keys as well.&lt;/p&gt;
&lt;p&gt;As stated in the introduction above, some disk image encryption implementations
for ephemeral disks in Nova and volumes in Cinder already touch on this topic
but not always in a standardized and interoperable way. For example, the way of
handling image metadata and encryption keys can differ. Furthermore, users
are not easily able to make use of these implementations when supplying their
own images in a way that encryption can work the same across services.&lt;/p&gt;
&lt;p&gt;That’s why we propose the introduction of a streamlined encrypted image format
along with well-defined metadata specifications which will be supported across
OpenStack services for the existing encryption implementations and increase
interoperability as well as usability for users.&lt;/p&gt;
&lt;section id="use-cases"&gt;
&lt;h3&gt;Use Cases&lt;/h3&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;1. A user wants to create a new volume based on an encrypted image. The
corresponding volume host has to be enabled to detect, that the image is
encrypted. Additionally encrypted images should always result in encrypted
volumes to avoid decryption.&lt;/div&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;1.1 If an encrypted image is the base for a new volume the used volume type
should always have an encryption type. If the given volume type or default
volume type does not have an encryption type the operation should result
in an ERROR.&lt;/div&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;div class="line"&gt;1.2 There are two possible types of encrypted images: qcow2 and raw images.
Cinder can already handle encrypted raw images. Encrypted qcow2 images
may need to be flattend to raw before transfering them into volumes.&lt;/div&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;div class="line"&gt;1.3 Encrypted images, that were created from encrypted volumes, may be
compressed depending on Cinder’s allow_compression_on_image_upload
option. This also needs to be handled when creating an encrypted volume
from such an image.&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;2. Whenever an encrypted image is converted to an encrypted volume the secret
should be copied to give Cinder full control over the life-cycle of the
secret.&lt;/div&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;2.1. The secret can be a key or a passphrase. The secret type
classification in the Key-Manager will determine the key handling
(“symmetric” vs “passphrase”).  Currently, Cinder is only able to handle
“symmetric”. Support for “passphrase” (like used in Nova) has to be added.&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;3. A user wants to create an image from a volume with an encrypted volume
type.  The target image will reuse the LUKS encryption and key. This use case
is already implemented as part of the default behavior of Cinder.&lt;/div&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;3.1. Creating an encrypted image from an unencrypted volume will not be
part of this spec, but may be implemented later on.&lt;/div&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;div class="line"&gt;3.2. Creating an unencrypted image from an encrypted volume is not possible
right now. The volume encryption is transparently also used for the image.
This behavior will stay in place to optimize resource usage and avoid costly
conversion of the whole volume data on volume hosts.&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;In Glance we propose the following additional metadata properties that should be
carried by encrypted images:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;‘os_encrypt_format’ - the main mechanism used, e.g. ‘LUKS’&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;‘os_encrypt_cipher’ - the cipher algorithm, e.g. ‘AES256’&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;‘os_encrypt_key_id’ - reference to secret in the key manager&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;‘os_encrypt_key_deletion_policy’ - on image deletion indicates whether the key
should be deleted too&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;‘os_decrypt_container_format’ - format change, e.g. from ‘compressed’ to
‘bare’&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;‘os_decrypt_size’ - size after payload decryption&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We propose to align the encryption with Nova and Cinder and use LUKS, which
will be allowed in combination with qcow and raw images. We use this two
versions for the following reasons:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Nova can directly use qcow-LUKS encrypted when creating a server. This is
the standard procedure of Nova.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cinder allows the creation of Images from encrypted volumes. These will
always result in LUKS-encrypted raw images. Those images can be converted
directly to volumes again.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In the latter case it is already possible to upload such an encrpyted image to
another OpenStack infrastructure, upload the key as well and set the
corresponding metadata. After doing so the image can be used in the second
infrastructure to create an encrypted volume.&lt;/p&gt;
&lt;p&gt;We want to align the existing implementations between Nova and Cinder by
standardizing the used metadata parameters and adding interoperability where
applicable. This would in the case of Cinder mainly be a rename:
- ‘cinder_encryption_key_deletion_policy’ to ‘os_encrypt_key_deletion_policy’
- ‘cinder_encryption_key_id’ to ‘os_encrypt_key_id’&lt;/p&gt;
&lt;p&gt;In the Volume creation there will be a check added, to look for encrypted
images proposed as a volume source. If an image is encrypted another check is
added to determine, whether the volume type to create the volume has an
encryption type. If that is not the case the volume create will be aborted in
the API still. Otherwise there will be an unusable volume created.&lt;/p&gt;
&lt;p&gt;The flattening of a qcow2 image should be handled when uploading the image to
the volume. The volume size should be resulting from the ‘os_decrypt_size’
parameter. If compression is enabled through Cinder’s
allow_compression_on_image_upload option Cinders implementation to handle this
should be re-used.&lt;/p&gt;
&lt;p&gt;The key management for creating an encrypted volume from an encrypted image
must include the copying of the secret in Barbican. On this way Cinder always
has the full control over the life-cycle of the secret, because this way is
similar to the original creation of an encrypted volume.&lt;/p&gt;
&lt;p&gt;In all places that use decryption within Cinder, there need to be an
additional check for the type of the secret. And a different handling, if the
secret is a “passphrase”, because the way Cinder treats keys to create a
passphrase for the LUKS header of a volume is quite unique and differs from
Nova’s handling of images, that have passphrases only.&lt;/p&gt;
&lt;p&gt;The creation of an image from an volume just need to be adjusted to use the new
parameters.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;We also evaluated an image encryption implementation based on GPG. The downside
with such an implementation is, that everytime such an image is used to create
a server or a volume the image has to be decrypted and maybe re-encrypted for
another encryption format as both Nova and Cinder use LUKS as an encryption
mechanism. This would not only have impact on the performance of the operation
but it also would need free space for the encrypted image file, the decrypted
parts and the encrypted volume or server that is created.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;When creating a volume from an encrypted image there might occure a new ERROR
that is triggered, when an image is encrypted but no encrypted volume type is
given.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;There are impacts on the security of OpenStack:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;confidentiality of data in images will be addressed in this spec&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;image encryption is introduced formally, thus cryptographic algorithms will
be used in all involved components (Nova, Cinder, OSC)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="active-active-ha-impact"&gt;
&lt;h3&gt;Active/Active HA impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Users should be able to use encrypted images to create volumes in a
consistant way&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;The proposed checks for the Cinder API may have minimal impact on performance.&lt;/p&gt;
&lt;p&gt;When creating a volume or server from an encrypted image the only operation
that may be triggerd is the conversion between qcow-LUKS and raw LUKS blocks.&lt;/p&gt;
&lt;p&gt;Thus, any performance impact is only applicable to the newly introduced
encrypted image type where the processing of the image will have increased
computational costs and longer processing times than regular images. Impact
will vary depending on the individual host performance and supported CPU
extensions for cipher algorithms.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;For interoperability between the OpenStack services only the presence of a
key manager should decide, whether encryption can be used or not.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A key manager - like Barbican - is required, if encrypted images are to be
used.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Primary assignee: Markus Hentsch (IRC: mhen)&lt;/p&gt;
&lt;p&gt;Other contributors: Josephine Seifert (IRC: Luzi)&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add checks in the create volume API&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add copying the secret and registering as a consumer in Barbican&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add flattening of qcow2 to raw encrypted images&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the image create from volume: change the
‘cinder_encryption_key_deletion_policy’ to ‘os_encrypt_key_deletion_policy’
and ‘cinder_encryption_key_id’ to ‘os_encrypt_key_id’&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Presence of the image encryption parameters in Glance has to be implemented&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Tempest tests would require access to encrypted images for testing. This means
that Tempest either needs to be provided with an image file that is already
encrypted and its corresponding key or needs to be able to encrypt images
itself. This point is still open for discussion.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;It should be documented for deployers, how to enable this feature in the
OpenStack configuration.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;[1] Barbican Secret Consumer Spec:
&lt;a class="reference external" href="https://review.opendev.org/#/c/662013/"&gt;https://review.opendev.org/#/c/662013/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[2] Glance Image Encryption Spec:
&lt;a class="reference external" href="https://review.opendev.org/c/openstack/glance-specs/+/915726"&gt;https://review.opendev.org/c/openstack/glance-specs/+/915726&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="history"&gt;
&lt;h2&gt;History&lt;/h2&gt;
&lt;table class="docutils align-default" id="id1"&gt;
&lt;caption&gt;&lt;span class="caption-text"&gt;Revisions&lt;/span&gt;&lt;/caption&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Release Name&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Dalmatian&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Introduced&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/section&gt;
</description><pubDate>Mon, 13 May 2024 00:00:00 </pubDate></item><item><title>User visible information in volume types</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/2024.2/user-visible-information-in-volume-types.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/user-visible-information-in-volume-types"&gt;https://blueprints.launchpad.net/cinder/+spec/user-visible-information-in-volume-types&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Volume types are used to find a fitting backend when creating a volume. But
they also imply a few configurations to the volume to be created, that are
good to know for anyone who has to choose from various volume types.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;When a non-admin user is creating a volume they would like to see various
information about the volume type. Some of those information are already
visible for users, when looking into a volume type (e.g. multiattach). Other
information are either not available at all or not visible for non-admin
users. This is a problem when trying to choose a fitting volume type when
creating a volume.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;The information users would like to see are first and foremost:
1. Whether a volume type can be used to create encrypted volumes
2. Whether a volume type creates replicated volumes, either through Cinder or
through a configured backend like ceph&lt;/p&gt;
&lt;p&gt;The first information comes from the encryption type within the volume, which
is only accessible for an admin. The second information can either be set and
directly seen in the volume type extra_specs or is indirectly a part of the
configuration of the backend.&lt;/p&gt;
&lt;p&gt;There might be more use cases, that should benefit from a solution allowing
an admin to add certain user facing information into the volume type in a
uniform way.&lt;/p&gt;
&lt;p&gt;As there are more and more tools that automatically create IaaS resources,
that information should be accessible in a uniform way and could best be used
to filter for fitting volume types in the client.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;To let an operator add information that is visible for users and also machine-
readable, we introduce a new field in the volume type object called “metadata”.
This will include API changes to address the new view of the volume type as
well as a new API endpoint to set information as key value pairs for this
metadata field. A new database table for those metadata is also necessary.&lt;/p&gt;
&lt;p&gt;The table will consist of columns for the volume type id, the key, the value,
an id as the primary key and metadata for creation, updates and deletion. The
upgrade path for the database may look like this:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;upgrade&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
  &lt;span class="n"&gt;op&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="s1"&gt;'volume_type_metadata'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'created_at'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'updated_at'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'deleted_at'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'deleted'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;primary_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="s1"&gt;'volume_type_id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
          &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ForeignKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
              &lt;span class="s1"&gt;'volume_types.id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'volume_type_metadata_ibfk_1'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="p"&gt;),&lt;/span&gt;
          &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'key'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
      &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'value'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
      &lt;span class="n"&gt;mysql_engine&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'InnoDB'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="n"&gt;mysql_charset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'utf8'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;In API there will be two fields: “extra_specs” and “metadata” and in CLI those
fields will be “properties” and “metadata”. The latter might confuse users, so
documentation is needed for both API and CLI to clarify, what to expect of each
field. The limit for this change is, that key-value pairs not meant for
scheduling purposes can still be put into the properties/extra_specs and will
lead to Errors in the scheduling process later on.&lt;/p&gt;
&lt;p&gt;In a second phase metadefs can be added to standardize certain keys like
“encryption_type” or “replicated”.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;We evaluated using the already existing user facing “extra_specs” field.
Administrators can already set key-value pairs here and user visible
extra_specs can be seen in this field. But this would lead to a problem in the
volume scheduler, as EVERY input in the extra_specs table will be evaluated by
the scheduler when looking for a fitting backend for the volume. While this
problem could be solved through a whitelisting or blacklisting approach,
maintaining and evaluating such lists is very opaque for users. Overall
this approach may lead to even more confusion in users.&lt;/p&gt;
&lt;p&gt;Another option is to face use cases individually:&lt;/p&gt;
&lt;p&gt;1. Information about whether a volume type creates encrypted volumes or not
could be calculated in the API calls for list/show volume types from the
presence of an encryption type. The information would be shown in the
“properties” field. This would be a very minimal patch, but will not solve
other use cases, that would benefit from user facing information.
2. Creating an extra field for the encryption in the volume type table, that
is automatically set when creating or deleting an encryption type. This
would need a database change and a change of the view of the volume_types.
3. Looking into the different drivers and how they handle internal
configurable replication and whether there are ways to let OpenStack know
this and propagate it to users. This is very hard to achieve, maybe even
impossible without input from an operator, who configured the backends and
volume types.
4. The policy for the encryption type could be loosend to let users see not
only whether a volume type has an encryption type, but also what algorithm
and provider is used for it. This may have a security impact.&lt;/p&gt;
&lt;p&gt;All these options are not able to solve the general issue of having a
reliable way to provide user visible information in volume types. Neither will
they solve the problem, that operators are able to add key-value pairs not
meant for scheduling purposes to the volume type extra specs.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;It will be necessary to create a new table &lt;cite&gt;metadata&lt;/cite&gt; that works like the
&lt;cite&gt;extra_specs&lt;/cite&gt; table. As there are currently no user visible information in
volume types in place, an initially empty table would be sufficient.&lt;/p&gt;
&lt;p&gt;To adhere the case of an upgrade from a previous OpenStack version, all volume
types need to be checked and for volume types with associated encryption types,
there need to be an encryption parameter set in the database according to the
chosen option. This should not be doable through an API call but will need
direct DB access, as changing the metadata of volume types in use should be
prohibited.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;A new field needs to be added to the view of volume types. For that field new
API calls will be needed:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;a POST method to set new key-value pairs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;a DELETE method to delete a key-value pair.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;optionally a GET method to show a key-value pair.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;optionally add filtering for certain metadata for the GET volume types method&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The volume type metadata will be handled like the volume type description, that
is, we will allow it to be modified even if the volume-type is in use. We can
do this because the volume type metadata is only descriptive, as opposed to the
volume-type extra_specs that affect the scheduler.&lt;/p&gt;
&lt;p&gt;Additionally the create volume type API call should be able to handle key-value
pairs for the new metadata field.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;This change will expose a boolean value, that shows, whether a volume type
will encrypt volumes at creation or not.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="active-active-ha-impact"&gt;
&lt;h3&gt;Active/Active HA impact&lt;/h3&gt;
&lt;p&gt;There should not be any impact upon Cinder’s Active/Active HA support.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;There will be additional notifications when database entries are made or
removed. They will behave the same way as the notifications of extra_specs.
Those will be sent, whenever a key-value pair is created or deleted from the
new metadata field/database.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;This change may lead to users wanting to use the filtering mechanism in
&lt;cite&gt;openstack volume type list –metadata key=value&lt;/cite&gt; for both explained use
cases.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;The API call for getting volume types and their details will have an additional
query for the new metadata table.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;Old volume types with associated encryption types will need to have the
potentially new database entry set. This cannot be done via &lt;cite&gt;volume type set&lt;/cite&gt;
command, but has to be written into the database either manually or with a
script, that sets the correct entry for all affected volume types.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Josephine Seifert (josei)&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;None&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add a “volume_type_metadata” table to the Cinder database&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add new API-Endpoints for the metadata field of volume types and add new
possibility to create new key-value pairs in the metadata field when
creating a volume type&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add support in CLI/SDK for the new API calls&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;There are no dependencies.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;The test case for creating a volume type may be updated to integrate the
addition of a metadata key-value pair.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;There will be a documentation needed to separate between the extra specs
and the handling of user visible information.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://lists.openstack.org/archives/list/openstack-discuss@lists.openstack.org/thread/PP7IMXVOO2SM47JRMDYYVB2IA3XIEZD5/"&gt;Mailing list discussion&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://etherpad.opendev.org/p/cinder-caracal-midcycles#L93"&gt;Discussion in the Cinder Midcycle&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Fri, 16 Feb 2024 00:00:00 </pubDate></item><item><title>No specs were approved for the 2023.1 release.</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/2023.1/placeholder.html</link><description>

</description><pubDate>Thu, 07 Dec 2023 00:00:00 </pubDate></item><item><title>New Quota System</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/2024.1/quota-system.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/count-resource-to-check-quota"&gt;https://blueprints.launchpad.net/cinder/+spec/count-resource-to-check-quota&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Cinder quotas have been a constant pain for operators and cloud users. This
spec proposes a new quota system to resolve inconsistencies in tracking quota
usage.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Cinder’s current quota system is based on reservations and commits/rollbacks.
When the API receives an operation that consumes quota, the request is
validated and Cinder checks that there’s enough quota to perform the operation,
and finally creates reservations to ensure that this quota is not consumed by
other operations. Then when the operation finishes these reservations are
committed as used resources or rolled back if the operation failed.&lt;/p&gt;
&lt;p&gt;The current usage and reservations for resources, e.g. number of volumes or
gigabytes, are tracked in the database as a counter in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;quota_usages&lt;/span&gt;&lt;/code&gt;
table, so if for whatever reason this counter doesn’t match the real usage,
then users may become unable to create new resources or able to create
resources beyond their project limits.&lt;/p&gt;
&lt;p&gt;There are many possible reasons why resource tracking can become out of sync in
Cinder, including bugs in the code and services dying during an operation.&lt;/p&gt;
&lt;p&gt;As a workaround for quotas becoming out of sync, the Cinder service has code to
make reservations expire after a given time and also has the possibility of
resynching the quotas with a certain frequency.&lt;/p&gt;
&lt;p&gt;Besides the impact on operators and users, the current quota implementation
also has an impact on developers, because the system of reserve/commit and
resource counting in the database has the downside of having to be very
thorough in order to always keep track of everything, making the quota system a
very manual and tedious process to code, which in turn results in hard to find
bugs, since we don’t know at which point the counting went wrong.&lt;/p&gt;
&lt;p&gt;Low level implementation details of the current quota system are also present
&lt;em&gt;everywhere&lt;/em&gt; in Cinder, and almost every single area of the code needs to be
aware of the low level implementation details, making the code very verbose and
obscuring the high level logic.&lt;/p&gt;
&lt;p&gt;As an example, we can look at the code of the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;accept&lt;/span&gt;&lt;/code&gt; method of the transfer
api in file &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cinder/transfer/api.py&lt;/span&gt;&lt;/code&gt;, where, at the time of this writing, out
of the 106 lines of code that constitute the method, 70 are quota related!&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;A cloud administrator wants to prevent system capacities from being exhausted
without notification so it limits quota systems based on the deployments
capabilities.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A cloud administrator wants to limit how many resources each department can
consume.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A Cinder contributor wants to add a new feature that creates or destroys
resources, so it needs to write code to manage the quota.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;This spec proposes a new quota system where most low level quota details will
be hidden from developers working on features, simplifying feature development
and the chances of introducing new bugs.&lt;/p&gt;
&lt;p&gt;This quota system will support 2 different drivers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;StoredQuotaDriver&lt;/span&gt;&lt;/code&gt;:  This will be similar to the old system, using
counters in the DB, but instead of doing reservations and commits/rollbacks
for every resource modification, it will only do reservations for the very
few operations that really need it to keep track of the resources while the
operation is in progress.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DynamicQuotaDriver&lt;/span&gt;&lt;/code&gt;: This driver will no longer store usage and resource
tracking in the database table (&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;quota_usages&lt;/span&gt;&lt;/code&gt;) and instead dynamically
calculates each quota check based on the resources that exist in the
database.&lt;/p&gt;
&lt;p&gt;Calculations will be counting for resources (e.g. &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;snapshots&lt;/span&gt;&lt;/code&gt;) or sum of
values for sizes (e.g. &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;gigabytes&lt;/span&gt;&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;Just like the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;StoredQuotaDriver&lt;/span&gt;&lt;/code&gt; driver this will use reservations as
little as possible.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The reason for having 2 drivers instead of a single one is because there are
trade-offs with each of the drivers, and the default will be the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DynamicQuotaDriver&lt;/span&gt;&lt;/code&gt; driver, for reasons explained later in the
&lt;a class="reference internal" href="#performance-impact"&gt;Performance Impact&lt;/a&gt; section.&lt;/p&gt;
&lt;p&gt;The changes will try, as much as possible, to avoid over engineering the
solution focusing on the 2 new drivers and current cinder and not solve all
cases for potential different drivers that will probably never come.&lt;/p&gt;
&lt;section id="quota-limits"&gt;
&lt;h3&gt;Quota limits&lt;/h3&gt;
&lt;p&gt;In the original implementation of quota classes (&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;quota_classes&lt;/span&gt;&lt;/code&gt; database
table) it was mentioned the possibility of supporting different classes besides
the existing &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;default&lt;/span&gt;&lt;/code&gt;, and being able to pass it via the context, but more
than 9 years after its implementation neither Nova nor Cinder support it, so
this new quota system and drivers will just focus on the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;default&lt;/span&gt;&lt;/code&gt; quota
class, which will be referred as &lt;em&gt;system wide defaults&lt;/em&gt;, &lt;em&gt;global defaults&lt;/em&gt;,
&lt;em&gt;global limits&lt;/em&gt;, or just &lt;em&gt;defaults&lt;/em&gt; since the term is easier to understand.&lt;/p&gt;
&lt;p&gt;Limits from the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;quotas&lt;/span&gt;&lt;/code&gt; table will be referred as &lt;em&gt;per project limits&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The effective quota limits that apply to a specific project after considering
the global and per project limits will be referred simply as &lt;em&gt;quota limits&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The way quota limits are calculated will be kept as they are now:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;System wide quota limit defaults are stored in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;quota_classes&lt;/span&gt;&lt;/code&gt; table
under the records that have the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;default&lt;/span&gt;&lt;/code&gt; value in their &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;class_name&lt;/span&gt;&lt;/code&gt;
column.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Per project quota limit overrides that replace the system wide limits are
optional and will be stored in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;quotas&lt;/span&gt;&lt;/code&gt; table.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;hard_limit&lt;/span&gt;&lt;/code&gt; value of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;-1&lt;/span&gt;&lt;/code&gt; indicates that there are no limits.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="resources"&gt;
&lt;h3&gt;Resources&lt;/h3&gt;
&lt;p&gt;The new quota system will not introduce or remove any of the existing quota
resources, so available resources for the quota limits will still be:
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volumes&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volumes_&amp;lt;volume-type&amp;gt;&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;snapshots&lt;/span&gt;&lt;/code&gt;,
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;snapshots_&amp;lt;volume-type&amp;gt;&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;gigabytes&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;gigabytes_&amp;lt;volume-type&amp;gt;&lt;/span&gt;&lt;/code&gt;,
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;backups&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;backup_gigabytes&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;groups&lt;/span&gt;&lt;/code&gt;, and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;per_volume_gigabytes&lt;/span&gt;&lt;/code&gt;.
And quota usage will report in-use and reserved values for all existing limits
except the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;per_volume_gigabytes&lt;/span&gt;&lt;/code&gt;, since there cannot be any usage for it.&lt;/p&gt;
&lt;p&gt;Reservation values will be stored in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;delta&lt;/span&gt;&lt;/code&gt; field of the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;reservations&lt;/span&gt;&lt;/code&gt; table just like they are today.&lt;/p&gt;
&lt;p&gt;For the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DynamicQuotaDriver&lt;/span&gt;&lt;/code&gt; these values will be dynamically added,
grouping by &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;resource&lt;/span&gt;&lt;/code&gt; for non deleted rows belonging to the specific
project.  On the other hand the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;StoredQuotaDriver&lt;/span&gt;&lt;/code&gt; will track the sum in
the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;reserved&lt;/span&gt;&lt;/code&gt; field of the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;quota_usages&lt;/span&gt;&lt;/code&gt; table.&lt;/p&gt;
&lt;p&gt;Both drivers will adhere to the following rules when reporting in-use values:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volumes&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volumes_&amp;lt;volume-type&amp;gt;&lt;/span&gt;&lt;/code&gt; quotas must match the number of non
deleted rows in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volumes&lt;/span&gt;&lt;/code&gt; table, with the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;use_quota&lt;/span&gt;&lt;/code&gt; field set to
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;true&lt;/span&gt;&lt;/code&gt; plus the sum of positive values from the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;reservations&lt;/span&gt;&lt;/code&gt; table
where the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;resource&lt;/span&gt;&lt;/code&gt; matches &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volumes&lt;/span&gt;&lt;/code&gt; or &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volumes_&amp;lt;volume-type&amp;gt;&lt;/span&gt;&lt;/code&gt;, in
both cases only those values belonging to the specific project.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;snapshots&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;snapshots_&amp;lt;volume-type&amp;gt;&lt;/span&gt;&lt;/code&gt; quotas must match the number of
non deleted rows in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;snapshots&lt;/span&gt;&lt;/code&gt; table, with the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;use_quota&lt;/span&gt;&lt;/code&gt; field set
to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;true&lt;/span&gt;&lt;/code&gt;, and belonging to the specific project.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;gigabytes&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;gigabytes_&amp;lt;volume_type&amp;gt;&lt;/span&gt;&lt;/code&gt; quotas must match the sum of
the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;size&lt;/span&gt;&lt;/code&gt; of the quotable volumes (as defined above) incremented in the
sum of the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volume_size&lt;/span&gt;&lt;/code&gt; values of the quotable snapshots (as defined
above) when the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;no_snapshot_gb_quota&lt;/span&gt;&lt;/code&gt; configuration option is set to
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;false&lt;/span&gt;&lt;/code&gt; (default value) plus the sum of positive values from the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;reservations&lt;/span&gt;&lt;/code&gt; table where the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;resource&lt;/span&gt;&lt;/code&gt; matches &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;gigabytes&lt;/span&gt;&lt;/code&gt; or
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;gigabytes_&amp;lt;volume-type&amp;gt;&lt;/span&gt;&lt;/code&gt;, in both cases only those values belonging to the
specific project.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;groups&lt;/span&gt;&lt;/code&gt; quota must match the number of non deleted rows in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;groups&lt;/span&gt;&lt;/code&gt;
table.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;backups&lt;/span&gt;&lt;/code&gt; quota must match the number of non deleted rows in the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;backups&lt;/span&gt;&lt;/code&gt; table, and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;backup_gigabytes&lt;/span&gt;&lt;/code&gt; must match the sum of their
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;size&lt;/span&gt;&lt;/code&gt; values.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;per_volume_gigabytes&lt;/span&gt;&lt;/code&gt; is a quota limit that doesn’t need any kind of
calculation.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="mechanism"&gt;
&lt;h3&gt;Mechanism&lt;/h3&gt;
&lt;p&gt;The new quota system will rely heavily on database transactions and database
row locking using the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;SELECT&lt;/span&gt; &lt;span class="pre"&gt;FOR&lt;/span&gt; &lt;span class="pre"&gt;UPDATE&lt;/span&gt;&lt;/code&gt; SQL statement to control parallel
operations and ensure quota limits are honored and &lt;strong&gt;all&lt;/strong&gt; database changes
happen or they are automatically rolled back.&lt;/p&gt;
&lt;p&gt;A high level view of how this mechanism would work is:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Start a transaction&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Get current quota limits creating a lock on those rows&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Check operation doesn’t go over quota&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create the resource on the database or make reservations&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finish the transaction releasing the lock&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The lock will only happen on the rows of the resources we are interested in,
allowing operations on other projects and resources to be executed in parallel.
For example, quota checks to create a volume will lock rows for &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volumes&lt;/span&gt;&lt;/code&gt;,
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volumes_&amp;lt;volume-type&amp;gt;&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;gigabytes&lt;/span&gt;&lt;/code&gt;, and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;gigabytes_&amp;lt;volume-type&amp;gt;&lt;/span&gt;&lt;/code&gt;, so
cinder will be able to check for the quota to create a backup since that only
requires &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;backup&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;backup_gigabytes&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The new system will leverage Python context manager functionality and the Oslo
DB transaction context provider available in the Cinder &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;RequestContext&lt;/span&gt;&lt;/code&gt;
(&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;context.session&lt;/span&gt;&lt;/code&gt;) to facilitate the sharing of the transaction/session
between different areas of the Cinder code.&lt;/p&gt;
&lt;p&gt;This will allow developers to write cleaner code, for example when creating a
volume, the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;create&lt;/span&gt;&lt;/code&gt; method of the Cinder &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Volume&lt;/span&gt;&lt;/code&gt; Oslo object will have to
check that it can create 1 volume, that will consume additional gigabytes and
that the size of the volume doesn’t exceed the largest volume size allowed, so
the code will be something like this:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quota_check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;volume_type&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="n"&gt;vol_gbs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="n"&gt;vol_qty&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="n"&gt;vol_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

   &lt;span class="n"&gt;db_volume&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;volume_create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;updates&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;quota_check&lt;/span&gt;&lt;/code&gt; is a property in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Volume&lt;/span&gt;&lt;/code&gt; OVO that returns a context
manager that ensures quota limits are honored.  Returned context manager
depends on whether the volume consumes quota or not, returning a &lt;em&gt;noop&lt;/em&gt; if it
doesn’t and returning a context manager provided by the quota driver if it
does.&lt;/p&gt;
&lt;p&gt;The quota driver context manager starts a DB session/transaction in the
provided &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;context&lt;/span&gt;&lt;/code&gt; so the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volume_create&lt;/span&gt;&lt;/code&gt; call will use that same session
to create the volume record, and the transaction will be finalized when the
code exits the context manager, thus ensuring that no other operations check
the quota until the volume has been created.&lt;/p&gt;
&lt;p&gt;From a developer’s point of view all this will be hidden, because at a higher
level all they need to do is create the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Volume&lt;/span&gt;&lt;/code&gt; OVO and the quota will be
automatically checked.  As an example this is the code in the create volume
flow (&lt;em&gt;cinder/volume/flows/api/create_volume.py&lt;/em&gt;):&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;volume&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Volume&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;volume_properties&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;volume&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;In an effort to abstract the quota system implementation and hide its details
from most of the code, the code interfacing with the driver directly will no
longer use the resource names such as &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;gigabytes&lt;/span&gt;&lt;/code&gt; and
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volumes_&amp;lt;volume-type&amp;gt;&lt;/span&gt;&lt;/code&gt;, instead the parameters that will be used for the
volume and snapshot context manager checker are:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vol_qty&lt;/span&gt;&lt;/code&gt;: Delta on the number of volumes that will be consumed within the
checker context manager.  The quota system internal name for this is
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volumes&lt;/span&gt;&lt;/code&gt; in the database.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vol_type_vol_qty&lt;/span&gt;&lt;/code&gt;: Delta on the number of volumes for the specific volume
type that will be consumed within the checker context manager.  Defaults to
the value of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vol_qty&lt;/span&gt;&lt;/code&gt; since that’s the most common case. The quota system
internal name for this is &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volumes_&amp;lt;volume-type&amp;gt;&lt;/span&gt;&lt;/code&gt; in the database.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vol_gbs&lt;/span&gt;&lt;/code&gt;: Delta on the number of volume gigabytes that will be consumed
within the checker context manager.  The quota system internal name for this
is &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;gigabytes&lt;/span&gt;&lt;/code&gt; in the database.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vol_type_gbs&lt;/span&gt;&lt;/code&gt;: Delta on the number of volume gigabytes for the specific
volume type that will be consumed within the checker context manager.
Defaults to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vol_gbs&lt;/span&gt;&lt;/code&gt; since that’s the most common case. The quota system
internal name for this is &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;gigabytes_&amp;lt;volume-type&amp;gt;&lt;/span&gt;&lt;/code&gt; in the database.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;snap_qty&lt;/span&gt;&lt;/code&gt;: Delta on the number of snapshots that will be consumed within
the checker context manager.  The quota system internal name for this is
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;snapshots&lt;/span&gt;&lt;/code&gt; in the database.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;snap_type_qty&lt;/span&gt;&lt;/code&gt;: Delta on the number of snapshots for the specific volume
type that will be consumed within the checker context manager.  Defaults to
the value of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;snap_qty&lt;/span&gt;&lt;/code&gt; since that’s the most common case. The quota
system internal name for this is &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;snapshots_&amp;lt;volume-type&amp;gt;&lt;/span&gt;&lt;/code&gt; in the database.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;snap_gbs&lt;/span&gt;&lt;/code&gt;: Delta on the number of snapshot gigabytes that will be consumed
within the checker context manager.  Will end up using the quota system
internal name of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;gigabytes&lt;/span&gt;&lt;/code&gt; if the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;no_snapshot_gb_quota&lt;/span&gt;&lt;/code&gt; configuration
option is set to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;false&lt;/span&gt;&lt;/code&gt; (default) or will be disregarded if set to
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;true&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;snap_type_gbs&lt;/span&gt;&lt;/code&gt;: Delta on the number of snapshot gigabytes for the specific
volume type that will be consumed within the checker context manager.
Defaults to the value of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;snap_gbs&lt;/span&gt;&lt;/code&gt; since that’s the most common case.
The quota system internal name for this is &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;gigabytes_&amp;lt;volume_type&amp;gt;&lt;/span&gt;&lt;/code&gt; in the
database if the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;no_snapshot_gb_quota&lt;/span&gt;&lt;/code&gt; configuration option is set to
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;false&lt;/span&gt;&lt;/code&gt; or will be disregarded if set to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;true&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vol_size&lt;/span&gt;&lt;/code&gt;: Total volume size when creating or extending it, in the
internally the quota system uses the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;per_volume_gigabytes&lt;/span&gt;&lt;/code&gt; quota limit to
check this value.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This change may seem worthless, but it has its value, because it abstracts the
implementation details of the snapshots and volumes sharing the same quota size
limits which provides:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Cleaner code since snapshot creation or transfer of a volume with snapshots
doesn’t need to know about the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;no_snapshot_gb_quota&lt;/span&gt;&lt;/code&gt; configuration option.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If we want to add, in the future, snapshot specific quota limits -
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;snapshot_gigabytes&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;snapshot_gigabytes_&amp;lt;volume-type&amp;gt;&lt;/span&gt;&lt;/code&gt;- we’ll be
able to do so without affecting any of the Cinder code with the sole
exception of the quota driver itself.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="reservations"&gt;
&lt;h3&gt;Reservations&lt;/h3&gt;
&lt;p&gt;For the new quota system the reservation commit and rollback operations will be
grouped into a single context manager that handles both cases.  Committing and
rolling back reservations have different meanings for the 2 drivers.&lt;/p&gt;
&lt;p&gt;For the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DynamicQuotaDriver&lt;/span&gt;&lt;/code&gt; these are &lt;em&gt;noop&lt;/em&gt; operations, since checks use
the DB values every time and the database has already been modified in the
same transaction that the reservations are removed.  On the other hand the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;StoredQuotaDriver&lt;/span&gt;&lt;/code&gt; needs to modify the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;in_use&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;reserved&lt;/span&gt;&lt;/code&gt; counters
in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;quota_usages&lt;/span&gt;&lt;/code&gt; table accordingly to the operation.&lt;/p&gt;
&lt;p&gt;As mentioned before, reservations will only be necessary for specific
operations, to be exact on 3 operations: extend, transfer, and retype.&lt;/p&gt;
&lt;p&gt;Each of these operations have different reasons for requiring reservations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Extend: Until the operations completes, the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;size&lt;/span&gt;&lt;/code&gt; field of the volume in
the database must be kept as it is to reflect its real value, but we need to
reserve the additional gigabytes, for &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;gigabytes&lt;/span&gt;&lt;/code&gt; and
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;gigabytes_&amp;lt;volume_type&amp;gt;&lt;/span&gt;&lt;/code&gt; quotas, during the operation so we don’t go over
quota due to other concurrent operations.  If the operation completes
successfully the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;size&lt;/span&gt;&lt;/code&gt; of the volume will be increased and the
reservations will be committed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Transfer: Under normal circumstances accepting a transfer would not require
the use of a reservation, as we should be able to check the quota and do the
database changes to accept the transfer in the same transaction.
Unfortunately the &lt;em&gt;SolidFire&lt;/em&gt; and &lt;em&gt;VMDK&lt;/em&gt; drivers need to make some changes in
their backend on transfer, so the volume service has to make a driver call.&lt;/p&gt;
&lt;p&gt;We cannot keep the database locked while the driver call completes, as it can
take some time and we don’t want to prevent the API from processing other
operations.&lt;/p&gt;
&lt;p&gt;That is why reservations will be created before calling the driver and
cleared after accepting the resources.&lt;/p&gt;
&lt;p&gt;In terms of reservations, transfers are complex for the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;StoredQuotaDriver&lt;/span&gt;&lt;/code&gt;, because when completing one it needs to modify 2
different projects.  One to increase counters and the other to decrease them,
so higher levels will need to make 2 different calls for 2 different
projects, one with positive and one with negative numbers and negative
numbers should ignore quota usage and limits.&lt;/p&gt;
&lt;p&gt;When storing reservations for transfer of volumes with snapshots they have
to be stored separately in case someone restarts the service after changing
the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;no_snapshot_gb_quota_toggled&lt;/span&gt;&lt;/code&gt; configuration option as detailed in the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vol_snap_check_and_reserve_cm&lt;/span&gt;&lt;/code&gt; method below.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Retype: When doing a retype the API needs to reserve
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;gigabytes_&amp;lt;dest-volume-type&amp;gt;&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volumes_&amp;lt;dest-volume-type&amp;gt;&lt;/span&gt;&lt;/code&gt; until the
operation is completed as well as create negative reservations for
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;gigabytes_&amp;lt;source-volume-type&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volumes_&amp;lt;source-volume-type&amp;gt;&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This consumes volumes and gigabytes on both types until the operation
completes for the following reasons:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;If the retype fails we will continue consuming volumes and gigabytes on the
source volume type, but if we “released” that usage when we started the
operation we may find that there is no longer enough quota available for
the volume to stay there.  This is the main reason.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Even if the retype succeeds Cinder doesn’t know the reasons why the cloud
administrator has set the quota limits, so freeing the source gigabytes and
volumes as soon as the retype starts means that if a new volume for the
source type is created during the retype Cinder will be exceeding the quota
for that volume type.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is the only operation where a race condition can happen, though it’s a
corner case.  It can happen if we are adding a new quota limit, global or per
project, to a volume type resource (e.g. &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volume_&amp;lt;volume_type&amp;gt;&lt;/span&gt;&lt;/code&gt;) that
didn’t have any limit in the database while at the same time we are doing
volume retypes to that same volume type.  This race should fall within
reasonable expectations, as one would argue that the limit was added right
after the retype already passed the quota check.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It is possible that while doing an operation on a resource the code flow
doesn’t complete in an unexpected way leaving leftover reservations in the
database, for example:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;A coding bug in Cinder that leaves the volume in an unexpected status.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Service kill.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Node restart or shutdown.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For these situations the new quota system will add code to the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;os-reset_status&lt;/span&gt;&lt;/code&gt; REST API action on volumes to automatically clear any
reservations that the volume may have when the status is changed, which is what
happens when a volume is stuck in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;extending&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;retyping&lt;/span&gt;&lt;/code&gt;, etc.  This way
there is no need to wait until the reservation expires and the operator can do
the cleanup in an easy way without needing additional API calls.&lt;/p&gt;
&lt;p&gt;On volume deletion the code will also clear any existing reservations on the
specific volume.&lt;/p&gt;
&lt;p&gt;To facilitate the cleanup of these reservations the volume’s id will be used as
the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;uuid&lt;/span&gt;&lt;/code&gt; field for all the reservations, instead of creating a random one,
regardless of the value of the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;resource&lt;/span&gt;&lt;/code&gt; field in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;reservations&lt;/span&gt;&lt;/code&gt;
table.&lt;/p&gt;
&lt;p&gt;Both drivers will create reservations the same way to facilitate switching the
drivers without having usage numbers go out of sync.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="changing-configuration"&gt;
&lt;h3&gt;Changing configuration&lt;/h3&gt;
&lt;p&gt;There are 2 Cinder configuration options that are crucial for the new quota
system to operate correctly: &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;quota_driver&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;no_snapshot_gb_quota&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;no_snapshot_gb_quota&lt;/span&gt;&lt;/code&gt; configuration option is used to determine whether
snapshots should be counted towards the volume quota or not, so this is not
something we want to be counting in some places and not counting in others; we
want a consistent behaviour through &lt;strong&gt;all&lt;/strong&gt; the Cinder services, which means
that they must have the same value.&lt;/p&gt;
&lt;p&gt;Currently Cinder has no way of enforcing the same value for the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;no_snapshot_gb_quota&lt;/span&gt;&lt;/code&gt;, and what’s worse, it cannot even know when the
current quota calculations have become invalid because this configuration
option has changed (&lt;a class="reference external" href="https://bugs.launchpad.net/cinder/+bug/1952635"&gt;Bug #1952635&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;This is something we definitely don’t want in the quota system, and with the
new quota system we have bigger problems, because it’s not only
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;no_snapshot_gb_quota&lt;/span&gt;&lt;/code&gt; that can be changed, but also &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;quota_driver&lt;/span&gt;&lt;/code&gt;, and
changing the quota driver means that a quota system may need to recalculate
things to ensure that it starts operating with the correct quota assumptions.
For example when changing from the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DynamicQuotaDriver&lt;/span&gt;&lt;/code&gt; to the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;StoredQuotaDriver&lt;/span&gt;&lt;/code&gt; all the counters in the DB will be wrong, so the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;StoredQuotaDriver&lt;/span&gt;&lt;/code&gt; needs to calculate the counters before it can start
working or the whole quota system will not operate correctly.&lt;/p&gt;
&lt;p&gt;These configuration options are not the kind of things that are frequently
changed, and we expect most deployments to never have to change them at all,
but Cinder should still provide a way for them to be safely changed since one
of the cases we expect to happen is a deployment outgrowing the usefulness of
the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DynamicQuotaDriver&lt;/span&gt;&lt;/code&gt; and running into performance issues.  In that case
they will want to switch to the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;StoredQuotaDriver&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To support changing configuration option changes to the quota system there are
3 things that the new quota system needs to be able to do:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Detect changes in configuration options.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Signal drivers that the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;no_snapshot_gb_quota&lt;/span&gt;&lt;/code&gt; configuration option has
changed and for driver to react to this change.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Signal drivers that they were not the quota driver that was running on the
last start and they should see if they need to do some calculations.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To detect changes to these configuration options, a new &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;global_data&lt;/span&gt;&lt;/code&gt; table
will be created to store the currently used configuration values.  This table
will be used to signal quota drivers when things have changed.&lt;/p&gt;
&lt;p&gt;A system administrator will have to follow these steps to change any of these 2
configuration options:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Stop all Cinder services.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Change the cinder.conf file in all the nodes where a Cinder service is
running.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Run a cinder-manage command to apply the changed options.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Restart Cinder services.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The cinder-manage command will not only trigger the quota system
recalculations, but it will also make the appropriate DB changes in the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;global_data&lt;/span&gt;&lt;/code&gt; table to reflect the new configuration options that are in
effect.&lt;/p&gt;
&lt;p&gt;Since we cannot allow Cinder services to run with mismatching configuration
options they will fail to start if the quota configuration options from the
database don’t match the one that the service has.  This will prevent system
administrators making an error and only realize it after their whole system has
some crazy quotas.&lt;/p&gt;
&lt;p&gt;Please see the &lt;a class="reference internal" href="#changing-configuration-alternatives"&gt;Changing configuration alternatives&lt;/a&gt; for other possible
mechanism to the one proposed here.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="interface"&gt;
&lt;h3&gt;Interface&lt;/h3&gt;
&lt;p&gt;Here is the proposed interface for the new quota system drivers:&lt;/p&gt;
&lt;section id="name"&gt;
&lt;h4&gt;NAME&lt;/h4&gt;
&lt;p&gt;Unique string of maximum 254 ASCII characters that identifies the driver.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="init"&gt;
&lt;h4&gt;__init__&lt;/h4&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;driver_switched&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;no_snapshot_gb_quota_toggled&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Initialization method for the quota driver where the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;driver_switched&lt;/span&gt;&lt;/code&gt;
parameter indicates whether the last run was done using the same Quota driver
or if a different one was used and this is the first run with this one.&lt;/p&gt;
&lt;p&gt;This is important because switching to the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;StoredQuotaDriver&lt;/span&gt;&lt;/code&gt; from the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DynamicQuotaDriver&lt;/span&gt;&lt;/code&gt; means that &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;in-use&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;reserved&lt;/span&gt;&lt;/code&gt; counters need to
be recalculated since they could be out of sync or missing altogether.&lt;/p&gt;
&lt;p&gt;This effort is going to focus on only supporting these 2 quota drivers and
avoid unnecessary complexity, because if we wanted to support other kind of
drivers that were not based on the Cinder database we would need to add a more
complex mechanism, since the cinder code would need to notify drivers when the
limits are changed in the DB and there would need to be a way for Cinder to
request information from the old quota driver, such as current reservations,
when switching.&lt;/p&gt;
&lt;p&gt;The interface can be enhanced if a future quota driver finds it insufficient.&lt;/p&gt;
&lt;p&gt;The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;no_snapshot_gb_quota_toggled&lt;/span&gt;&lt;/code&gt; parameter indicates whether the option has
changed since the last run.  This is important for the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;StoredQuotaDriver&lt;/span&gt;&lt;/code&gt;
that would need to recalculate &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;in-use&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;reserved&lt;/span&gt;&lt;/code&gt; counters.  This is
something that doesn’t work correctly right now.&lt;/p&gt;
&lt;p&gt;Drivers can block the Cinder database when synchronizing when the driver has
been switched or the snapshot quota configuration option has been toggled,
because the driver will only be called with any of the parameters set to
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;True&lt;/span&gt;&lt;/code&gt; on a single service in the deployment and the quota will not be in use
at that time by any other service.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="resync"&gt;
&lt;h4&gt;resync&lt;/h4&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;resync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This is only relevant for the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;StoredQuotaDriver&lt;/span&gt;&lt;/code&gt;, and is intended to allow
the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cinder-manage&lt;/span&gt;&lt;/code&gt; command request a recalculation of quotas for a specific
project or for the whole deployment.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="set-defaults"&gt;
&lt;h4&gt;set_defaults&lt;/h4&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;set_defaults&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;defaults&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Set system wide default limits.&lt;/p&gt;
&lt;p&gt;The keys for the keyword arguments &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;defaults&lt;/span&gt;&lt;/code&gt; are in the internal form of the
quota system, that is to say, they will be &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;gigabytes&lt;/span&gt;&lt;/code&gt; and not
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vol_gbs&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This will be a common implementation for both database based quota drivers,
where it modifies the record if it exists and creates it if it doesn’t.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="set-limits"&gt;
&lt;h4&gt;set_limits&lt;/h4&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;set_limits&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;limits&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Set project specific limits.&lt;/p&gt;
&lt;p&gt;The keys for the keyword arguments &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;limits&lt;/span&gt;&lt;/code&gt; are in the internal form of the
quota system, that is to say, they will be &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;gigabytes&lt;/span&gt;&lt;/code&gt; and not &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vol_gbs&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This will be a common implementation for both database based quota drivers,
where it modifies the record if it exists and creates it if it doesn’t.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="clear-limits-and-defaults-cm"&gt;
&lt;h4&gt;clear_limits_and_defaults_cm&lt;/h4&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;clear_limits_and_defaults_cm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                 &lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;type_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This context manager removes, on exit, all existing per project limits, for
when a project is deleted, or all type specific global defaults and per project
limits, for when a type is deleted.&lt;/p&gt;
&lt;p&gt;Parameters &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;project_id&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;type_name&lt;/span&gt;&lt;/code&gt; will be used used as filter in the
deletion.  So if only &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;project_id&lt;/span&gt;&lt;/code&gt; is provided then only per project entries
will be deleted (in the db driver those from the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;quotas&lt;/span&gt;&lt;/code&gt; table), and if
only the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;type_name&lt;/span&gt;&lt;/code&gt; is provided then only &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;gigabytes_&amp;lt;type-name&amp;gt;&lt;/span&gt;&lt;/code&gt;,
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volume_&amp;lt;type-name&amp;gt;&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;snapshots_&amp;lt;type-name&amp;gt;&lt;/span&gt;&lt;/code&gt; resources will be removed
but for per-project (&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;quotas&lt;/span&gt;&lt;/code&gt; db table) and global (&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;quota_classes&lt;/span&gt;&lt;/code&gt; table).&lt;/p&gt;
&lt;p&gt;If an error occurs within the context manager the limits and defaults should
not be cleared.&lt;/p&gt;
&lt;p&gt;This will be a common implementation for both database based quota drivers.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="type-name-change-cm"&gt;
&lt;h4&gt;type_name_change_cm&lt;/h4&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;type_name_change_cm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;old_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;new_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Context manager to make necessary modification, on enter, to system wide
defaults and per project limits to account for a volume type name change.&lt;/p&gt;
&lt;p&gt;This will rename &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;gigabytes_&amp;lt;old_name&amp;gt;&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volume_&amp;lt;old_name&amp;gt;&lt;/span&gt;&lt;/code&gt; and
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;snapshots_&amp;lt;old_name&amp;gt;&lt;/span&gt;&lt;/code&gt; to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;gigabytes_&amp;lt;new_name&amp;gt;&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volume_&amp;lt;new_name&amp;gt;&lt;/span&gt;&lt;/code&gt; and
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;snapshots_&amp;lt;new_name&amp;gt;&lt;/span&gt;&lt;/code&gt; respectively in all tables.&lt;/p&gt;
&lt;p&gt;The database change to the volume type name is called within this context
manager to ensure that the quota defaults and limits stay in sync with the
volume type name and we don’t change one but not the other.&lt;/p&gt;
&lt;p&gt;This will be a common implementation for both database based quota drivers.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="get-defaults"&gt;
&lt;h4&gt;get_defaults&lt;/h4&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;get_defaults&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Returns system wide defaults for quota limits. If &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;project_id&lt;/span&gt;&lt;/code&gt; is not
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;None&lt;/span&gt;&lt;/code&gt; then volume types quota resources (&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volumes_&amp;lt;volume-type&amp;gt;&lt;/span&gt;&lt;/code&gt;,
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;gigabytes_&amp;lt;volume-type&amp;gt;&lt;/span&gt;&lt;/code&gt;, and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;snapshots_&amp;lt;volume-type&amp;gt;&lt;/span&gt;&lt;/code&gt;) will be filtered
based on the project’s visibility of the volume types, if &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;project_id&lt;/span&gt;&lt;/code&gt; is
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;None&lt;/span&gt;&lt;/code&gt; then &lt;strong&gt;all&lt;/strong&gt; defaults will be returned regardless of the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;is_public&lt;/span&gt;&lt;/code&gt;
value of the volume types.&lt;/p&gt;
&lt;p&gt;In terms of volume type visibility, a project can view all public volume types
and private ones where it has permissions (entries in the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volume_type_projects&lt;/span&gt;&lt;/code&gt; table).&lt;/p&gt;
&lt;p&gt;System wide defaults are stored in the database in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;quota_classes&lt;/span&gt;&lt;/code&gt; table
with the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;default&lt;/span&gt;&lt;/code&gt; value on the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;class_name&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Returned data is a dictionary mapping resources to their hard limits, and must
include &lt;strong&gt;all&lt;/strong&gt; volume type resources even if there is no record in the
database.&lt;/p&gt;
&lt;p&gt;In the following example of returned data the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;gigabytes_lvmdriver-1&lt;/span&gt;&lt;/code&gt;,
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volumes_lvmdriver-1&lt;/span&gt;&lt;/code&gt;, and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;snapshots_lvmdriver-1&lt;/span&gt;&lt;/code&gt; are not present in the
database:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="s2"&gt;"per_volume_gigabytes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s2"&gt;"volumes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s2"&gt;"gigabytes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s2"&gt;"snapshots"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s2"&gt;"backups"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s2"&gt;"backup_gigabytes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s2"&gt;"groups"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s2"&gt;"gigabytes___DEFAULT__"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s2"&gt;"volumes___DEFAULT__"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s2"&gt;"snapshots___DEFAULT__"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s2"&gt;"gigabytes_lvmdriver-1"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s2"&gt;"volumes_lvmdriver-1"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s2"&gt;"snapshots_lvmdriver-1"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This will be a common implementation for both database based quota drivers.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="get-limits-and-usage"&gt;
&lt;h4&gt;get_limits_and_usage&lt;/h4&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;get_limits_and_usage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;usages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Get &lt;strong&gt;all&lt;/strong&gt; effective quota limits for a specific project, and optionally quota
usage, for a specific project.  If &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;project_id&lt;/span&gt;&lt;/code&gt; is &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;None&lt;/span&gt;&lt;/code&gt; the one from the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;context&lt;/span&gt;&lt;/code&gt; will be used.&lt;/p&gt;
&lt;p&gt;Volume types quota resources (&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volumes_&amp;lt;volume-type&amp;gt;&lt;/span&gt;&lt;/code&gt;,
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;gigabytes_&amp;lt;volume-type&amp;gt;&lt;/span&gt;&lt;/code&gt;, and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;snapshots_&amp;lt;volume-type&amp;gt;&lt;/span&gt;&lt;/code&gt;) will be filtered
based on the project’s visibility of the volume types.&lt;/p&gt;
&lt;p&gt;A project can view all public volume types and private volume types where it
has permissions (entries in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volume_type_projects&lt;/span&gt;&lt;/code&gt; table).&lt;/p&gt;
&lt;p&gt;A quota limit values defined in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;quotas&lt;/span&gt;&lt;/code&gt; table overrides global values
from the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;quota_classes&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Returned data will always be a dictionary (or &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;defaultdict&lt;/span&gt;&lt;/code&gt;), but the
contents will depend on whether we are getting quota usage or not.  Just like
the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;get_defaults&lt;/span&gt;&lt;/code&gt; method this returns &lt;strong&gt;all&lt;/strong&gt; volume type resources even if
there is no record in the database.&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="s2"&gt;"per_volume_gigabytes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s2"&gt;"volumes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s2"&gt;"gigabytes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s2"&gt;"snapshots"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s2"&gt;"backups"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s2"&gt;"backup_gigabytes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s2"&gt;"groups"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s2"&gt;"gigabytes___DEFAULT__"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s2"&gt;"volumes___DEFAULT__"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s2"&gt;"snapshots___DEFAULT__"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s2"&gt;"gigabytes_lvmdriver-1"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s2"&gt;"volumes_lvmdriver-1"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s2"&gt;"snapshots_lvmdriver-1"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;With quota usage returned value will look like this:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="s1"&gt;'per_volume_gigabytes'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'limit'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'in_use'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'reserved'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
 &lt;span class="s1"&gt;'volumes'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'limit'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'in_use'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'reserved'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
 &lt;span class="s1"&gt;'gigabytes'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'limit'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'in_use'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'reserved'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
 &lt;span class="s1"&gt;'snapshots'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'limit'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'in_use'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'reserved'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
 &lt;span class="s1"&gt;'backups'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'limit'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'in_use'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'reserved'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
 &lt;span class="s1"&gt;'backup_gigabytes'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'limit'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'in_use'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'reserved'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
 &lt;span class="s1"&gt;'groups'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'limit'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'in_use'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'reserved'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
 &lt;span class="s1"&gt;'gigabytes___DEFAULT__'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'limit'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'in_use'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'reserved'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
 &lt;span class="s1"&gt;'volumes___DEFAULT__'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'limit'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'in_use'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'reserved'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
 &lt;span class="s1"&gt;'snapshots___DEFAULT__'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'limit'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'in_use'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'reserved'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
 &lt;span class="s1"&gt;'gigabytes_lvmdriver-1'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'limit'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'in_use'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'reserved'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
 &lt;span class="s1"&gt;'volumes_lvmdriver-1'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'limit'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'in_use'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'reserved'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
 &lt;span class="s1"&gt;'snapshots_lvmdriver-1'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'limit'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'in_use'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'reserved'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="group-check-cm"&gt;
&lt;h4&gt;group_check_cm&lt;/h4&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;group_check_cm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;qty&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Context manager to check group quota upon context entering.&lt;/p&gt;
&lt;p&gt;Raises &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;QuotaError&lt;/span&gt;&lt;/code&gt; if quota usage would go over the quota limits upon adding
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;qty&lt;/span&gt;&lt;/code&gt; new groups.&lt;/p&gt;
&lt;p&gt;Effective quota limits are determined based on the project’s quota limits
(&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;hard_limit&lt;/span&gt;&lt;/code&gt; for the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;groups&lt;/span&gt;&lt;/code&gt; resource in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;quotas&lt;/span&gt;&lt;/code&gt; table) if defined
or the global defaults (in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;quota_classes&lt;/span&gt;&lt;/code&gt; table) otherwise.&lt;/p&gt;
&lt;p&gt;The project is determined by the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;project_id&lt;/span&gt;&lt;/code&gt; parameter or the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;context&lt;/span&gt;&lt;/code&gt;’s
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;project_id&lt;/span&gt;&lt;/code&gt; if the optional &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;project_id&lt;/span&gt;&lt;/code&gt; parameter value is &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;None&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The context manager must ensure that there are no race conditions with
concurrent calls to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;group_check_cm&lt;/span&gt;&lt;/code&gt; within different threads and processes
in the node as well as across different nodes.&lt;/p&gt;
&lt;p&gt;For the database driver this can be achieved using a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;SELECT&lt;/span&gt; &lt;span class="pre"&gt;FOR&lt;/span&gt; &lt;span class="pre"&gt;UPDATE&lt;/span&gt;&lt;/code&gt; on
the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;groups&lt;/span&gt;&lt;/code&gt; quota limit which blocks other requests until the context
manager exists.&lt;/p&gt;
&lt;p&gt;Users of this context manager should try to keep the code within the context
manager to a minimum to allow higher concurrency.&lt;/p&gt;
&lt;p&gt;For the DB driver, the context manager will start a database
transaction/session, making it available in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;session&lt;/span&gt;&lt;/code&gt; attribute of the
provided &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;context&lt;/span&gt;&lt;/code&gt;, and this transaction will be committed if the code
enveloped by the context manager completes successfully, but if an exception is
raised in the enveloped code then the transaction will be rolled back.  So this
context manager not only checks the quotas but also provides a transaction
context.&lt;/p&gt;
&lt;p&gt;An example of using this context manager within the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;create&lt;/span&gt;&lt;/code&gt; method of the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Group&lt;/span&gt;&lt;/code&gt; Oslo Versioned Object:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;quota&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;group_check_cm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;qty&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;db_groups&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;group_create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                &lt;span class="n"&gt;updates&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                &lt;span class="n"&gt;group_snapshot_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                &lt;span class="n"&gt;source_group_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="group-free"&gt;
&lt;h4&gt;group_free&lt;/h4&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;group_free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;gbs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;qty&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Context manager to free group quotas upon context exiting.  The DB row soft
deletion of groups will be enclosed by this call.&lt;/p&gt;
&lt;p&gt;This is only relevant for the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;StoredQuotaDriver&lt;/span&gt;&lt;/code&gt; that needs to decrease its
counters.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="backup-check-cm"&gt;
&lt;h4&gt;backup_check_cm&lt;/h4&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;backup_check_cm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;gbs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;qty&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Context manager to check backup quotas upon context entering.&lt;/p&gt;
&lt;p&gt;Raises &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;QuotaError&lt;/span&gt;&lt;/code&gt; if quota usage would go over the quota limits upon adding
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;qty&lt;/span&gt;&lt;/code&gt; backups or &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;gbs&lt;/span&gt;&lt;/code&gt; backup gigabytes.&lt;/p&gt;
&lt;p&gt;Effective quota limits are determined based on the project’s quota limits
(&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;hard_limit&lt;/span&gt;&lt;/code&gt; for the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;backups&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;backup_gigabytes&lt;/span&gt;&lt;/code&gt; resources in the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;quotas&lt;/span&gt;&lt;/code&gt; table) if defined or the global defaults (in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;quota_classes&lt;/span&gt;&lt;/code&gt;
table) otherwise.&lt;/p&gt;
&lt;p&gt;The project is determined by the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;project_id&lt;/span&gt;&lt;/code&gt; parameter or the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;context&lt;/span&gt;&lt;/code&gt;’s
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;project_id&lt;/span&gt;&lt;/code&gt; if the optional &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;project_id&lt;/span&gt;&lt;/code&gt; parameter value is &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;None&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The context manager must ensure that there are no race conditions with
concurrent calls to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;backup_check_cm&lt;/span&gt;&lt;/code&gt; within different threads and processes
in the node as well as across different nodes.&lt;/p&gt;
&lt;p&gt;For the database driver this can be achieved using a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;SELECT&lt;/span&gt; &lt;span class="pre"&gt;FOR&lt;/span&gt; &lt;span class="pre"&gt;UPDATE&lt;/span&gt;&lt;/code&gt; on
the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;backups&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;backup_gigabytes&lt;/span&gt;&lt;/code&gt; quota limits which blocks other
requests until the context manager exists.&lt;/p&gt;
&lt;p&gt;Users of this context manager should try to keep the code within the context
manager to a minimum to allow higher concurrency.&lt;/p&gt;
&lt;p&gt;For the DB driver, the context manager will start a database
transaction/session, making it available in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;session&lt;/span&gt;&lt;/code&gt; attribute of the
provided &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;context&lt;/span&gt;&lt;/code&gt;, and this transaction will be committed if the code
enveloped by the context manager completes successfully, but if an exception is
raised in the enveloped code then the transaction will be rolled back.  So this
context manager not only checks the quotas but also provides a transaction
context.&lt;/p&gt;
&lt;p&gt;An example of using this context manager within the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;create&lt;/span&gt;&lt;/code&gt; method of the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Backup&lt;/span&gt;&lt;/code&gt; Oslo Versioned Object:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;quota&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;backup_check_cm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;qty&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;gbs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;db_backup&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;backup_create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;updates&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="backup-free"&gt;
&lt;h4&gt;backup_free&lt;/h4&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;backup_free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;gbs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;qty&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Context manager to free backup quotas upon context exiting.  The DB row soft
deletion of the backup will be enclosed by this call.&lt;/p&gt;
&lt;p&gt;This is only relevant for the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;StoredQuotaDriver&lt;/span&gt;&lt;/code&gt; that needs to decrease its
counters.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="vol-snap-check-and-reserve-cm"&gt;
&lt;h4&gt;vol_snap_check_and_reserve_cm&lt;/h4&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;vol_snap_check_and_reserve_cm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;type_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;type_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                  &lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                  &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                  &lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                  &lt;span class="n"&gt;vol_gbs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vol_qty&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                  &lt;span class="n"&gt;vol_type_gbs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vol_type_vol_qty&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                  &lt;span class="n"&gt;snap_gbs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;snap_qty&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                  &lt;span class="n"&gt;snap_type_gbs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;snap_type_qty&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                  &lt;span class="n"&gt;vol_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Context manager that, upon entering, checks volume and snapshot quotas and
optionally makes reservations.&lt;/p&gt;
&lt;p&gt;Volumes and snapshot are tightly coupled resources, since a snapshot cannot
exist without a parent volume, so their quota checks are handled jointly in the
same method.&lt;/p&gt;
&lt;p&gt;Raises &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;QuotaError&lt;/span&gt;&lt;/code&gt; if quota usage would go over the quota limits upon
consuming provided resources:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vol_qty&lt;/span&gt;&lt;/code&gt; number of volumes being reserved.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vol_gbs&lt;/span&gt;&lt;/code&gt; additional volume gigabytes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vol_type_vol_qty&lt;/span&gt;&lt;/code&gt; volumes of the specified volume type. Defaults to the
value of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vol_qty&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vol_type_gbs&lt;/span&gt;&lt;/code&gt; additional volume gigabytes of the specified volume type.
Defaults to the value of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vol_gbs&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;snap_qty&lt;/span&gt;&lt;/code&gt; snapshots.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;snap_gbs&lt;/span&gt;&lt;/code&gt; additional snapshot gigabytes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;snap_type_qty&lt;/span&gt;&lt;/code&gt; snapshots of the specified volume type. Defaults to the
value of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;snap_qty&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;snap_type_gbs&lt;/span&gt;&lt;/code&gt; additional snapshot gigabytes of the specified volume type.
Defaults to the value of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;snap_gbs&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Unlike the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vol_gbs&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vol_type_gbs&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;snap_gbs&lt;/span&gt;&lt;/code&gt;, and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;snap_type_gbs&lt;/span&gt;&lt;/code&gt;
parameters, the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vol_size&lt;/span&gt;&lt;/code&gt; is not an increment over existing consumption, but
an absolute value representing the total size of the volume.  And the context
manager also raises a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;QuotaError&lt;/span&gt;&lt;/code&gt; exception if it is greater than the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;per_volume_gigabytes&lt;/span&gt;&lt;/code&gt; limit.&lt;/p&gt;
&lt;p&gt;Effective quota limits are determined based on the project’s quota limits
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volumes&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volumes_&amp;lt;volume-type&amp;gt;&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;snapshots&lt;/span&gt;&lt;/code&gt;,
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;snapshots_&amp;lt;volume-type&amp;gt;&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;gigabytes&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;gigabytes_&amp;lt;volume_type&amp;gt;&lt;/span&gt;&lt;/code&gt;, and
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;per_volume_gigabytes&lt;/span&gt;&lt;/code&gt; if defined in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;quotas&lt;/span&gt;&lt;/code&gt; table or the global
defaults defined in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;quota_classes&lt;/span&gt;&lt;/code&gt; table otherwise.&lt;/p&gt;
&lt;p&gt;The project is determined by the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;project_id&lt;/span&gt;&lt;/code&gt; parameter or the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;context&lt;/span&gt;&lt;/code&gt;’s
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;project_id&lt;/span&gt;&lt;/code&gt; if the optional &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;project_id&lt;/span&gt;&lt;/code&gt; parameter value is &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;None&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The volume type name (&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;type_name&lt;/span&gt;&lt;/code&gt;) is necessary to perform quota checks, but
the method can query this information based on the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;type_id&lt;/span&gt;&lt;/code&gt;.  Due to current
Cinder behavior (where a type can be changed to private even when projects have
volumes) then the quota driver needs to confirm that the project still has
access to it.&lt;/p&gt;
&lt;p&gt;Volumes and snapshots are currently the only resources that can have
reservations, and this method automatically creates them when a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;uuid&lt;/span&gt;&lt;/code&gt; is
provided.  This &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;uuid&lt;/span&gt;&lt;/code&gt; must be of the primary resource for the operation,
that is to say that if we are transferring a volume with all its snapshots the
reservations will pass the volume’s &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;uuid&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Both drivers must use different entries for volume and snapshot gigabyte
reservations because the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;no_snapshot_gb_quota_toggled&lt;/span&gt;&lt;/code&gt; configuration option
may be changed and the service restarted before a transfer is accepted, and the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;StoredQuotaDriver&lt;/span&gt;&lt;/code&gt; will need to make a decision both when recalculating (if
driver has changed) and on transfer accept.&lt;/p&gt;
&lt;p&gt;This context manager must ensure that there are no race conditions with
concurrent calls to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vol_snap_check_and_reserve_cm&lt;/span&gt;&lt;/code&gt; within different threads
and processes in the node as well as across different nodes.&lt;/p&gt;
&lt;p&gt;For the database driver this can be achieved using a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;SELECT&lt;/span&gt; &lt;span class="pre"&gt;FOR&lt;/span&gt; &lt;span class="pre"&gt;UPDATE&lt;/span&gt;&lt;/code&gt; on
the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volumes&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volumes_&amp;lt;volume-type&amp;gt;&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;snapshots&lt;/span&gt;&lt;/code&gt;,
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;snapshots_&amp;lt;volume-type&amp;gt;&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;gigabytes&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;gigabytes_&amp;lt;volume_type&amp;gt;&lt;/span&gt;&lt;/code&gt;
quota limits which blocks other volume and snapshot requests until the context
manager exists.&lt;/p&gt;
&lt;p&gt;Users of this context manager should try to keep the code within the context
manager to a minimum to allow higher concurrency.&lt;/p&gt;
&lt;p&gt;When creating reservations the context manager must ensure that they are
cleaned up if an exception is raised within the context manager. For the DB
driver the context manager will start a database transaction/session, making
it available in provided &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;context&lt;/span&gt;&lt;/code&gt;, and will commit everything on normal
context manager exit and roll everything back, including the reservations, when
an exception is raised.&lt;/p&gt;
&lt;p&gt;An example of using this context manager within the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;create&lt;/span&gt;&lt;/code&gt; method of the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Volume&lt;/span&gt;&lt;/code&gt; Oslo Versioned Object:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quota_check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;volume_type&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="n"&gt;volume_type&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;volume_type&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="n"&gt;vol_gbs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="n"&gt;vol_qty&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="n"&gt;vol_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;db_volume&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;volume_create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;updates&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Where &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;quota_check&lt;/span&gt;&lt;/code&gt; is a property that takes into account whether the volume
uses quota or not:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="nd"&gt;@property&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;quota_check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'use_quota'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;quota&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;vol_snap_check_and_reserve&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nullcontext&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="vol-snap-free"&gt;
&lt;h4&gt;vol_snap_free&lt;/h4&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;vol_snap_free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;type_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;type_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="n"&gt;vol_gbs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vol_qty&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="n"&gt;vol_type_gbs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vol_type_vol_qty&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="n"&gt;snap_gbs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;snap_qty&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="n"&gt;snap_type_gbs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;snap_type_qty&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Context manager to free volume and snapshot quotas upon context exiting.&lt;/p&gt;
&lt;p&gt;This is only relevant for the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;StoredQuotaDriver&lt;/span&gt;&lt;/code&gt; that needs to decrease its
counters.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="reservations-clean-cm"&gt;
&lt;h4&gt;reservations_clean_cm&lt;/h4&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;reservations_clean_cm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resource_uuid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;commit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Context manager that cleans all reservations, committing or rolling back, for
the given uuid on &lt;strong&gt;exit&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;uuid&lt;/span&gt;&lt;/code&gt; is the “primary” uuid of the operation and it won’t be a different
uuid for each resource that has been reserved. E.g. when accepting a volume
transfer with its snapshots, all reservations will use the volume’s id.&lt;/p&gt;
&lt;p&gt;For the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DynamicQuotaDriver&lt;/span&gt;&lt;/code&gt; this is mostly just deleting the entries from
the database, but for the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;StoredQuotaDriver&lt;/span&gt;&lt;/code&gt; it needs to adjust the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;in-use&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;reserved&lt;/span&gt;&lt;/code&gt; counters.&lt;/p&gt;
&lt;p&gt;These counters may be from different projects, for the transfer of volumes, so
the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;context&lt;/span&gt;&lt;/code&gt;’s &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;project_id&lt;/span&gt;&lt;/code&gt; will be ignored.&lt;/p&gt;
&lt;p&gt;The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DynamicQuotaDriver&lt;/span&gt;&lt;/code&gt; driver must also take into account the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;no_snapshot_gb_quota_toggled&lt;/span&gt;&lt;/code&gt; configuration option when committing a
transfer, because the snapshot reservations are stored in different row entries
in case the option is changed and the service rebooted before a transfer is
accepted.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="differences"&gt;
&lt;h3&gt;Differences&lt;/h3&gt;
&lt;p&gt;There are some differences between the new and old system that are worth
highlighting:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Resource consumption rules stated in the &lt;em&gt;Resources&lt;/em&gt; section of this spec are
absolute, so it doesn’t matter if a volume becomes in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;error&lt;/span&gt;&lt;/code&gt; status
because scheduling failed or because the driver call on the volume service
failed. If there is a quotable database record, then it will be counted
towards the quota.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Negative reservations, created when retyping a volume, won’t be taken into
account in usage calculations, because like we mentioned before we want the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volumes_&amp;lt;volume-type&amp;gt;&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;gigabytes_&amp;lt;volume-type&amp;gt;&lt;/span&gt;&lt;/code&gt; of the source type
to still be consumed while we do the operations, since we don’t know if we’ll
succeed or not, and on failure we would need to consume them again.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The new quota system drops the illusion that Cinder can support multiple ORM
systems and accepts the fact that Cinder is tightly coupled with SQLAlchemy
and MySQL/InnoDB (this is not new, &lt;a class="reference external" href="https://review.opendev.org/c/openstack/cinder/+/813229"&gt;there is already a patch proposed that
removes the intermediate layer&lt;/a&gt;, so instead of
having all the quota code in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cinder/db/sqlalchemy/api.py&lt;/span&gt;&lt;/code&gt; it will be under
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cinder/quota&lt;/span&gt;&lt;/code&gt;, including all the database queries.&lt;/p&gt;
&lt;p&gt;This approach has the downside of having DB code in multiple places, with
potential code duplication, but on the other hand it has the great benefit of
having the quota code contained in fewer files and using less memory for
custom quota drivers (currently the standard quota driver file is always
loaded even if it’s not instantiated).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;All deployments will use the default quota class instead of supporting the
already deprecated configuration file quota limits.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The new quota system fixes a number of existing bugs, so there are some
undesired behaviors that change:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Now listing quota limits and quota usages won’t show private types the
project doesn’t have access to (&lt;a class="reference external" href="https://bugs.launchpad.net/cinder/+bug/1576717"&gt;bug #1576717&lt;/a&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A limit of 0 will be shown if a project has resources for a type we no
longer have access to because it was made private after the resource was
created (&lt;a class="reference external" href="https://bugs.launchpad.net/cinder/+bug/1952456"&gt;related bug #1952456&lt;/a&gt;).  This can also happen
if an admin creates a volume for a private type that the project doesn’t
have access to.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="limitations"&gt;
&lt;h3&gt;Limitations&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Spec is aimed at these 2 drivers, so additional drivers may not be easy to
add.  Though it shouldn’t be a problem if these 2 work as expected.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There is a bottleneck in concurrent code execution, because the code locks on
the system wide defaults, which are common to &lt;strong&gt;all&lt;/strong&gt; projects. So, even if
the critical section code enveloped by the check context managers is very
small, it will still limit to only 1 context entering at a time for the whole
deployment for the given quota limits.  As an example, if we are concurrently
creating 100 volumes in as many projects, they will be happening mostly in
parallel, but once they reach the point to check quota limits and create the
DB record they will be serialized.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Race condition on the retype operation as explained in the &lt;em&gt;reservations&lt;/em&gt;
section.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;section id="work-with-what-we-have"&gt;
&lt;h4&gt;Work with what we have&lt;/h4&gt;
&lt;p&gt;Some of the alternatives include:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Carefully go through the Cinder code looking for potential error causes and
fixing them.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Refactor existing quota code to move part of the Quota Python logic into
database queries.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Refactor existing code to reduce spillage of the quota system implementation
details all over the code and reduce the usage of reservations to only the
strictly necessary cases.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These alternatives have the same underlying issue as the current
implementation, where it would be hard to tell whether we have resolved all the
issues or not, and upon encountering another out of sync case in a deployment
we would be, once again, in a position where we cannot tell how we reached that
point.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="unified-limits"&gt;
&lt;h4&gt;Unified Limits&lt;/h4&gt;
&lt;p&gt;Another alternative is to use the &lt;a class="reference external" href="https://docs.openstack.org/keystone/latest/admin/unified-limits.html"&gt;KeyStone Unified Limits&lt;/a&gt;.  At
first glance this may seem like a perfect solution since it:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Allows for a unified limit system in all OpenStack (once all projects
implement it).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Supports different enforcement models, including hierarchies.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But upon closer inspection it’s not without its disadvantages:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;While &lt;a class="reference external" href="https://review.opendev.org/q/topic:bp%252Fglance-unified-quotas"&gt;Glance&lt;/a&gt; and &lt;a class="reference external" href="https://review.opendev.org/q/topic:bp%252Funified-limits-nova"&gt;Nova&lt;/a&gt; implemented
its usage in the Yoga release this still cannot be considered a &lt;em&gt;proven
solution&lt;/em&gt; since there have not been enough time for users to actually
evaluate it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Unified Limits system does not have any mechanism to prevent race
conditions between concurrent operations.  So we’ll have to implement our own
mechanism that needs to work across all the Cinder services. It can be with a
DLM, some database locking, or how Nova is going to do it, which is to check
the limit, commit claim, then check limit again and revert if over usage is
detected.  The Nova mechanism means that we are always doing a double check
and sometimes a revert, and we can even get a false failure due to a double
race condition on the checks (2 concurrent requests pass the initial check
and then both fail on the confirmation check, whereas only 1 of them on its
own would have succeeded).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The oslo.limit project will fail a limit check if the limit has not been
previously registered in KeyStone, which is the opposite of how our quota
system currently behaves, as it assumes unlimited (-1).  This means that
Cinder will either have to manage the registrations of the limits when we
create or destroy volume types, when a project is given access to a volume
type, when a volume type’s public status changes, etc. or to force operators
to manage all this on their own. A more reasonable alternative would be to
modify the oslo.limit project to support alternative behavior on non defined
values.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It will be slower since we have to call an external service, KeyStone, for
the limit check, which has to check the user making the call, go to the
database, etc.  And because each of the resources that are checked &lt;a class="reference external" href="https://github.com/openstack/oslo.limit/blob/a6fff3be3194ebb26c5c851ddb0200f84458c46d/oslo_limit/limit.py#L288"&gt;requires
its own REST API call to KeyStone&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This could be improved in Keystone to allow multiple simultaneous checks.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Hierarchical support using the Strict Two Level enforce mechanism &lt;a class="reference external" href="https://github.com/openstack/oslo.limit/blob/a6fff3be3194ebb26c5c851ddb0200f84458c46d/oslo_limit/limit.py#L201-L215"&gt;isn’t
implemented in oslo.limit&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="fix-bottleneck"&gt;
&lt;h4&gt;Fix bottleneck&lt;/h4&gt;
&lt;p&gt;As mentioned before, in the proposed quota system there is a bottleneck in the
concurrent code execution due to the DB locking, because it is locking using
entries from the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;quotas&lt;/span&gt;&lt;/code&gt; table which are shared among all projects.&lt;/p&gt;
&lt;p&gt;To resolve this bottleneck using the DB locking we would need to duplicate the
system wide defaults.  These entries can be duplicated in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;quotas&lt;/span&gt;&lt;/code&gt; table
or in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;quota_classes&lt;/span&gt;&lt;/code&gt; table.&lt;/p&gt;
&lt;p&gt;If they are duplicated into the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;quotas&lt;/span&gt;&lt;/code&gt; table, then a new column would need
to be added (&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;is_default&lt;/span&gt;&lt;/code&gt;) to flag the contents as being defaults or not.
Because when a global default from the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;quota_classes&lt;/span&gt;&lt;/code&gt; table is changed it
would need to be changed in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;quotas&lt;/span&gt;&lt;/code&gt; table records that have the default
values but not on the records that have been explicitly set, even if they have
the same value as the default.&lt;/p&gt;
&lt;p&gt;If the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;quota_classes&lt;/span&gt;&lt;/code&gt; table is used, then we would store the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;project_id&lt;/span&gt;&lt;/code&gt;
into the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;name&lt;/span&gt;&lt;/code&gt; column, which means that we would have trouble in the future
if we ever wanted to fully implement the Quota Classes concept.  Though this is
unlikely given how long it has been since the table was created and how the
concept has never been implemented.&lt;/p&gt;
&lt;p&gt;When setting a global default quota limit we would need to remove the
restriction on the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;name&lt;/span&gt;&lt;/code&gt; column being &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;default&lt;/span&gt;&lt;/code&gt; when using the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;quota_classes&lt;/span&gt;&lt;/code&gt; and if we used the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;quotas&lt;/span&gt;&lt;/code&gt; table we would need an
additional query besides the one to the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;default&lt;/span&gt;&lt;/code&gt; &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;quota_classes&lt;/span&gt;&lt;/code&gt; record,
as we would need to update non deleted records from the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;quotas&lt;/span&gt;&lt;/code&gt; table for
that resource that have the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;is_default&lt;/span&gt;&lt;/code&gt; value set to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;true&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Another thing to consider is that Cinder doesn’t know beforehand what projects
exist, so it will also need to dynamically duplicate the global default quota
records if they are not present when the first operation on a project is
called.  This can be done efficiently, only incurring into additional queries
on the first request for a project, by assuming the values exist and querying
with locking on them, and only if the result is missing the values we go and
duplicate the global defaults.&lt;/p&gt;
&lt;p&gt;This dynamic duplication is also tricky, because we don’t want to have races
with a global quota limit update request or with other operation that triggers
the same duplication.  These 2 races can be prevented with a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;SELECT&lt;/span&gt; &lt;span class="pre"&gt;...&lt;/span&gt;  &lt;span class="pre"&gt;FOR&lt;/span&gt;
&lt;span class="pre"&gt;UPDATE&lt;/span&gt;&lt;/code&gt; on the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;quota_classes&lt;/span&gt;&lt;/code&gt; table.&lt;/p&gt;
&lt;p&gt;At the time of writing, we are hoping that the bottleneck is not significant
enough to warrant the extra effort of removing it.  If time proves us wrong we
can go and implement one of these or other solution.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="changing-configuration-alternatives"&gt;
&lt;h4&gt;Changing configuration alternatives&lt;/h4&gt;
&lt;p&gt;The &lt;a class="reference internal" href="#changing-configuration"&gt;Changing configuration&lt;/a&gt; subsection of the &lt;a class="reference internal" href="#proposed-change"&gt;Proposed change&lt;/a&gt; section
presented the chosen mechanism to change &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;quota_driver&lt;/span&gt;&lt;/code&gt; and
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;no_snapshot_gb_quota&lt;/span&gt;&lt;/code&gt; configuration options, but those are not the only
possibilities.&lt;/p&gt;
&lt;p&gt;This subsection presents 2 alternatives to make changes to the options and
ensure that &lt;strong&gt;all&lt;/strong&gt; Cinder services run with the same configuration option
values:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Build a complex system to orchestrate the change on running services: Signal
the change to all Cinder services and make sure they complete ongoing quota
operations before signaling the quota driver that it needs to do
recalculations, then signal services that they have to reload the quota
driver and finally continue their operation.&lt;/p&gt;
&lt;p&gt;Implementing this is quite complex, starting with how difficult is to make
sure that there are no services that have missed the notification: A service
may have a temporary loss of connection to RabbitMQ or the DB.&lt;/p&gt;
&lt;p&gt;We also have the difficulty of hitting pause in all running operations among
others.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Only allow changing the configuration option when all services are down.
Cinder services would be smart enough to detect on start that the
configuration has changed and confirm that they are the only service that is
currently running and can proceed to tell the quota driver that it needs to
do the recalculations.&lt;/p&gt;
&lt;p&gt;We find multiple challenges when trying to make Cinder smart enough to detect
that there are no other services running:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;We have no way of knowing if a Cinder API service is running or not because
they don’t issue DB heartbeats and they don’t receive any RPC calls via
RabbitMQ.  We can make them issue DB heartbeats and we may even make them
listed on a message queue for RabbitMQ messages.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When starting all Cinder services at the same time they need to avoid
racing to tell the driver to recalculate the quotas.  This can be resolved
locking for update a DB row to prevent the race and allowing only 1 service
to do the calculation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Even if all services are brought down, the DB heartbeat for the services
won’t timeout for a while, so Cinder will have to wait until those
heartbeats time out.  This introduces an unnecessary delay on the Cinder
restart.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Spurious/temporary network issues that may make Cinder think that there are
no running services.  This is actually the biggest issues.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Since changing the quota configuration options is not something that’s going to
be frequently changed, we actually expect it to be change once at most, passing
the responsibility of doing it right to the system administrator seems like the
best choice.&lt;/p&gt;
&lt;p&gt;In any case this is not something that has to be like that forever.  If this
behavior becomes a real problem we can change it in the future.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;The new quota system will place greater importance on the database queries and
reduce the Python code, so the database needs to be ready to perform counting
queries efficiently.&lt;/p&gt;
&lt;p&gt;The main change to ensure efficiency will be adding the proper indexes to
resource tables.  The index that we’ll need to have is one on the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;project_id&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;deleted&lt;/span&gt;&lt;/code&gt; columns for the following tables (that currently
don’t have them):&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volumes&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;snapshots&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;backups&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;groups&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This changes will bring additional benefits to the Cinder service, because
right now listing resources on a deployment with many projects or with many
deleted resources is not efficient, because the database has to go through
&lt;em&gt;all&lt;/em&gt; the resources to filter out non delete rows that belong to a specific
project (&lt;a class="reference external" href="https://bugs.launchpad.net/cinder/+bug/1952443"&gt;bug #1952443&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Existing &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;quota_usages&lt;/span&gt;&lt;/code&gt; tables will no longer be used, and it will be removed
on the next release after the rollout of the new quota system.&lt;/p&gt;
&lt;p&gt;The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;reservations&lt;/span&gt;&lt;/code&gt; table will remain in use, although only for a couple of
operations.&lt;/p&gt;
&lt;p&gt;Additionally we’ll need to track the current quota driver that is being used as
well as the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;no_snapshot_gb_quota&lt;/span&gt;&lt;/code&gt; configuration option to be able to tell
the quota drivers if they have changed.&lt;/p&gt;
&lt;p&gt;For this purpose the proposal is to create a new table that can store global
cinder information.&lt;/p&gt;
&lt;p&gt;Table &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;global_data&lt;/span&gt;&lt;/code&gt; will have the following fields:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;created_at&lt;/span&gt;&lt;/code&gt;: When this key-value pair was created&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;updated_at&lt;/span&gt;&lt;/code&gt;: When this key-value pair was last updated&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;key&lt;/span&gt;&lt;/code&gt;: String value describing the value. For example
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;no_snapshot_gb_quota&lt;/span&gt;&lt;/code&gt; or &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;quota_driver&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;value&lt;/span&gt;&lt;/code&gt;: String with the value of the key. For example &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;true&lt;/span&gt;&lt;/code&gt; or
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;StoredQuotaDriver&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;There will be no REST API impact, because we currently only expose the usage
and reservations (&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;quota_usages&lt;/span&gt;&lt;/code&gt; table) through a listing API that we’ll
still be able to provide with the current quota driver interface, and we still
have reservations (even if fewer operations use them) so that information still
remains relevant and we don’t need to remove it from the response.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="active-active-ha-impact"&gt;
&lt;h3&gt;Active/Active HA impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;No notification impact, since no new operations are added or removed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;End users of the Cinder service should not have significant impact, except for
how the quota is counted.&lt;/p&gt;
&lt;p&gt;Current behavior can be erratic on how quota is counted, as it will depend on
how and where things fail, so we can have volumes in ERROR status that have
been counted towards quota and others that have not.&lt;/p&gt;
&lt;p&gt;With this new approach the quota consumption rules will be very
straightforward, users/admins just need to list resources and add all that have
the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;consumes_quota&lt;/span&gt;&lt;/code&gt; field set to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;true&lt;/span&gt;&lt;/code&gt; to check if usage is correct.&lt;/p&gt;
&lt;p&gt;This stable behavior, can have a positive impact on a deployment regardless of
how services are going down, since end users will not be able to go over their
allowed quota and be forced to clean failed resources instead of being able to
leave them be.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Some preliminary code was prototyped for the volume creation and get usage
operations to evaluate the performance of the different quota drivers: the old,
the new &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;StoredQuotaDriver&lt;/span&gt;&lt;/code&gt;, and the new &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DynamicQuotaDriver&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The results showed that the new &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;StoredQuotaDriver&lt;/span&gt;&lt;/code&gt; system was twice as fast
as the old code in both operations, and the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DynamicQuotaDriver&lt;/span&gt;&lt;/code&gt; was slower
than the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;StoredQuotaDriver&lt;/span&gt;&lt;/code&gt;, as expected, but faster than the old one until
there are around 26000 resources per project.&lt;/p&gt;
&lt;p&gt;So the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DynamicQuotaDriver&lt;/span&gt;&lt;/code&gt; is less likely to be out of sync with reality
because it doesn’t store fixed values, but the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;StoredQuotaDriver&lt;/span&gt;&lt;/code&gt; has better
performance, and that’s the reason why both drivers are going to be
implemented, to allow system administrators decide which one is better for
them.&lt;/p&gt;
&lt;p&gt;The default driver will be &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DynamicQuotaDriver&lt;/span&gt;&lt;/code&gt; to prioritize the usage
values always stay in sync, and large deployments or those looking for best
performance will be able to use the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;StoredQuotaDriver&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Deployments may even start with one quota system and then switch to the other
if necessary.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;As soon as the new code is deployed and executed the new quota system will be
used, there will be no backward compatibility support for old quota code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Deployments using a custom external quota driver will no longer be able to
start.  This should not be a problem as we believe there is nobody using a
custom driver.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;During rolling upgrades the quota system will be more fragile than usual, and
users may be able to go over quota.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;New quota system will no longer have an internal brute force cleaning
mechanism of quotas, the volume state change API will be used to clean
reservations, and the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cinder-manage&lt;/span&gt; &lt;span class="pre"&gt;quota&lt;/span&gt; &lt;span class="pre"&gt;sync&lt;/span&gt;&lt;/code&gt; command will be used for
the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;StoredQuotaDriver&lt;/span&gt;&lt;/code&gt;, so the following configuration options will be
deprecated and will no longer have any effect:
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;reservation_expire&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;reservation_clean_interval&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;until_refresh&lt;/span&gt;&lt;/code&gt;,
and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;max_age&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Configuration option &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;use_default_quota_class&lt;/span&gt;&lt;/code&gt; will be deprecated, because
all deployments will use the default quota class instead of supporting the
already deprecated configuration file quota limits
(&lt;a class="reference external" href="https://bugs.launchpad.net/cinder/+bug/1609937"&gt;related bug #1609937&lt;/a&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;There should be a positive impact on Cinder developers, since the code should
be more readable without all the quota code in between the higher level logic,
and adding new code should not require touching the quota manually.&lt;/p&gt;
&lt;p&gt;The new code will probably break the cinderlib project, so changes to the
project will also be necessary.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Gorka Eguileor (geguileo)&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Rajat Dhasmana (whoami-rajat)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;As discussed in the PTG/mid-cycle this work may be split in 2 phases that may
be implemented in different releases:&lt;/p&gt;
&lt;section id="phase-1-dynamicquotadriver"&gt;
&lt;h4&gt;Phase 1: &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DynamicQuotaDriver&lt;/span&gt;&lt;/code&gt;&lt;/h4&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Deprecate configuration options and log warnings for deployments that are
using custom quota drivers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add required indexes to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volumes&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;snapshots&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;backups&lt;/span&gt;&lt;/code&gt;, and
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;groups&lt;/span&gt;&lt;/code&gt; tables.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add missing &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;backup&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;backup_gigabytes&lt;/span&gt;&lt;/code&gt; default quota limits to the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;quota_classes&lt;/span&gt;&lt;/code&gt; table.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Remove deprecated &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;consistencygroups&lt;/span&gt;&lt;/code&gt; resources from the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;quota_classes&lt;/span&gt;&lt;/code&gt;,
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;quotas&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;quota_usages&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;reservations&lt;/span&gt;&lt;/code&gt; table.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Write the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DynamicQuotaDriver&lt;/span&gt;&lt;/code&gt; database quota driver.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make the following operations use the new quota driver:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Create volume&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete volume&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Manage volume&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Extend volume&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Retype volume&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Transfer volume&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create snapshot&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete snapshot&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Manage snapshot&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Backup create&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Backup restore&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Group create&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Group delete&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Remove code for the old quota driver.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cinder-manage&lt;/span&gt; &lt;span class="pre"&gt;quota&lt;/span&gt; &lt;span class="pre"&gt;sync&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;check&lt;/span&gt;&lt;/code&gt; be &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;noop&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Write the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DynamicQuotaDriver&lt;/span&gt;&lt;/code&gt; database quota driver unit tests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update existing unit tests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Write initial documentation and mention that a more efficient driver will be
coming in the future.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="phase-2-storedquotadriver"&gt;
&lt;h4&gt;Phase 2: &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;StoredQuotaDriver&lt;/span&gt;&lt;/code&gt;&lt;/h4&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Write the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;StoredQuotaDriver&lt;/span&gt;&lt;/code&gt; database quota driver.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Write the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;StoredQuotaDriver&lt;/span&gt;&lt;/code&gt; database quota driver unit tests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cinder-manage&lt;/span&gt; &lt;span class="pre"&gt;quota&lt;/span&gt; &lt;span class="pre"&gt;sync&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;check&lt;/span&gt;&lt;/code&gt; commands.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cinder-manage&lt;/span&gt; &lt;span class="pre"&gt;quota&lt;/span&gt; &lt;span class="pre"&gt;change&lt;/span&gt;&lt;/code&gt; command.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Do basic manual performance comparison of old and new quota system.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add support for the new quota system to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cinderlib&lt;/span&gt;&lt;/code&gt; with a &lt;em&gt;noop&lt;/em&gt; quota
driver and use it as the default value of the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;quota_driver&lt;/span&gt;&lt;/code&gt; configuration
option.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update documentation.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The database engine cannot lock on non-existent rows, so the new code needs
the database to hold default quota limit records for all the basic resources
in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;quota_classes&lt;/span&gt;&lt;/code&gt; table.  So this new code depends on us ensuring that
the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;backups&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;backup_gigabytes&lt;/span&gt;&lt;/code&gt; records are present in the database
and we should also have the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;consistencygroups&lt;/span&gt;&lt;/code&gt; removed since they haven’t
been used for a long time
(&lt;a class="reference external" href="https://bugs.launchpad.net/cinder/+bug/1952420"&gt;bug #1952420&lt;/a&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Besides some manual testing that will be performed to do some basic performance
comparison between the old and the new quota system, most of the testing will
be focused on the testing of the SQL queries.&lt;/p&gt;
&lt;p&gt;Currently supported database engines are InnoDB and SQLite, and the second one
has some limitations and quirks that may make testing some of the queries
difficult or impossible, so some of the unit tests will be skipped on SQLite.&lt;/p&gt;
&lt;p&gt;We may explore the possibility of running a tempest job that checks the quota
usage after finishing the tempest run and reports if it has become out of sync.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;The Cinder quota documentation will be updated to reflect how resources will be
tracked now, to contain description and use cases of the different quota
drivers, as well as the procedure to change the quota driver driver and the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;no_snapshot_gb_quota_toggled&lt;/span&gt;&lt;/code&gt; configuration option.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://etherpad.opendev.org/p/yoga-ptg-cinder#L469"&gt;In the Yoga PTG&lt;/a&gt; it
was accepted that the quota system will be flaky during rolling upgrades.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.opendev.org/c/openstack/cinder/+/819691"&gt;WIP patch showing how the new quota system could look like&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Related bugs:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Backup creation quota warning in logs: &lt;a class="reference external" href="https://bugs.launchpad.net/cinder/+bug/1952420"&gt;bug #1952420&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Remove &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;default_quota_class&lt;/span&gt;&lt;/code&gt; configuration option: &lt;a class="reference external" href="https://bugs.launchpad.net/cinder/+bug/1609937"&gt;bug #1609937&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Warnings when creating volumes and snapshots with a type that doesn’t have
values in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;quota_classes&lt;/span&gt;&lt;/code&gt;: &lt;a class="reference external" href="https://bugs.launchpad.net/cinder/+bug/1435807"&gt;bug #1435807&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Inneficient listing of resources: &lt;a class="reference external" href="https://bugs.launchpad.net/cinder/+bug/1952443"&gt;bug #1952443&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Showing quotas for private types: &lt;a class="reference external" href="https://bugs.launchpad.net/cinder/+bug/1576717"&gt;bug #1576717&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Incorrect limit for private volume types: &lt;a class="reference external" href="https://bugs.launchpad.net/cinder/+bug/1952456"&gt;bug #1952456&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Incorrect usage when changing &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;no_snapshot_gb_quota&lt;/span&gt;&lt;/code&gt;: &lt;a class="reference external" href="https://bugs.launchpad.net/cinder/+bug/1952635"&gt;bug #1952635&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Sat, 21 Oct 2023 00:00:00 </pubDate></item><item><title>Default volume type overrides</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/victoria/default-volume-type-overrides.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/multiple-default-volume-types"&gt;https://blueprints.launchpad.net/cinder/+spec/multiple-default-volume-types&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Cinder’s current default volume type options are limited and are insufficient
for big and/or complex deployments.&lt;/p&gt;
&lt;p&gt;This spec proposes adding per project volume types.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;On complex and/or big OpenStack deployments we may have multiple availability
zones (AZs) with many projects, increasing the complexity of properly
structuring and managing resources.&lt;/p&gt;
&lt;p&gt;One of the problems we encounter when having multiple AZs is that we usually
want our projects to have volumes and instances collocated within the same AZ,
but we can only define one default volume type, forcing our users to always
remember to create volumes with a volume type (if it has the AZ defined in it)
or to explicitly pass the AZ.&lt;/p&gt;
&lt;p&gt;This is error prone, and users forgetting it will lead to unwanted cross AZ
attachments, with the consequent performance issues and network throughput
costs.&lt;/p&gt;
&lt;p&gt;Right now there are 2 workarounds that users are adopting to mitigate this
situation:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Disabling cross AZ attachments in Nova: For deployments that don’t want to do
cross AZ instance live migrations, they can disable cross AZ attachments in
Nova so the attachment to the instance fails, thus preventing performance
issues on running VMs.  This solution usually forces users to recreate the
volume in the right AZ.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unusable default volume type: Setting a default volume type with a self
explanatory name, such as &lt;em&gt;Need_To_Select_Volume_Type&lt;/em&gt; and setting it in a
way that will fail the scheduling and leave the volume in an error state.
This is less wasteful, but still not a nice user experience.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This spec addresses this specific problem.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;On a country wide OpenStack deployment that spreads across multiple data
centers where each one has its own storage array and OpenStack project, an
administrator wants to make sure that volumes are created in their own data
center by default.  For this purpose the admin defines a per project default
volume type where it has the appropriate extra specs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;On an OpenStack deployment with 3 different volume types (high performance,
replicated, compressed) and different department (each with a different
project) have different requirements, so the system admin wants to assign a
different OpenStack volume type to each one of them.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;The proposal is to add the possibility to override the existing Cinder default
Volume Type on a per project basis to make it easier to manage complex
deployments.&lt;/p&gt;
&lt;p&gt;With the introduction of this new default volume type configuration, we’ll now
have 2 different default volume types.  From more specific to more generic
these are:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Per project&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Defined in cinder.conf (defaults to &lt;em&gt;__DEFAULT__&lt;/em&gt; type)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So when a user creates a new volume that has no defined volume type (explicit
or in the source), Cinder will look for the appropriate default first by
checking if there’s one defined in the DB for the specific project and use it,
if there isn’t one, it will continue like it does today, using the default type
from &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cinder.conf&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Administrators and users must still be careful with the normal Cinder behavior
when creating volumes, as Cinder will still only resort to using the default
volume type if the user doesn’t select one on the request or if there’s no
volume type in the source, which means that Cinder &lt;strong&gt;will not&lt;/strong&gt; use any of
those defaults if we:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create a volume providing a volume type&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a volume from a snapshot&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Clone a volume&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a volume from an image that has &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cinder_img_volume_type&lt;/span&gt;&lt;/code&gt; defined in
its metadata.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;By default the policy restricting access to set, unset, get or list all
project default volume type will be set to system admins only.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;An alternative would be allow setting default volume types overrides on a per
user and per project basis, as well as globally.&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.opendev.org/#/c/733555/2/specs/victoria/default-volume-type-overrides.rst"&gt;Such alternative was discarded&lt;/a&gt;,
given the added complexity and effort needed to implement to provide very
little benefits, as configurable per user and global default volume types don’t
seem to be a user necessity.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;We will add a new table called &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;default_volume_type&lt;/span&gt;&lt;/code&gt; that will have 3 fields:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;id&lt;/span&gt;&lt;/code&gt; primary integer key.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volume_type_id&lt;/span&gt;&lt;/code&gt; foreign key string of length 36.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;project_id&lt;/span&gt;&lt;/code&gt; string.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We won’t reuse existing &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volume_type_projects&lt;/span&gt;&lt;/code&gt; table and just add an
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;is_default&lt;/span&gt;&lt;/code&gt; field because then the combinations of private/public volume
types and defaults get complex as we update or remove them.&lt;/p&gt;
&lt;p&gt;In terms of database migrations we’ll just have to create the table.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;We’ll need a new set of REST API calls to provide the CRUD operations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Set the default volume type (create or update) for a specific project.&lt;/p&gt;
&lt;p&gt;Besides ensuring that the volume type exists and the project has access to
it, this method will also call keystone to validate that the project exists.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;PUT /v3/default-types/{project_id}&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;JSON body to set default type (by name or id) for a project:&lt;/p&gt;
&lt;div class="highlight-json notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"volume_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"lvm"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;dl&gt;
&lt;dt&gt;Response Codes:&lt;/dt&gt;&lt;dd&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Success - 200 (with body)&lt;/p&gt;
&lt;div class="highlight-json notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"248592b4-a6da-4c4c-abe0-9d8dbe0b74b4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"type_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"f8a82360-0b1a-4649-8615-114341dd06e0"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Error - 400 (volume type not found), 404 (project id not found)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unset a default volume type.  It will fail if there is not a default
volume type for the given project or if the project no longer exists in
keystone.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;DELETE /v3/default-types/{project_id}&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Response Codes:
- Success - 204
- Error - 404 (project id not found)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Get volume types&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Show default type for a project
GET /v3/default-types/{project_id}&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A request with project_id will return a single JSON object containing
the project_id and type_id of the specified project.  Returns 404 error
code if the entry is not in the DB, independent of the existence of the
project in keystone.&lt;/p&gt;
&lt;div class="highlight-json notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"248592b4-a6da-4c4c-abe0-9d8dbe0b74b4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"type_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"f8a82360-0b1a-4649-8615-114341dd06e0"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Response Codes:
- Success - 200 (with body)
- Error - 404 (project id not found or no default type)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;List all default types
GET /v3/default-types&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A request without a project_id will return all the volume type
defaults defined.  A sample response would be:&lt;/p&gt;
&lt;div class="highlight-json notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;[&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"248592b4-a6da-4c4c-abe0-9d8dbe0b74b4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"type_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"f8a82360-0b1a-4649-8615-114341dd06e0"&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1234567-4c4c-abcd-abe0-1a2b3c4d5e6ff"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"type_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"5c4df055-571e-4430-9823-416b82f337b2"&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Response Codes:
- Success - 200 (with body)&lt;/p&gt;
&lt;p&gt;Notice that we only list overrides, we won’t return the value of
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;default_volume_type&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A user can get its effective default type using existing &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cinder&lt;/span&gt;
&lt;span class="pre"&gt;type-default&lt;/span&gt;&lt;/code&gt; command: &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;GET&lt;/span&gt; &lt;span class="pre"&gt;/v3/{project_id}/types/default&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="active-active-ha-impact"&gt;
&lt;h3&gt;Active/Active HA impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;There will be a new set of commands in the &lt;em&gt;python-cinderclient&lt;/em&gt; to match the
new REST API endpoints:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Set default: &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cinder&lt;/span&gt; &lt;span class="pre"&gt;default-type-set&lt;/span&gt; &lt;span class="pre"&gt;&amp;lt;type-name&amp;gt;&lt;/span&gt; &lt;span class="pre"&gt;&amp;lt;project-id&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unset default: &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cinder&lt;/span&gt; &lt;span class="pre"&gt;default-type-unset&lt;/span&gt; &lt;span class="pre"&gt;&amp;lt;project-id&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;List defaults: &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cinder&lt;/span&gt; &lt;span class="pre"&gt;default-type-list&lt;/span&gt; &lt;span class="pre"&gt;[--project&lt;/span&gt; &lt;span class="pre"&gt;&amp;lt;project-id&amp;gt;]&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Create volume operations that don’t define a default volume type (explicitly or
via a source) will have a tiny performance impact since we’ll add a DB query to
get the defaults.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;We should no longer refer directly to the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;default_volume_type&lt;/span&gt;&lt;/code&gt; configuration
option throughout the code and instead use the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;get_default_volume_type&lt;/span&gt;&lt;/code&gt;
method from &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cinder.volume.volume_types&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&amp;lt;whoami-rajat&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Cinder service&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Check if caller is authorized to do the operation: First we’ll check the
normal policy to see if it’s a system admin, etc, but then we’ll have to
check the project, and we’ll only authorize the operation if caller’s
context has system scope.&lt;/p&gt;
&lt;p&gt;For this we have introduced a new policy to check if the caller is a
system admin and then leverage the &lt;cite&gt;get_project_hierarchy&lt;/cite&gt; method in
&lt;cite&gt;cinder.quota_utils&lt;/cite&gt; to validate that the project actually exists
(since the method does a &lt;cite&gt;get&lt;/cite&gt; of the project).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the DB field and the DB migration.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add 3 DB layer methods:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Set default volume type: Given a volume type id and a project id this
method sets its default volume type.&lt;/p&gt;
&lt;p&gt;It will try to update the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volume_type_id&lt;/span&gt;&lt;/code&gt; for the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;project_id&lt;/span&gt;&lt;/code&gt; and
if it fails because the row doesn’t exist, then it will create the DB
row.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unset default volume type: This will set &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;deleted&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;deleted_at&lt;/span&gt;&lt;/code&gt;
fields for the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;project_id&lt;/span&gt;&lt;/code&gt;.  If it fails because it doesn’t exist, the
failure will not be propagated and it will be considered a success.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Get projects default volume type: Returns a list of project and volume
type ids limited by the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;project_id&lt;/span&gt;&lt;/code&gt; if it is provided.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;get_default_volume_type&lt;/span&gt;&lt;/code&gt; to return the effective volume type for
the current project.  Basically calling the &lt;em&gt;get project default type&lt;/em&gt; DB
method, and if it returns None, then we’ll continue with the current code
we have to use the one from the config.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Updating the volume type methods to ensure we don’t try to delete a volume
type that is used as a default, and making sure we don’t set as private a
volume type that a project is using as a default, and such operations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ensure that &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;purge_deleted_rows&lt;/span&gt;&lt;/code&gt; from &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cinder.db.sqlalchemy.api&lt;/span&gt;&lt;/code&gt; works
as expected.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a new API microversion and implement the 4 REST API methods.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Write appropriate unit-tests for the DB methods, REST API methods, and
update existing tests for the changes we introduced.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cinder client: Add the 3 commands mentioned earlier in the &lt;a class="reference internal" href="#other-end-user-impact"&gt;Other end user
impact&lt;/a&gt; section.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tempest tests: Add tempest tests as describe in the &lt;a class="reference internal" href="#testing"&gt;Testing&lt;/a&gt; section.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation as describe in the &lt;a class="reference internal" href="#documentation-impact"&gt;Documentation impact&lt;/a&gt; section.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Besides writing the appropriate unit-tests for the DB methods, REST API
methods, and update existing tests for the changes we introduced, we also need
a series of Tempest tests to test existing functionality.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Confirm that the priority of the default types are observed:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Admin creates a custom volume type and sets it as the project’s default&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create an empty volume with a normal user and check that the volume type is
the one we created, then delete it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create another volume with the admin user and see that it works the same.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create an empty volume with the alternative project admin user and confirm
it doesn’t use our custom volume type.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unset the custom volume type we set in step 1.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create an empty volume and check that the volume type is not the custom
one.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Confirm that &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cinder&lt;/span&gt; &lt;span class="pre"&gt;type-default&lt;/span&gt;&lt;/code&gt; works as expected:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Admin confirms that there are no default overrides for the project and
alternative project.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Get current default using &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;type-default&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create 2 custom volume types: #1 and #2&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set default volume type #1 for project and #2 for alternative project.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Request the type default with both projects and confirm we get the ones we
have just set.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unset the custom volume types.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Get current default using &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;type-default&lt;/span&gt;&lt;/code&gt; and confirm is the same as in
step 2.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Confirm that listing/showing default type overrides works as expected:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Admin confirms that there are no default overrides for the project by first
listing the default-types, and then by showing the default type for a project
(we’ll get 404), for both the normal project and the alternative.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create 2 custom volume types: #1 and #2&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set default volume type #1 for project and #2 for alternative project.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Admin lists all default volume type and validates them.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Admin gets default volume type for project and confirms that it only gets
that one.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Repeat previous 2 steps for the alternative project.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unset the default types.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Confirm that default type list returns empty list.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Confirm that showing default for a project id returns 404.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Show default for a fake project id and confirm we get 404 error code.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;A description of the default volume types overrides behavior will be added to
the admin section, for example on path
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;doc/source/admin/default-volume-types.rst&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This file will be linked from &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;doc/source/admin/index.rst&lt;/span&gt;&lt;/code&gt; and
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;doc/source/configuration/index.rst&lt;/span&gt;&lt;/code&gt; since it is part of the configuration
but it’s also an administrative task.&lt;/p&gt;
&lt;p&gt;The new CLI commands will be listed and explained in
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;doc/source/cli/cli-manage-volumes.rst&lt;/span&gt;&lt;/code&gt; with examples of the new CLI
commands.&lt;/p&gt;
&lt;p&gt;Additionally the new REST API calls will need to be documented in
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;api-ref/source/v3/default-volume-types.inc&lt;/span&gt;&lt;/code&gt; and samples added to
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;api-ref/source/v3/samples&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;And the microversion history will need to be updated in
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cinder/api/openstack/rest_api_version_history.rst&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://specs.openstack.org/openstack/cinder-specs/specs/train/untyped-volumes-to-default-volume-type.html"&gt;Untyped volume to default volume type&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Wed, 23 Aug 2023 00:00:00 </pubDate></item><item><title>Dedicated backup status field for volumes</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/2023.2/dedicated-volume-backup-status-field.html</link><description>

&lt;p&gt;This spec proposes to introduce a new &lt;cite&gt;backup_status&lt;/cite&gt; field for volumes
to remove the blocking or serialization that active backup tasks impose
on volume attachment workflows.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently all cinder tasks use the status field to check for suitable
volume &lt;cite&gt;status&lt;/cite&gt; while performing any particular operation. During the active
phase of a task, its status is also held and updated via the same volume status
field. And finally also certain errors thrown by a task are communicated back
via this field. This single field in essence creates a locking or
synchronization mechanism to have only one task act on a volume at any one time.&lt;/p&gt;
&lt;p&gt;While this is helpful for coordinating tasks affecting the volume itself,
applying the same logic to backups is actually not required or helpful:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Actions on the volume itself (such as &lt;cite&gt;resize&lt;/cite&gt; or &lt;cite&gt;attaching&lt;/cite&gt;) and backups
backups (backing-up) not techically relate to each other. The backup-driver
and block device-driver act independently and backups are read off a volume
snapshot or, in case the config option &lt;cite&gt;backup_use_temp_snapshot&lt;/cite&gt; is set to
false, a clone of the volume.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A backup might take quite a long time to finish and is blocking any other task
for the volume in the meantime. If we assume a 8TB volume is being
backed up in full and even if the backup was running at 1 GB/s the
volume backup will still take ~2.5 hrs to complete. Decoupling this from a
state machine perspective (since it already is for most drivers or
implementations which work via snapshots) seems to be quite beneficial.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;There are two sides to the use-cases of decoupling backup tasks from other tasks
on a volume:&lt;/p&gt;
&lt;p&gt;1. For cloud operators - Currently detaching volume from source compute node and
attaching it to the destination compute node during an instance live-migration
is blocked by a concurrently run volume backup. To make matters worse, the
potentially long running backup (task) could also have been triggered by the
user and then be blocking administrative actions such as the live-migration of
all instances to others hosts to take a hypervisor down for maintenance.&lt;/p&gt;
&lt;p&gt;Provided sufficiently large volumes or slow backup transfer rates this could
cause users to “lock out” administrative tasks indefinitely.&lt;/p&gt;
&lt;p&gt;2. For cloud users - Urgent operational tasks are blocked by an active backup
task currently. A running backup blocking the users ability to quickly resize a
volume that is running low of available space or attach it to another instance.
This issue is worsened if the backup tasks is even triggered by the cloud
provider or some automatic scheduling.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;For volumes there shall be field &lt;cite&gt;backup_status&lt;/cite&gt; to hold the backup related
values currently stored in &lt;cite&gt;status&lt;/cite&gt;:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;‘backing-up’&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;‘error_backing-up’&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;‘restoring-backup’&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;‘error_restoring’&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;(The &lt;cite&gt;backup_status&lt;/cite&gt; certainly can also be &lt;cite&gt;null&lt;/cite&gt;, to indicate there currently
is no backup related status for this volume.)&lt;/p&gt;
&lt;p&gt;Those shall then be removed from the list of (valid) values of &lt;cite&gt;status&lt;/cite&gt;
and be values for &lt;cite&gt;backup_status&lt;/cite&gt;.&lt;/p&gt;
&lt;p&gt;There will be some changes to the conditional checks for certain tasks to be
started, but most usually depend on those volume status values that would remain
in the status field anyways.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;There was a discussion around a spec [1] moving all task
status to a new field. This ended up being way too complex and not really
suitable for the described use-cases of decoupling volume backups.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;An additional field &lt;cite&gt;backup_status&lt;/cite&gt; would have to be added to the volume table,
together with a change to the list of valid values it might hold.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This will be introduced via a schema change to the database first,
to add the new field.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This change is then followed by an online update/upgrade to split up the
“moved out” status related to backups in their newly dedicated fields.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The valid values for volume status would then also have to be reduced.
&lt;a class="reference external" href="https://opendev.org/openstack/cinder/src/commit/5c23c9fbe41baef22a71eac4406fd9db269d1271/cinder/objects/fields.py#L168-L190"&gt;https://opendev.org/openstack/cinder/src/commit/5c23c9fbe41baef22a71eac4406fd9db269d1271/cinder/objects/fields.py#L168-L190&lt;/a&gt;
As the status &lt;cite&gt;backing-up&lt;/cite&gt;, &lt;cite&gt;error_backing-up&lt;/cite&gt; and are only to be stored in
the backup status.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The method &lt;cite&gt;conditional_update&lt;/cite&gt; needs to support different versions for the
volume data model during the update process of the database. In addition all
calls to the method in the cinder project have to be updated to use the new
field.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;Due to the introduction of a new field and the following split up of the status
field for a volume a new API microversion is required. To serve older
microversions a mapping between the two data-models has to be introduced.
In essence the API has to present the status from both fields
(status, backup_status) in the (previously used) single status field when older
microversions are used.&lt;/p&gt;
&lt;p&gt;The additional field of a backup_status would need to be sent to the user. The
valid status of a volume would only allow the reduced set. In addition
endpoints the reset_status_backup action needs to be adapted to the new
data model to allow (admin only) setting a backup status.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: The list of endpoints to be changed is based on the current proposed
change and is subject to change.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Show volume&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-json notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"volume"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"attachments"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"availability_zone"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"nova"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"bootable"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"false"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"consistencygroup_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"created_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2018-11-29T06:50:07.770785"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"encrypted"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"f7223234-1afc-4d19-bfa3-d19deb6235ef"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"links"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="nt"&gt;"href"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http://127.0.0.1:45839/v3/89afd400-b646-4bbc-b12b-c0a4d63e5bd3/volumes/f7223234-1afc-4d19-bfa3-d19deb6235ef"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="nt"&gt;"rel"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"self"&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="nt"&gt;"href"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http://127.0.0.1:45839/89afd400-b646-4bbc-b12b-c0a4d63e5bd3/volumes/f7223234-1afc-4d19-bfa3-d19deb6235ef"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="nt"&gt;"rel"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bookmark"&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"metadata"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"migration_status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"multiattach"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"os-vol-host-attr:host"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"os-vol-mig-status-attr:migstat"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"os-vol-mig-status-attr:name_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"os-vol-tenant-attr:tenant_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"89afd400-b646-4bbc-b12b-c0a4d63e5bd3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"replication_status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"size"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"snapshot_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"source_volid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"creating"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"backup_status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"updated_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"user_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"c853ca26-e8ea-4797-8a52-ee124a013d0e"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"volume_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"__DEFAULT__"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"provider_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"service_uuid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"shared_targets"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"cluster_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"volume_type_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"5fed9d7c-401d-46e2-8e80-f30c70cb7e1d"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"consumes_quota"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Update volume&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;return additional field for the backup_status&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;List volumes&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;show additional field for the backup_status&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;additional filter for the backup_status&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;List detailed volumes&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;show additional field for the backup_status&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;additional filter for the backup_status&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Additionally (only available with the use of the new micro version)&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Set volume backup_status&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unset volume backup_status&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;While not a performance impact per se, having the backup state-machine
decoupled from the status will reduce the serialization of tasks
happening for a volume.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;The state of a volume can only be set to the reduced list of status.
In addition the backup status can now only be set or unset via the
introducted backup_status field.&lt;/p&gt;
&lt;p&gt;The change above has the impact that all methods have to be checked which allow
concurrent interaction with a volume and use the backup_status field instead of
the status field to indicate a running process.
This change should be communicated to other developer teams that rely on the
cinder api to check on the status to either use an old microversion or update
to use the status and the backup_status.&lt;/p&gt;
&lt;p&gt;Because the status is currently used as a locking mechanism to prevent actions
to start if an invalid status is reached, the method calls in the api have to
be updated to also include a check for the backup_status if necessary. Some of
the work here is currently done by the conditional_update method which needs to
receive support for the updated volume model. This versioning is only needed if
an old database model is received. The API always sends the new model even if
an older API version is used due to the translation layer. This translation
layer guarantees backwards compatibility with older API versions and translates
(status, backup_status) -&amp;gt; status and status -&amp;gt; (status, backup_status).&lt;/p&gt;
&lt;p&gt;To be able to perform an online migration of the database for an update of
openstack a method to remap the status -&amp;gt; (status, backup_status) and save it in
the database is necessary. This method should only be called if the schema
update is done. This method will allow older openstack versions to be able to
perform as before and set or check on their status as needed. These methods
should be removed in further releases.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="upgrade-impact"&gt;
&lt;h3&gt;Upgrade impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;p&gt;The following existing restrictions on which actions / tasks can happen
on a volume have to be maintained with the changes implemented:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Reject volume deletion while volume is currently being backed up&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reject concurrent backups of a volume if one is already in progress&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reject volume or “block storage” migration if a backup is currently running&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Christian Rohmann (IRC: crohmann)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Other contributors:&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Split up the status field to the above mentioned status and backup_status
fields&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Update SQL data model by adding a backup_status column to the volumes table&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create DB migration (Alembic)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;additional method(s) for the model to allow an online migration of the database&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update volume class by adding backup_status field and bumping the version&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Introduce validation methods for the new backup_status field to guarantee that
no wrong status can be set&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update validation methods for the status field to guarantee that
no wrong status can be set&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add versioning to the conditional_update method for &lt;cite&gt;old&lt;/cite&gt; database models&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update method calls to conditional_update to use status and backup_status&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Introduce the API-Layer as a translator to serve older micro versions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Introduce a new microversion to allow backups to be performed in isolation
from other operations that use volume’s status field as a locking mechanism.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Breaking changes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;API Documentation&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Models&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Endpoints&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Upgrade guide/scripts for older database models&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;online migration&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;schema updates&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;Dependencies to other developer teams have to be communicated to ensure they use
the old microversion to avoid breaking changes and to switch to the new split up
fields. This change should especially be communicated to the nova team which
checks regularly for the status of an attached volume.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Since only a reduced set of states are handled via the &lt;cite&gt;status&lt;/cite&gt; field
and with &lt;cite&gt;backup_status&lt;/cite&gt; as newly introduced field, some functional tests
have to be adapted to use the new data model.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Further tests have to be added to ensure the translation layer for older API
microversions work as expected. E.g. the backup status is presented via either
&lt;cite&gt;status&lt;/cite&gt; for an older microversion and then via &lt;cite&gt;backup_status&lt;/cite&gt; for the
new version.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Because the &lt;cite&gt;conditional_update`&lt;/cite&gt; method needs to support versioning in this
release, test should be written to verify that the versioning happens
correctly.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add a release note explaining the motivation and effect of the change&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Document the state-machines for the volume itself and the backup and
restore tasks.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Document the translation layer for the older microversions and how the
translation behaves.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;[1] Previously proposed spec to add a task status: &lt;a class="reference external" href="https://review.opendev.org/c/openstack/cinder-specs/+/818551"&gt;https://review.opendev.org/c/openstack/cinder-specs/+/818551&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="history"&gt;
&lt;h2&gt;History&lt;/h2&gt;
&lt;table class="docutils align-default" id="id1"&gt;
&lt;caption&gt;&lt;span class="caption-text"&gt;Revisions&lt;/span&gt;&lt;/caption&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Release Name&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;2023.02&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Introduced&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/section&gt;
</description><pubDate>Wed, 28 Dec 2022 00:00:00 </pubDate></item><item><title>Image Encryption and Decryption</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/zed/image-encryption.html</link><description>

&lt;p&gt;OpenStack already has the ability to create encrypted volumes and ephemeral
storage to ensure the confidentiality of block data. In contrast to that,
images are currently handled without protection towards confidentiality,
only providing the possibility to ensure integrity using image signatures.
For further protection of user data - e.g. when a user uploads an image
containing private data or confidential information - the image data should
not be accessible for unauthorized entities. For this purpose, an encrypted
image format is to be introduced in OpenStack.&lt;/p&gt;
&lt;p&gt;To enable this, several adjustments to support image encryption/decryption in
various projects, e.g. Nova, Glance, Cinder and OSC, need to be implemented.&lt;/p&gt;
&lt;p&gt;The proposal documented in this spec describes the Cinder-related part of
the overall cross-project concept for image encryption.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;An image, when uploaded to Glance or being created through Nova from an
existing server (VM), may contain sensitive information. The already
provided signature functionality only protects images against alteration.
Images may be stored on several hosts over long periods of time. First and
foremost this includes the image storage hosts of Glance itself. Furthermore
it might also involve other systems such as volume hosts. As a result they
are exposed to a multitude of potential scenarios involving different hosts
with different access patterns and attack surfaces. The OpenStack components
involved in those scenarios – including Cinder - do not protect the
confidentiality of image data.&lt;/p&gt;
&lt;p&gt;Using encrypted storage backends for volume and compute hosts in conjunction
with direct data transfer from/to encrypted images can enable workflows that
never expose an image’s data on a host’s filesystem. Storage of encryption
keys on a dedicated key manager host ensures isolation and access control for
the keys as well. With such a set of configuration recommendations for
security focused environments, we are able to reach a good foundation. Future
enhancements can build upon that and extend the provided security enhancements
to a broader set of variants.&lt;/p&gt;
&lt;p&gt;That’s why we propose the introduction of an encrypted image format.&lt;/p&gt;
&lt;section id="use-cases"&gt;
&lt;h3&gt;Use Cases&lt;/h3&gt;
&lt;p&gt;1. A user wants to create a new volume based on an encrypted image. The
corresponding volume host has to be able to decrypt the image using the
symmetric key stored in the key manager and transform it into the requested
volume resource.&lt;/p&gt;
&lt;p&gt;2.1. A user wants to create an encrypted image from a volume. The volume
does not use an encrypted volume type. The target image is to be encrypted
using the proposed image encryption mechanism and a specified key.&lt;/p&gt;
&lt;p&gt;2.2. A user wants to create an encrypted image from a volume. The volume uses
an encrypted volume type (LUKS-based). The target image is not to be
re-encrypted but will instead reuse the LUKS encryption and key. This use
case is already implemented as part of the default behavior of Cinder.&lt;/p&gt;
&lt;p&gt;2.3. A user wants to create an encrypted image from a volume. The volume uses
an encrypted volume type (LUKS-based). The target image is to be re-encrypted
using the proposed image encryption mechanism and a specified key. This
involves opening a dmcrypt mapping for the LUKS encryption and streaming the
plain data of the volume directly into the target image file while encrypting
it using the specified image encryption mechanism (e.g. GPG).&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;In Glance we propose to add a new container_format called ‘encrypted’.
Furthermore, we propose the following additional metadata properties carried by
images of this format:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;‘os_encrypt_format’ - the main mechanism used, e.g. ‘GPG’&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;‘os_encrypt_type’   - encryption type, e.g. ‘symmetric’&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;‘os_encrypt_cipher’ - the cipher algorithm, e.g. ‘AES256’&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;‘os_encrypt_key_id’ - reference to key in the key manager&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;‘os_decrypt_container_format’ - format after payload decryption&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;‘os_decrypt_size’ - size after payload decryption&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All these metadata properties are only used for the decryption of an image and
won’t be needed in the lifecycle of a volume anymore. When creating an image
from a volume these metadata properties are newly generated and saved in the
Glance metadata of the new image.&lt;/p&gt;
&lt;p&gt;For Cinder we want to add support for encrypted image decryption when a
volume is created from it. Cinder should select a suitable decryption
mechanism according to the new image container_format and metadata. The
symmetric key will be retrieved from the key manager (e.g. Barbican)
according to the key id stored in the metadata. Additionally, Cinder should
be able to encrypt volume data in a similar fashion if the user requests an
encrypted image to be created from a volume according to the use cases 2.1
and 2.3 illustrated above.&lt;/p&gt;
&lt;p&gt;The implementations in Cinder should make use of a centralized encryption
implementation provided by a global library, shared between all involved
OpenStack components to prevent individual implementations of the encryption
mechanism.&lt;/p&gt;
&lt;p&gt;For general image encryption, we propose to use an implementation of
symmetric AES 256 provided by GnuPG as a basic mechanism supported by this
draft. It is a well established implementation of PGP and supports
streamable encryption/decryption processes, which is important as we require
the streamability of the encryption/decryption mechanism for two reasons:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Loading entire images into the memory of volume hosts is unacceptable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We propose direct decryption-streaming into the target volume to prevent
the creation of temporary unencrypted files.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;There is already one existing case in Cinder’s current implementation where
encrypted images are created (use case 2.2). This is when an image is
created directly from an encrypted volume. Since the encrypted block data is
simply copied into the image, the encryption (usually LUKS) is automatically
inherited - as is the encryption key, which is simply cloned in Barbican.
We will not change this behavior as a part of this spec. Our changes will
only apply, when the user actively wants to create an encrypted image from
any volume.&lt;/p&gt;
&lt;p&gt;The key management is handled differently than with encrypted volumes or
encrypted ephemeral storage. The reason for this is, that the encryption and
decryption of an image will never happen in Glance but in all other services,
which consume images. Therefore the service which needs to create a key for
a newly created encrypted image may not be the same service which then has to
delete the key (in most cases Glance). To delete a key, which has not been
created by the same entity, is bad behavior. To avoid this, we choose to let
the user create and delete the key. To not accidently delete a key, which is
used to encrypt an image, we will let Glance register as a consumer of that
key (secret in Barbican [1]) when the corresponding encrypted image is
uploaded and unregister as a consumer when the image is deleted in Glance.&lt;/p&gt;
&lt;p&gt;The methods for encryption and decryption of files - in this case images -
will be written in a driver like manner in os-brick so the image encryption
can be extended with another encryption format easily. The encryption driver
should focus a specific encryption format and implement exactly one encrypt
and one decrypt method, both based on a cipher implementation of GPG aes.
This driver may be simple wrappers around an existing implementation. An
abstract base class should be defined and be used for the implementation of
GPG encryption (and might be used for other implementations in the future).&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Regarding the image encryption, we also explored the possibility of using
more elaborate and dynamic approaches like PKCS#7 (CMS) but ultimately
failed to find a free open-source implementation (e.g. OpenSSL) that
supports streamable decryption of CMS-wrapped encrypted data. More precisely,
no implementation we tested was able to decrypt a symmetrically encrypted,
CMS-wrapped container without trying to completely load it into memory or
suffering from other limitations regarding big files.&lt;/p&gt;
&lt;p&gt;We also evaluated an image encryption implementation based on LUKS which is
already used in Cinder and Nova as an encryption mechanism for volumes and
ephemeral disks respectively. However, we were unable to find a suitable
solution to directly handle file-based LUKS encryption in user space. Firstly,
the handling of LUKS devices (even when file-based) via cryptsetup always
requires the dm-crypt kernel module and corresponding root privileges.
Secondly, in contrast to native LUKS used by LibVirt, the LUKS handling
available via cryptsetup creates temporary device mapper endpoints where data
is read from or written to. There is no direct reading/writing from/to an
encrypted LUKS file and LUKS opening/closing needs to be handled accordingly.
Lastly, LUKS is a format primarily designed for disk encryption. Although it
may be used for files as well (by formatting files as LUKS devices), the
handling is rather inconvenient; for example, the size of the LUKS container
file needs to be calculated and allocated beforehand since it acts like a disk
with a fixed size.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;For creating encrypted images from volumes, additional properties in the
request body of “os-volume_upload_image” will need to be introduced to
specify the desired encryption format and key id.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;There are impacts on the security of OpenStack:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;confidentiality of data in images will be addressed in this spec&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;image encryption is introduced, thus additional cryptographic algorithms
will be used in Cinder to implement this functionality&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Users should be able to optionally, but knowingly create a differently
encrypted image from a volume.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If an administrator has configured Glance to reject unencrypted images, such
images will not be accepted when attempted to be uploaded to Glance.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;The proposed encryption/decryption mechanisms in Cinder will only be utilized
on-demand and skipped entirely for image container types that aren’t
encrypted.&lt;/p&gt;
&lt;p&gt;Thus, any performance impact is only applicable to the newly introduced
encrypted image type where the processing (or creation) of such image will
have increased computational costs and longer processing times than for
regular images. Impact will vary depending on the individual host performance
and supported CPU extensions for cipher algorithms.&lt;/p&gt;
&lt;p&gt;For Ceph-based setups, the usual cloning performance benefit provided by the
shared storage between Glance and Cinder is lost for encrypted images, due to
the need of converting the encrypted image data format to the volume format.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;A key manager - like Barbican - is required.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The key manager needs to be accessible from volume hosts, requiring
appropriate cinder.conf adjustments.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;To use the encoding and decoding of images in os-brick, we need to
execute priviledged functions. We decided to use privsep for this as in
nova.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="upgrade-impact"&gt;
&lt;h3&gt;Upgrade impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Markus Hentsch (IRC: mhen)&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Josephine Seifert (IRC: Luzi)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add a decryption implementation in Cinder for creating volumes from GPG
encrypted images&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a dedicated encryption workflow and implementation in Cinder for
creating encrypted images from volumes using the proposed image encryption
format (GPG)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add encryption and decryption methods for the GPG format in os-brick&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;GPG is required to be installed on all systems that are required to
perform encryption/decryption operations in order to support the proposed
base encryption mechanism.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This spec requires the implementation of an encrypted container_format and
corresponding metadata property support in Glance&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This spec requires the implementation of appropriate encryption/decryption
functionality in a global library shared between the components involved
in image encryption workflows (Nova, Cinder, OSC), like os-brick&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Tempest tests would require access to encrypted images for testing. This
means that Tempest either needs to be provided with an image file that is
already encrypted and its corresponding key or needs to be able to encrypt
images itself. This point is still open for discussion.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;It should be documented for deployers, how to enable this feature in the
OpenStack configuration. An end user should have a documentation on how to
use encrypted images in Cinder and how to create them respectively.
Furthermore, any resulting limitations such as reduced performance should be
mentioned, especially for Ceph-based setups usually benefiting from shared
storage cloning.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;[1] Barbican Secret Consumer Spec: &lt;a class="reference external" href="https://review.opendev.org/#/c/662013/"&gt;https://review.opendev.org/#/c/662013/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Nova-Spec: &lt;a class="reference external" href="https://review.openstack.org/#/c/608696/"&gt;https://review.openstack.org/#/c/608696/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Glance-Spec: &lt;a class="reference external" href="https://review.openstack.org/#/c/609667/"&gt;https://review.openstack.org/#/c/609667/&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="history"&gt;
&lt;h2&gt;History&lt;/h2&gt;
&lt;table class="docutils align-default" id="id1"&gt;
&lt;caption&gt;&lt;span class="caption-text"&gt;Revisions&lt;/span&gt;&lt;/caption&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Release Name&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Train&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Introduced&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Ussuri&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Postponed&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/section&gt;
</description><pubDate>Mon, 02 May 2022 00:00:00 </pubDate></item><item><title>Add Capacity Factors to scheduler get pools API</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/zed/add-capacity-factors-to-get-pools.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/add-capacity-factors-to-pool"&gt;https://blueprints.launchpad.net/cinder/+spec/add-capacity-factors-to-pool&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This spec proposes adding the new capacity factors in the response to the
get-pools API request.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Typically there is some monitoring and alerting in place against a cinder
deployment and it’s storage array to warn/alert the operator of the cloud
that they are running out of storage, or are out of storage.  The only
mechanism in Cinder now to see the capacity factors of the backends that cinder
is managing is to call the cinder api to get-pools.   This returns some
basic information about the backend/pools.  But it doesn’t really tell the whole
story.&lt;/p&gt;
&lt;p&gt;The new capacity factors are various aspects of the capacity management that
cinder calculates on each provisioning request.  Each of those factors are
used at runtime to decide if a volume can land on a particular pool.  Those
factors decide if a pool is full or not depending on several factors including,&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;thin or thick provisioning support&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;total capacity reported by the storage array&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;free capacity reported by the storage array&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;reserved percentage&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;max over subscription ratio&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;From those configuration settings and pool capabilities a wider set of factors
is calculated to determine the capacity availability on a backend/pool.  All
of those factors determine if a backend/pool has space, is running out of space,
or is out of space for cinder to use.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;As an operator of cinder, I want cinder to report all of the factors it uses
and calculates to determine if cinder’s backend/pools have space available.
Only cinder has all information and the calculate_capacity_factors() can
create the information the scheduler uses.  It should also report that in
the pools api request, so tooling for monitoring and alerting can be in
sync with the cinder scheduler.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Add the dictionary that is created from calculate_capacity_factors() to each
pool information in the get-pools response.  The capacity factors are not the
same thing as the capabilities being reported now.  The capacity factors are
the breakdown of the capacity calculations based on the driver’s reported
capabilities seen by the backend storage.  Depending on the capabilities
in each pool such as thin_provisioning_support and thick_provisioning_support,
factors will be calculated for each thin and thick if the pool supports.&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"total_capacity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;5120.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"free_capacity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4616&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"reserved_capacity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"total_reserved_available_capacity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4096&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"max_over_subscription_ratio"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"total_available_capacity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4096&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"provisioned_capacity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"calculated_free_capacity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3596&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"virtual_free_capacity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3596&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"free_percent"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;87.79296875&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"provisioned_ratio"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.1220703125&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"provisioned_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"thick"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;The calculate_capacity_factors() function in utils.py can get copy/pasted into
some external tooling that can do the alerting, but it’s subject to getting out
of sync with cinder’s version.  Therefore Cinder itself should report all of
those capacity factors for each backend/pool that it calculates.   Then cinder
will be the definitive answer on the capacity it sees and can use.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;A new microversion would be required and if compatible cinder
would return the capacity_factors dictionary in the pools response.&lt;/p&gt;
&lt;div class="highlight-console notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="go"&gt;GET /v3/{project_id}/scheduler-stats/get_pools?detail=True&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"pools"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"pool1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"capabilities"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s2"&gt;"updated"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2014-10-28T00:00:00-00:00"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"total_capacity_gb"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"free_capacity_gb"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"volume_backend_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"pool1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"reserved_percentage"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"driver_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"1.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"storage_protocol"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"iSCSI"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"QoS_support"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"thin_provisioning_support"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"thick_provisioning_support"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="s2"&gt;"capacity_factors"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="s2"&gt;"total_capacity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"free_capacity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"reserved_capacity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;51&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"total_reserved_available_capacity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;973&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"max_over_subscription_ratio"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"total_available_capacity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;973&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"provisioned_capacity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"calculated_free_capacity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;873&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"virtual_free_capacity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;873&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"free_percent"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;89.72&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"provisioned_ratio"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.1028&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"provisioned_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"thick"&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="s2"&gt;"total_capacity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"free_capacity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"reserved_capacity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;51&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"total_reserved_available_capacity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;973&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"max_over_subscription_ratio"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"total_available_capacity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1946&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"provisioned_capacity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"calculated_free_capacity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1846&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"virtual_free_capacity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1846&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"free_percent"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;94.86&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"provisioned_ratio"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.05&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"provisioned_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"thin"&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="active-active-ha-impact"&gt;
&lt;h3&gt;Active/Active HA impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;hemna (Walter A. Boring IV)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add new microversion&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;capacity_factors&lt;/span&gt;&lt;/code&gt; in get-pools API response&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;This requires the new calculate_capacity_factors() function that is in the
following review:
&lt;a class="reference external" href="https://review.opendev.org/c/openstack/cinder/+/831247"&gt;https://review.opendev.org/c/openstack/cinder/+/831247&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Add new unit tests to show the factors being returned in API call.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Add documentation to describe the capacity factors and the API response change&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;This was discussed at length at the Zed PTG:
&lt;a class="reference external" href="https://etherpad.opendev.org/p/zed-ptg-cinder"&gt;https://etherpad.opendev.org/p/zed-ptg-cinder&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Youtube Video of discussion:
&lt;a class="reference external" href="https://www.youtube.com/watch?v=6yuOlGckkGE"&gt;https://www.youtube.com/watch?v=6yuOlGckkGE&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The capacity factors definitions
&lt;a class="reference external" href="https://specs.openstack.org/openstack/cinder-specs/specs/queens/provisioning-improvements.html"&gt;https://specs.openstack.org/openstack/cinder-specs/specs/queens/provisioning-improvements.html&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Wed, 13 Apr 2022 00:00:00 </pubDate></item><item><title>Support Linux on System z (S/390) as a hypervisor platform</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/kilo/linux-systemz.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/linux-systemz"&gt;https://blueprints.launchpad.net/cinder/+spec/linux-systemz&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;There are some platform-specific changes needed in order to allow Cinder
manage FCP-based block storage on Linux on System z.&lt;/p&gt;
&lt;p&gt;Additional OpenStack functionality beyond initial Cinder support is not part of
this blueprint; we will have specific additional blueprints for that, as
needed.&lt;/p&gt;
&lt;p&gt;Required support in Nova is described by a separate blueprint which is listed
as a dependency below.&lt;/p&gt;
&lt;p&gt;iSCSI does not require any changes.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Linux on System z differs from other Linux platforms in the following
respects:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;System z uses a different format for device file paths (ccw-based, rather
than pci-based)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Auto-discovery for fibre-channel devices can be configured online, or
offline. In case auto-discovery is turned off, devices need to be
added, and removed explicitly by OpenStack (unit_add, unit_remove)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;vHBAs may be turned online, or offline. Offline vHBAs need to be
ignored.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Change code in Cinder to address these issues, dependent on the host
capabilities indicating a CPU architecture of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;arch.S390X&lt;/span&gt;&lt;/code&gt;, and
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;arch.S390&lt;/span&gt;&lt;/code&gt;.
For details, see section &lt;a class="reference internal" href="#work-items"&gt;Work Items&lt;/a&gt;.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None (no need for platform-specific parameters in cinder.conf as part of this
blueprint)&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None (changes should not affect other platforms)&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;stefan-amann&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;mzoeller
maiera&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;In &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cinder/brick/initiator/connector.py&lt;/span&gt;&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;connect_volume needs to support the System z specific format of the
device file paths and issue the unit_add command (which is done
by calling the new configure_scsi_device() function)&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;platform&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;machine&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;'s390x'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;target_lun&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"0x00&lt;/span&gt;&lt;span class="si"&gt;%02d&lt;/span&gt;&lt;span class="s2"&gt;000000000000"&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;
                 &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;connection_properties&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'target_lun'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;host_device&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"/dev/disk/by-path/ccw-&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s2"&gt;-zfcp-&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;
                  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pci_num&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="n"&gt;target_wwn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="n"&gt;target_lun&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_linuxfc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;configure_scsi_device&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pci_num&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target_wwn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target_lun&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;host_device&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"/dev/disk/by-path/pci-&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s2"&gt;-fc-&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s2"&gt;-lun-&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;
                  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pci_num&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="n"&gt;target_wwn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="n"&gt;connection_properties&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'target_lun'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="n"&gt;host_devices&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;host_device&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;disconnect_volume needs to support the System z specific format of the
device file paths and issue the unit_remove command (which is done by
calling the new deconfigre_scsi_device() function)&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;device&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;devices&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_linuxscsi&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;remove_scsi_device&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"device"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;platform&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;machine&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;'s390x'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;ports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;connection_properties&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'target_wwn'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;wwns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="c1"&gt;# we support a list of wwns or a single wwn&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;wwn&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;wwns&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wwn&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="nb"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;basestring&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;wwns&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;hbas&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_linuxfc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_fc_hbas_info&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;hba&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;hbas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;pci_num&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_get_pci_num&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hba&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;pci_num&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;wwn&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;wwns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;target_wwn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"0x&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;wwn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                &lt;span class="n"&gt;target_lun&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"0x00&lt;/span&gt;&lt;span class="si"&gt;%02d&lt;/span&gt;&lt;span class="s2"&gt;000000000000"&lt;/span&gt;
                    &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;connection_properties&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'target_lun'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
                &lt;span class="n"&gt;host_device&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"/dev/disk/by-path/ccw-&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s2"&gt;-zfcp-&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;
                              &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pci_num&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                               &lt;span class="n"&gt;target_wwn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                               &lt;span class="n"&gt;target_lun&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
                &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_linuxfc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;deconfigure_scsi_device&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                               &lt;span class="n"&gt;pci_num&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                               &lt;span class="n"&gt;target_wwn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                               &lt;span class="n"&gt;target_lun&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cinder/brick/initiator/linuxfc.py&lt;/span&gt;&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Utility functions to execute the unit_add, or unit_remove command.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;configure_scsi_device&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;device_number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target_wwn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lun&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;out&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;
    &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;
    &lt;span class="n"&gt;zfcp_device_command&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"/sys/bus/ccw/drivers/zfcp/&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s2"&gt;/unit_add"&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;
                            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;device_number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                             &lt;span class="n"&gt;target_wwn&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;echo_scsi_command&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;zfcp_device_command&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lun&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;putils&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ProcessExecutionError&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;exc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;LOG&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;warn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"zKVM unit_add call failed exit (&lt;/span&gt;
                               &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;stderr&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;")&lt;/span&gt;
                 &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'code'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;exc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exit_code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'stderr'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;exc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;



&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;deconfigure_scsi_device&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;device_number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target_wwn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lun&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;out&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;
    &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;
    &lt;span class="n"&gt;zfcp_device_command&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"/sys/bus/ccw/drivers/zfcp/&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s2"&gt;/unit_remove"&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;
                            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;device_number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                             &lt;span class="n"&gt;target_wwn&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;echo_scsi_command&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;zfcp_device_command&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lun&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;putils&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ProcessExecutionError&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;exc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;LOG&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;warn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"zKVM unit_remove call failed&lt;/span&gt;
                    &lt;span class="n"&gt;exit&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;stderr&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;")&lt;/span&gt;
                 &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'code'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;exc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exit_code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'stderr'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;exc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Have get_fc_hbas_info() only return enabled vHBAs for System z.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;hbas_info&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;hba&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;hbas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;platform&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;machine&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s1"&gt;'s390x'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hba&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'port_state'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;'Online'&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="n"&gt;same&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;today&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;Nova blueprint to add support for KVM/libvirt in Linux on System z
&lt;a class="reference external" href="https://blueprints.launchpad.net/nova/+spec/libvirt-kvm-systemz"&gt;https://blueprints.launchpad.net/nova/+spec/libvirt-kvm-systemz&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit test:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit tests will be added and performed on System z, as well as
Intel-based machines.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We will provide an environment for CI testing on System z.
This is described by the Nova blueprint which is listed as a dependency.
We will test Cinder and Nova on System z in this environment.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;No changes needed in config docs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Doc changes for the platform will be made as needed (details are to be
determined).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Linux on System z Device Driver book,
&lt;a class="reference external" href="http://public.dhe.ibm.com/software/dw/linux390/docu/l316dd25.pdf"&gt;http://public.dhe.ibm.com/software/dw/linux390/docu/l316dd25.pdf&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Linux on System z,
&lt;a class="reference external" href="http://www.ibm.com/developerworks/linux/linux390/"&gt;http://www.ibm.com/developerworks/linux/linux390/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Tue, 25 Jan 2022 00:00:00 </pubDate></item><item><title>Support ECKD volumes on Linux on System z</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/newton/linux-ficon-support.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/linux-ficon-support"&gt;https://blueprints.launchpad.net/cinder/+spec/linux-ficon-support&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;FICON (Fibre Connection) is a Fibre-Channel FC-4 layer protocol. It is
used on mainframes to attach ECKD volumes via Fibre-Channel.
Several changes are needed in order to allow Cinder to
manage FICON-based block storage on Linux on System z.&lt;/p&gt;
&lt;p&gt;Besides, support is to be added to the existing Cinder drivers
for storage subsystems supporting ECKD (for example, IBM DS8000).&lt;/p&gt;
&lt;p&gt;Required support in Nova is described by a separate blueprint which is
listed as a dependency below.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;FICON and FCP are Fibre-Channel FC-4 layer protocols. FICON uses a
different scheme to address volumes, compared to FCP.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;ECKD volumes are addressed by a Control Unit and Unit Address, rather
than WWPN and LUN.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;System z uses a different format for device file paths (ccw-based, rather
than pci-based), similar to the file paths used for FCP on System z&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ECKD volumes need to be set online and formatted before they can be
used&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;Allow an end-user to create and manage Cinder block devices based upon
FICON attached storage subsystems supporting the ECKD protocol.
For example: create, delete, image deploy, snapshot, ..&lt;/p&gt;
&lt;p&gt;We will extend a Cinder driver for IBMs DS8000. Other vendors, such as
EMC, Hitachi, or HP support ECKD, too. They are potential candidates.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Change code in os-brick to address these issues, dependent on a new
protocol type of ‘fibre_channel_eckd’, provided by the driver
For details, see section &lt;cite&gt;Work Items&lt;/cite&gt;.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Platforms that support FICON/ECKD will need to implement this for their
drivers.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;stefan-amann&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;arecknag
maiera&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;In &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;os-brick/initiator/connector.py&lt;/span&gt;&lt;/code&gt;:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;provide a new connector FibreChannelECKDConnector&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;connect_volume needs to enable interrupts for the volume and
set the volume online. This is done by calling the new
configure_eckd_device() function)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;disconnect_volume needs to set the volume offline. This is done by
calling the new deconfigure_eckd_device() function&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;os-brick/initiator/linuxeckd.py&lt;/span&gt;&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Utility functions to set the volume online, validate it is formatted
appropriately, and format it if required&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;_is_online&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="sd"&gt;"""&lt;/span&gt;
&lt;span class="sd"&gt;    Return True if device is online, else return False&lt;/span&gt;
&lt;span class="sd"&gt;    :param device: device id&lt;/span&gt;
&lt;span class="sd"&gt;    """&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;access&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/sys/bus/ccw/devices/&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s1"&gt;/online'&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;R_OK&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;online_file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;online_file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/sys/bus/ccw/devices/&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s1"&gt;/online'&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;online_file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;readline&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;'1'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;
        &lt;span class="k"&gt;finally&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;online_file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;online_file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;_is_formatted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="sd"&gt;"""&lt;/span&gt;
&lt;span class="sd"&gt;    Return True if device is online, else return False&lt;/span&gt;
&lt;span class="sd"&gt;    :param device: device id&lt;/span&gt;
&lt;span class="sd"&gt;    """&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;access&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/sys/bus/ccw/devices/&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s1"&gt;/status'&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;R_OK&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;formatted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'cat'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                            &lt;span class="s1"&gt;'/sys/bus/ccw/devices/&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s1"&gt;/status'&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                            &lt;span class="n"&gt;run_as_root&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                            &lt;span class="n"&gt;root_helper&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_root_helper&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;out&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;'unformatted'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;format_eckd_volume&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="sd"&gt;"""&lt;/span&gt;
&lt;span class="sd"&gt;    formats ECKD volume&lt;/span&gt;
&lt;span class="sd"&gt;    :param device: device path&lt;/span&gt;
&lt;span class="sd"&gt;    """&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;realpath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;startswith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"/dev/"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;format_cmd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'dasdfmt -y -b 4096 -d ldl '&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;format_cmd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;run_as_root&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                            &lt;span class="n"&gt;root_helper&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_root_helper&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;os-brick/initiator/linuxfc.py&lt;/span&gt;&lt;/code&gt;:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;new class LinuxFibreChannelECKD&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;configure_eckd_device&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;device_number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="sd"&gt;"""Add the eckd volume to the Linux configuration. """&lt;/span&gt;

    &lt;span class="n"&gt;full_device_identifier&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"0.0.&lt;/span&gt;&lt;span class="si"&gt;%04x&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;device_number&lt;/span&gt;
    &lt;span class="n"&gt;eckd_device_command&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'cio_ignore'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'-r'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="si"&gt;%(dev_id)s&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"dev_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;full_device_identifier&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="n"&gt;LOG&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"issue cio_ignore for s390: &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;eckd_device_command&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;info&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;info&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'cio_ignore'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'-r'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="si"&gt;%(dev_id)s&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"dev_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;full_device_identifier&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="n"&gt;run_as_root&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;root_helper&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_root_helper&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;putils&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ProcessExecutionError&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;exc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;LOG&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;warning&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_LW&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"cio_ignore call for s390 failed exit"&lt;/span&gt;
                        &lt;span class="s2"&gt;" &lt;/span&gt;&lt;span class="si"&gt;%(code)s&lt;/span&gt;&lt;span class="s2"&gt;, stderr &lt;/span&gt;&lt;span class="si"&gt;%(stderr)s&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'code'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;exc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exit_code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'stderr'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;exc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="n"&gt;eckd_device_command&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'chccwdev'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'-e'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="si"&gt;%(dev_id)s&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"dev_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;full_device_identifier&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="n"&gt;LOG&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"add ECKD command for s390: &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;eckd_device_command&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;info&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;info&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'chccwdev'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'-e'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="si"&gt;%(dev_id)s&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"dev_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;full_device_identifier&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="n"&gt;run_as_root&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;root_helper&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_root_helper&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;putils&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ProcessExecutionError&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;exc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;LOG&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;warning&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_LW&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"add ECKD call for s390 failed exit"&lt;/span&gt;
                        &lt;span class="s2"&gt;" &lt;/span&gt;&lt;span class="si"&gt;%(code)s&lt;/span&gt;&lt;span class="s2"&gt;, stderr &lt;/span&gt;&lt;span class="si"&gt;%(stderr)s&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'code'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;exc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exit_code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'stderr'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;exc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;deconfigure_eckd_device&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;device_number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="sd"&gt;"""Remove the eckd volume from the Linux configuration. """&lt;/span&gt;

    &lt;span class="n"&gt;LOG&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Deconfigure ECKD volume: device_number=&lt;/span&gt;&lt;span class="si"&gt;%(device_num)s&lt;/span&gt;&lt;span class="s2"&gt; "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'device_num'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;device_number&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="n"&gt;full_device_identifier&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"0.0.&lt;/span&gt;&lt;span class="si"&gt;%04x&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;device_number&lt;/span&gt;
    &lt;span class="n"&gt;eckd_device_command&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'chccwdev'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'-d'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="si"&gt;%(dev_id)s&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"dev_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;full_device_identifier&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="n"&gt;LOG&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"remove ECKD command for s390: &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;eckd_device_command&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;info&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;info&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'chccwdev'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'-d'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="si"&gt;%(dev_id)s&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"dev_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;full_device_identifier&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="n"&gt;run_as_root&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;root_helper&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_root_helper&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;putils&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ProcessExecutionError&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;exc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;LOG&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;warning&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_LW&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"remove ECKD call for s390 failed exit"&lt;/span&gt;
                        &lt;span class="s2"&gt;" &lt;/span&gt;&lt;span class="si"&gt;%(code)s&lt;/span&gt;&lt;span class="s2"&gt;, stderr &lt;/span&gt;&lt;span class="si"&gt;%(stderr)s&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'code'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;exc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exit_code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'stderr'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;exc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Adaptations to volume.filters to allow the new commands to be sent&lt;/p&gt;
&lt;p&gt;Cinder drivers need to report the Control Unit address, and Unit Address
of the ECKD volume and set the driver_volume_type to ‘fibre_channel_eckd’&lt;/p&gt;
&lt;p&gt;Any drivers wishing to support FICON will need to have CI reporting results
from running against a FICON attached host.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;Nova blueprint to add support for ECKD for Linux on System z. The blueprint
can be found here:
&lt;a class="reference external" href="https://blueprints.launchpad.net/nova/+spec/linux-ficon-support"&gt;https://blueprints.launchpad.net/nova/+spec/linux-ficon-support&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit test:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit tests will be added and performed on System z, as well as
Intel-based machines.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;CI environment:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;We will provide a 3rd party CI environment for DS8000.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;We will update documentation as required.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Linux on System z Device Driver book,
&lt;a class="reference external" href="http://public.dhe.ibm.com/software/dw/linux390/docu/l316dd25.pdf"&gt;http://public.dhe.ibm.com/software/dw/linux390/docu/l316dd25.pdf&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Linux on System z,
&lt;a class="reference external" href="http://www.ibm.com/developerworks/linux/linux390/"&gt;http://www.ibm.com/developerworks/linux/linux390/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Tue, 25 Jan 2022 00:00:00 </pubDate></item><item><title>Use ‘LIKE’ operator to filter resource</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/pike/add-like-filter.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/support-regexp-based-query"&gt;https://blueprints.launchpad.net/cinder/+spec/support-regexp-based-query&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This blueprint proposes changing some filter behaviour to use ‘LIKE’
expression on some columns(name, description, etc).&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently, we could only filter cinder resource by exact match, and this is
not flexible enough when user would like to retrieve some resource whose name
or attribute is partly alike, especially for the users who have lots of
volumes. As it’s already introduced in many other projects, we can take
advantage of those some existing mechanism, &lt;a class="reference internal" href="#nova"&gt;nova&lt;/a&gt; and &lt;a class="reference internal" href="#ironic"&gt;ironic&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;Possible use case is to support client bulk operation, collect the
desired resources with single command.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Although we can provide filtering resource based on regex filter, but there
is a possibility that we could have &lt;a class="reference internal" href="#redos"&gt;ReDos&lt;/a&gt; attack. Considering the
‘LIKE’ operator is flexible and safe enough for this case. We could only
introduce ‘LIKE’ operator (‘NOT LIKE’ is another useful operator, but it’s
not as common as ‘LIKE’). And we can easily apply this filter at the
existing common filtering function individually with a decorator:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="nd"&gt;@apply_like_filters&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Volume&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;_process_volume_filters&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;filters&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;pass&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This spec intends to support ‘LIKE’ based filter on some specified resources
and columns, as we would have the generalized &lt;a class="reference internal" href="#resource-filtering"&gt;resource filtering&lt;/a&gt; feature,
this one will take advantage of that spec in order to make it
configurable for administrators, so this is what we would finally have in our
filters’ configuration file&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"volume_filters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"availability_zone"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"name~"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;‘~’ here means the attribute ‘name’ supports query with like operator (not
indicating the regex operator),  once this is configured, the input
key-value pair &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;name~=value&lt;/span&gt;&lt;/code&gt; from API will finally be translated into this
sql statement:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="c1"&gt;# '%' is automatically appended at both sides&lt;/span&gt;
&lt;span class="n"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;volumes&lt;/span&gt;
&lt;span class="n"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="n"&gt;LIKE&lt;/span&gt; &lt;span class="s1"&gt;'%value%'&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;so with that switch on, end user could filter volume with these inputs below:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;cinder&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;filters&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;volume_preserved&lt;/span&gt;   &lt;span class="c1"&gt;#exact matches&lt;/span&gt;
&lt;span class="n"&gt;cinder&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;filters&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;~=&lt;/span&gt;&lt;span class="n"&gt;volume_preserved&lt;/span&gt;  &lt;span class="c1"&gt;#inexact matches&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;assuming we have two volumes in the name of ‘volume_preserved_01’,
‘volume_preserved_02’, so with first command we will get none of
them while last command would have both of them.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;There is an option that we can deploy searchlight which mainly focus on
various cloud resource querying, and that’s a more widely topic. But we
should also consider the cloud environment that doesn’t have a
searchlight.&lt;/p&gt;
&lt;p&gt;Also, there is another option that user can gather all the raw data and
do the filtering on their own, but it’s obviously that that is what we try
to avoid, cause it costs a lot of unnecessary resource expense.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;Microversion bump is required for this change.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="cinder-client-impact"&gt;
&lt;h3&gt;Cinder-client impact&lt;/h3&gt;
&lt;p&gt;Help text will be updated to advertise this change.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;tommylikehu(&lt;a class="reference external" href="mailto:tommylikehu%40gmail.com"&gt;tommylikehu&lt;span&gt;@&lt;/span&gt;gmail&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Update the generalized resource filtering
logic to accept new symbol ‘~’ in config file.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update target object’s common filter method.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add related unit testcases&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update cinder-client and OSC.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;Depended on generalized &lt;a class="reference internal" href="#resource-filtering"&gt;resource filtering&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add unit tests to cover filter process change.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Update API documentation.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;&lt;span class="target" id="nova"&gt;nova&lt;/span&gt;: &lt;a class="reference external" href="https://review.openstack.org/#/c/45026/"&gt;https://review.openstack.org/#/c/45026/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class="target" id="ironic"&gt;ironic&lt;/span&gt;: &lt;a class="reference external" href="https://review.openstack.org/#/c/266688/"&gt;https://review.openstack.org/#/c/266688/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class="target" id="redos"&gt;reDos&lt;/span&gt;: &lt;a class="reference external" href="https://en.wikipedia.org/wiki/ReDoS"&gt;https://en.wikipedia.org/wiki/ReDoS&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class="target" id="resource-filtering"&gt;resource filtering&lt;/span&gt;: &lt;a class="reference external" href="https://review.openstack.org/#/c/441516/"&gt;https://review.openstack.org/#/c/441516/&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Tue, 25 Jan 2022 00:00:00 </pubDate></item><item><title>Support retrieve pools filtered by volume-type</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/pike/add-volume-type-filter-to-get-pools.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/add-volume-type-filter-to-get-pool"&gt;https://blueprints.launchpad.net/cinder/+spec/add-volume-type-filter-to-get-pool&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Add feature that administrators can get back-end storage pools filtered by
volume-type, cinder will return the pools filtered by volume-type’s
extra-specs.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Now cinder’s &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;get-pools&lt;/span&gt;&lt;/code&gt; API doesn’t support filtering pools by volume type,
and this is inconvenient when administrators want to know the specified pool’s
state which also can meet volume type’s requirements, the administrators also
can get all pools and filter them on their own, but it’s more complicated and
inefficient. This change intends to cover this situation and bring more
convenience to administrators.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;In production environment, administrators often need to have an overall
pool available statistics filtered by volume type, this will help them to make
an adjustment before resources run out.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;As we will introduce generalized resource filter in cinder, from the view of
outside cinder, the only thing we should do is to advertise that we can
support this filter now:&lt;/p&gt;
&lt;p&gt;From the view of inside cinder. We will mark &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volume-type&lt;/span&gt;&lt;/code&gt; recognizable, and
support for this filter in logic:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;once the volume-type (name or id) is detected, the volume type object will be
retrieved before scheduler api is called, and will be passed as a filter
item.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;scheduler.get_pools&lt;/span&gt;&lt;/code&gt; called, which will call the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;host_manager.get_pools&lt;/span&gt;&lt;/code&gt; in result.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;host_manager.get_pools&lt;/span&gt;&lt;/code&gt; will collect the pools information as normal,
and before it returns, the result will be filtered by
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;host.get_filtered_hosts&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;the filter properties of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;get_filtered_hosts&lt;/span&gt;&lt;/code&gt; only consists of volume-type
properties.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;As already proposed by generalized resource filtering &lt;a class="footnote-reference brackets" href="#id3" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, the changes on
cinder-client for this feature are not needed.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Administrators also can retrieve and filter on their own, but it’s more
complicated and inefficient. This change can reduce the request amount and
filter unnecessary data transmitted from server to client.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;Get-Pool API will accept new query string parameter volume-type.
Administrators can pass name or ID to retrieve pools filtered.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;GET&lt;/span&gt; &lt;span class="pre"&gt;/v3/{tenant_id}/scheduler-stats/get_pools?volume-type=lvm-default&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;Within generalized resource filtering, we would ultimately have a
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;get-pools&lt;/span&gt;&lt;/code&gt; command like this below:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;cinder&lt;/span&gt; &lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;pools&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;filters&lt;/span&gt; &lt;span class="n"&gt;volume&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'volume type'&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;TommyLike(&lt;a class="reference external" href="mailto:tommylikehu%40gmail.com"&gt;tommylikehu&lt;span&gt;@&lt;/span&gt;gmail&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add Get-Pools’s filter.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add filter logic when retrieving pools.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add related tests.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;Depended on generalized resource filtering &lt;a class="footnote-reference brackets" href="#id3" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Unit test to test whether volume-type filter can be correctly applied.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tempest test whether volume-type filter work correctly from API
perspective.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;The cinder API documentation will need to be updated to reflect the
REST API changes.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id3" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/441516/"&gt;https://review.openstack.org/#/c/441516/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Tue, 25 Jan 2022 00:00:00 </pubDate></item><item><title>Cinder volume revert to snapshot</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/pike/cinder-volume-revert-by-snapshot.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/revert-volume-to-snapshot"&gt;https://blueprints.launchpad.net/cinder/+spec/revert-volume-to-snapshot&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It makes sense to be able to revert a volume to a previously taken
snapshot. The revert function can be used to revert a volume to a previous
snapshot, restoring the volume to the state at the time the snapshot was
created. The feature supports reverting a volume to the most recent snapshot
taken, also manila (shared file system service) has already supported what
we are proposing in Ocata &lt;a class="footnote-reference brackets" href="#id3" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The revert process will overwrite the current state and data of the volume.
If the volume was extended after the snapshot, the request would be rejected
(reason is described in proposed change section). It’s assumed that the user
doing a revert is discarding the actual state and data of the volume.&lt;/p&gt;
&lt;p&gt;The purpose of this feature is to give users the possibility of recover
instances and volumes more conveniently and with minimal downtime.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently, a user can recover an instance by creating a volume from specified
snapshot and attaching it using the following workflow:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;User creates a volume(s)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;User attach volume to instance&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;User creates a snapshot&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Something happens (crash) causing the need of a revert&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;User creates a volume(s) from the snapshot(s)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;User detach old volumes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;User attach new volumes&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This workflow has the following problems:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;To create a volume from a snapshot, some of vendors need to copy data to the
new volume. This process takes more time than simply reverting to the most
recent snapshot.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To create a volume from a snapshot, the network configuration will change
and that leads to problems in most of applications demanding admin
intervention.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If the instance was created from a boot volume, initial customization
scripts might not be able to configure the instance to the same status it
was before the crash.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It consumes quota from the user and in some cases real space on the backend.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Another alternative is to restore the data from a backup, but that process
can’t be done by the cloud user, it’s not a common case (data inconsistency
is more likely the main cause), also, the end user would expect a less time
consuming operation.&lt;/p&gt;
&lt;p&gt;As mentioned above, we hope that can offer a way to recover instance quickly
using an easiest way, revert snapshot may be a good choice.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;The primary use case is the situation when an instance or volume crashes due
to any adverse situation, attack or malfunctioning while storage data is kept
alive. In this situation, the following workflow will be used:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;User creates a volume.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;User attaches the volume to instance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;User creates snapshots of safe points.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Something happens causing the need of a revert.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;User detaches the volume.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;User reverts to the safe snapshot(s).&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Theoretically, if multiple snapshots exist, a storage system could restore
a volume to any one of those snapshots. But revert a volume to a
snapshot which is not the latest one typically deletes the later snapshots,
which is a form of data loss and may not be what the user intends. So this
feature will limit cinder to revert the most recent volume snapshot known
to cinder.&lt;/p&gt;
&lt;p&gt;For this use case, reverting backwards in time starting with the most recent
snapshot makes sense. Only the user can determine whether a volume is usable
or must be reverted, so getting back to a good state is a manual iterative
process:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Observe&lt;/span&gt; &lt;span class="n"&gt;corruption&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;volume&lt;/span&gt;
&lt;span class="n"&gt;Revert&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;most&lt;/span&gt; &lt;span class="n"&gt;recent&lt;/span&gt; &lt;span class="n"&gt;snapshot&lt;/span&gt;
&lt;span class="n"&gt;While&lt;/span&gt; &lt;span class="n"&gt;corruption&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="n"&gt;present&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;volume&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;Delete&lt;/span&gt; &lt;span class="n"&gt;most&lt;/span&gt; &lt;span class="n"&gt;recent&lt;/span&gt; &lt;span class="n"&gt;snapshot&lt;/span&gt;
    &lt;span class="n"&gt;Revert&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;most&lt;/span&gt; &lt;span class="n"&gt;recent&lt;/span&gt; &lt;span class="n"&gt;snapshot&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;A suggestion with simple API which merely include the volume ID and allow
cinder to determine the most recent snapshot has been put forward, but it
could led to potential concurrency bugs:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;If two users call volume-revert-to-snapshot and snapshot-create at the
same time, the two calls race and one user could be surprised about
which snapshot was used to revert the volume.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;if two users call volume-revert-to-snapshot and snapshot-delete at the
same time, the calls race and someone may be surprised when the volume
is reverted to an even earlier snapshot than expected (which is a form
of data loss).&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;To keep the REST interface explicit, and to avoid the race conditions
described above, the interface will accept the ID of the snapshot to be
restored. cinder will verify that the snapshot is the most recent one via
the created_at field on the snapshot object, returning an error if not. At
no time will cinder delete any snapshots during the revert operation, and
it will not operate on any snapshot other than the one specified in the REST
call.&lt;/p&gt;
&lt;p&gt;There are two cases when reverting a volume, one is detached volume, and
the other is the attached volume. We would only support reverting a
detached volume.&lt;/p&gt;
&lt;p&gt;As we support extend volumes at present, we could meet the case that
snapshot is smaller than volume when reverting to snapshot and it’s obviously
safe to revert in that case. But we will still restrict to revert the volume
which current volume size is equal to snapshot, cause we don’t support shrink
volume yet &lt;a class="footnote-reference brackets" href="#id4" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; (that ability will be used in the generic method, if the
driver don’t support revert to snapshot).&lt;/p&gt;
&lt;p&gt;Therefore, we need to do the following changes in order to support volume
revert to snapshot.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Add volume revert to snapshot API&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;We will add a revert to snapshot API, in the API layer, the validations (
existence, status and size) on both snapshot and volume will be proceeded
along with whether the snapshot is the latest one.&lt;/p&gt;
&lt;p&gt;Cinder will accept the request only if the volume’s status is ‘available’.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Implement revert to snapshot in cinder volume service&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;During a snapshot restoration, there are two objects that are
affected whose status must be reflected. The volume’s status is
‘reverting’, the snapshot’s status is also ‘restoring’. Other
operations must not be allowed to either object during the
restoration.&lt;/p&gt;
&lt;p&gt;If the cinder driver can not support the revert feature, it will
use the generic implementation to run revert process.&lt;/p&gt;
&lt;p&gt;After a successful restoration, both objects’ status will again be set
to the status before reverting.  If the restoration fails, the volume
will be set to ‘error’, and the snapshot will be set to ‘available’.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Create snapshot for backup&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The volume’s revert process would possibly fail, in order to prevent
data loss, before the reverting process, we will create a snapshot
for backup and then delete it if the operation succeed, end users can
take advantage of that snapshot to recover their data.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Implement revert to snapshot in cinder drivers&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Add a function that vendors can use to overwrite the default
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;revert_to_snapshot&lt;/span&gt;&lt;/code&gt; function with an optimized version. Vendors can
implement the optimized version of the revert snapshot feature in their
drivers:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;revert_to_snapshot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;volume&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;snapshot&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="sd"&gt;"""Is called to perform revert volume from snapshot.&lt;/span&gt;

&lt;span class="sd"&gt;    :param context: Our working context.&lt;/span&gt;
&lt;span class="sd"&gt;    :param volume: the volume to be reverted.&lt;/span&gt;
&lt;span class="sd"&gt;    :param snapshot: the snapshot data revert to volume.&lt;/span&gt;
&lt;span class="sd"&gt;    :return None&lt;/span&gt;
&lt;span class="sd"&gt;    """&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Exception will be caught and stored if any inner error raised from
this function.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Add a generic revert to snapshot implementation function&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;If the cinder driver can not support the revert to snapshot feature,
the framework will use the generic way to implement the revert snapshot
feature.&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;create a temporary volume from snapshot (if the backend supports mount
snapshot, we will directly mount the snapshot, and don’t need to create
and mount the temporary volume anymore).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;mount temporary volume to host.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;copy data from temporary volume or snapshot to original volume.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;delete the temporary volume.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;There is an alternative that we can create a new volume from the snapshot
(already implemented and used). But this has some drawbacks as we described
in the ‘Problem description’ section.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement snapshot revert allowing revert to any snapshot the volume has.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;New status ‘reverting’ to volume object and new status ‘restoring’ to
snapshot object.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;Add a new revert action to volume action collections, the ‘volume_id’ and
‘snapshot_id’ are both required:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v3&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tenant_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;volumes&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;volume_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;

&lt;span class="n"&gt;Method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;POST&lt;/span&gt;

&lt;span class="n"&gt;Body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
           &lt;span class="s1"&gt;'revert'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
               &lt;span class="s1"&gt;'snapshot_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;snapshot_id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
           &lt;span class="p"&gt;}&lt;/span&gt;
       &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;Normal&lt;/span&gt; &lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Status&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="mi"&gt;202&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;empty&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;

&lt;span class="n"&gt;Error&lt;/span&gt; &lt;span class="n"&gt;responses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

&lt;span class="mf"&gt;1.&lt;/span&gt; &lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;volume&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;found&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="mf"&gt;2.&lt;/span&gt; &lt;span class="mi"&gt;409&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;volume&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;snapshot&lt;/span&gt;&lt;span class="s1"&gt;'s status are not '&lt;/span&gt;&lt;span class="n"&gt;available&lt;/span&gt;&lt;span class="s1"&gt;' or&lt;/span&gt;
   &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;sizes&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;volume&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;snapshot&lt;/span&gt; &lt;span class="n"&gt;are&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;equal&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="mf"&gt;3.&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;snapshot&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;found&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;belongs&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;specified&lt;/span&gt;
   &lt;span class="n"&gt;volume&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;latest&lt;/span&gt; &lt;span class="n"&gt;one&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Calling this method reverts a volume to the specified snapshot.
It is intended for both tenants and admins to use, and the policy.json
file will be updated to reflect allowed use by all.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;Notifications about the revert process(start, end, error) and
so does the related change notification will be add.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="cinder-client-impact"&gt;
&lt;h3&gt;Cinder-client impact&lt;/h3&gt;
&lt;p&gt;The cinder-client will add command to expose the revert API:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;usage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;cinder&lt;/span&gt; &lt;span class="n"&gt;revert&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;snapshot&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;snapshot&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="n"&gt;Revert&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;volume&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;specified&lt;/span&gt; &lt;span class="n"&gt;snapshot&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;

&lt;span class="n"&gt;snapshot&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;ID&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;snapshot&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;restore&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="openstack-client-impact"&gt;
&lt;h3&gt;OpenStack-client impact&lt;/h3&gt;
&lt;p&gt;The openstack-client will add command to expose the revert API:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;usage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;volume&lt;/span&gt; &lt;span class="n"&gt;snapshot&lt;/span&gt; &lt;span class="n"&gt;restore&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;snapshot&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="n"&gt;Revert&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;volume&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;specified&lt;/span&gt; &lt;span class="n"&gt;snapshot&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;

&lt;span class="n"&gt;snapshot&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;ID&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;snapshot&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;restore&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;This feature would also be implemented to cinder-ui.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;The in effect revert process might lock storage and consume a long time,
depending on the size of the volume.&lt;/p&gt;
&lt;p&gt;Determining which snapshot is the latest requires a database query that
sorts by a timestamp (the created_at field on the snapshot object). This
would be slightly slower than a query that does not care about result
ordering.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;There will be one new driver entry point &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;revert_to_snapshot&lt;/span&gt;&lt;/code&gt;, driver
maintainers can implement optimised version of this functionality.
Also driver should pay attention to this cases.&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;During the reverting process, the specified snapshot can’t be deleted
(this means the snapshot should be recreated in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;revert_to_snapshot&lt;/span&gt;&lt;/code&gt;
if that is deleted by the backend).&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;zhongjun(&lt;a class="reference external" href="mailto:jun.zhongjun2%40gmail.com"&gt;jun&lt;span&gt;.&lt;/span&gt;zhongjun2&lt;span&gt;@&lt;/span&gt;gmail&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;TommyLike(&lt;a class="reference external" href="mailto:tommylikehu%40gmail.com"&gt;tommylikehu&lt;span&gt;@&lt;/span&gt;gmail&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create APIs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create RPC calls&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add generic revert_to_snapshot function.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add revert_to_snapshot interface and lvm’s implementation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement unit test and functional test&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement tempest test&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement cinder client&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement OSC&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement cinder UI&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add API documents&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update develop reference and support matrix&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit tests and manual testing, as well as tempest test for these
proposed APIs.&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;To guarantee that a volume restore actually took place, a new scenario
test will be needed that writes data to a volume, creates a snapshot,
modifies the volume, restores the snapshot, and ensures the original data
is present in the volume.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To guarantee that this feature could work in the HA deploy mode.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;API Ref: Add content about the API.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add revert to snapshot feature to develop reference.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add RevertToSnapshot capability to cinder support matrix.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id3" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://specs.openstack.org/openstack/manila-specs/specs/ocata/manila-share-revert-to-snapshot.html"&gt;https://specs.openstack.org/openstack/manila-specs/specs/ocata/manila-share-revert-to-snapshot.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id4" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://wiki.openstack.org/wiki/CinderSupportMatrix"&gt;https://wiki.openstack.org/wiki/CinderSupportMatrix&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Tue, 25 Jan 2022 00:00:00 </pubDate></item><item><title>Explicit user messages</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/pike/explicit-user-messages.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/better-user-message"&gt;https://blueprints.launchpad.net/cinder/+spec/better-user-message&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Use ‘action’, ‘resource’, ‘message’ to replace ‘event’ in user messages.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;We have introduced user messages since Ocata, that’s a beneficial feature,
because it solves the problem that we don’t provide enough message when an
async task is failed (especially for volume and snapshot resources).
It’s easy to find out when and where the task failed with our new
messages APIs.&lt;/p&gt;
&lt;p&gt;But, the better user experience all depend on whether we have hard coded
enough user messages in our projects. So that raises a new question, how could
we add these messages without changing our code frequently and how could we
maintain this ‘better user experience but not functionality involved’ code
cleanly.&lt;/p&gt;
&lt;p&gt;Here are some of our user message related codes:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="c1"&gt;# CODE1: defined event ids&lt;/span&gt;
&lt;span class="n"&gt;UNKNOWN_ERROR&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'VOLUME_000001'&lt;/span&gt;
&lt;span class="n"&gt;UNABLE_TO_ALLOCATE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'VOLUME_000002'&lt;/span&gt;
&lt;span class="n"&gt;ATTACH_READONLY_VOLUME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'VOLUME_000003'&lt;/span&gt;
&lt;span class="n"&gt;IMAGE_FROM_VOLUME_OVER_QUOTA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'VOLUME_000004'&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="c1"&gt;# CODE2: try/except and write the user messages&lt;/span&gt;
&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;excutils&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;save_and_reraise_exception&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;exception&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ImageLimitExceeded&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;message_api&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;defined_messages&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EventIds&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IMAGE_FROM_VOLUME_OVER_QUOTA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;resource_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;resource_types&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;VOLUME&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;resource_uuid&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;volume_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;We would possibly have several issues if we try to add more user messages
based on those presets.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;[CODE1]: We would redefine a lot of similar event ids, such as
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;UNABLE_CREATE_VOLUME_DRIVER_NOT_READY&lt;/span&gt;&lt;/code&gt;,
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;UNABLE_CREATE_SNAPSHOT_DRIVER_NOT_READY&lt;/span&gt;&lt;/code&gt; and
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;UNABLE_CREATE_BACKUP_DRIVER_NOT_READY&lt;/span&gt;&lt;/code&gt;, it’s obvious that they are all
due to the same error and are created at same procedure (create resource).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[CODE2]: To have an explicit message, we would have a bunch of ‘if/else’
codes which only focus on detecting the error class and write down the
corresponding messages, and even worse if the exception gets more and more,
we have to update the code again and again.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So could we have a better way to fix these?&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;The main use-case here is for an explicit user message to end users and
a better maintaining experience for cinder developers.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;The proposed changes are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Introduce &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;message&lt;/span&gt;&lt;/code&gt; (or name it &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;detail&lt;/span&gt;&lt;/code&gt; to avoid confusion) to user
messages, the ‘message’ only represent what (no matter error or warning)
happened at that explicit time, that means &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;QUOTA_EXCEED&lt;/span&gt;&lt;/code&gt; is a valid one
while &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;UPLOAD_TO_IMAGE_OVER_QUOTA&lt;/span&gt;&lt;/code&gt; isn’t.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Build the relationship from exceptions to messages, we have a bunch of
exceptions which could directly point out what happened and how to fix,
but we couldn’t expose this to the end user because it would expose some
sensitive information. We couldn’t hard code the cleaned messages into
exceptions either, because the exceptions would be defined at different
places (take cinder exceptions and driver exceptions for example) and
different exceptions can be translated into one user messages. so this
is proposed how to do, build a dictionary from exception &lt;strong&gt;name&lt;/strong&gt; to
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;messages&lt;/span&gt;&lt;/code&gt; (introduced above):&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="c1"&gt;# multi_key dictionary&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'HBSDBusy'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'XtremIOArrayBusy'&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;MessageIds&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DEVICE_IS_BUSY&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'ConfigNotFound'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s1"&gt;'ViolinInvalidBackendConfig'&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;MessageIds&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;INVALID_CONFIGURATION&lt;/span&gt;

&lt;span class="n"&gt;message_map&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="n"&gt;MessageIds&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DEVICE_IS_BUSY&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Backend device is busy at present."&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="n"&gt;MessageIds&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;INVALID_CONFIGURATION&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Invalid configuration."&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Introduce &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;action&lt;/span&gt;&lt;/code&gt; to user messages. This one should be introduced along
with the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;messages&lt;/span&gt;&lt;/code&gt;, and can use it to indicate when the message is
created, such as &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;CREATE_SNAPSHOT_IN_BACKEND&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;UPLOAD_TO_IMAGE&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Generate &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;event_id&lt;/span&gt;&lt;/code&gt; automatically, user message is used to build user
friendly messages for project which directly display the information for
administrators. But when referring to the projects which detect, classify
and use our messages, the event_id is more useful at this case, so we should
have ‘event_id’ no matter how we change the underground behaviour. Instead
of manually define and maintain this event_ids we could build them by a
combination of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;RESOURCE&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ACTION&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;MESSAGE&lt;/span&gt;&lt;/code&gt;, take these for
example:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="c1"&gt;# This is how we define event currently&lt;/span&gt;
&lt;span class="n"&gt;IMAGE_FROM_VOLUME_OVER_QUOTA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'VOLUME_000004'&lt;/span&gt;

&lt;span class="c1"&gt;# This is how we would build the event_id at response after this change.&lt;/span&gt;
&lt;span class="n"&gt;VOLUME_BACKUP_001_0002&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="n"&gt;PROJECT&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;RESOURCE&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ACTION_ID&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;MESSAGE_ID&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;We could have these benefits:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;We don’t need to define that much events. (we only need to
define less messages).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It’s also unique cross all of OpenStack.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It’s reading friendly and easy to classify or analysis.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;The alternatives is we could keep adding user messages in the way of we
currently have &lt;a class="footnote-reference brackets" href="#id2" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. (There could be more alternatives or better solutions,
but I failed to figure out.)&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;Database update is required to store the ‘action_id’ and ‘message_id’, also
we can deprecate the ‘event_id’, because we could generate it anytime we
want.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;We don’t have API impact because we didn’t expose the create API.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;For a better experience, developers have to maintain the relationship
from exception to messages when any related change is made.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;tommylikehu(&lt;a class="reference external" href="mailto:tommylikehu%40gmail.com"&gt;tommylikehu&lt;span&gt;@&lt;/span&gt;gmail&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Upgrade database to reflect new user message object.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Support ‘exception’ and ‘action’ in user message APIs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add some unit tests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add script for database migration.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit tests&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Update developer documentation for ‘exception-to-message’ dictionary.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id2" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/298052/"&gt;https://review.openstack.org/#/c/298052/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Tue, 25 Jan 2022 00:00:00 </pubDate></item><item><title>Show resource’s total count info in list APIs</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/queens/add-count-info-in-list-response.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/add-amount-info-in-list-api"&gt;https://blueprints.launchpad.net/cinder/+spec/add-amount-info-in-list-api&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This blueprint proposes adding total count info in Cinder’s list APIs.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Show how many resources a user or tenant has is usually required in the web
portal’s summary section, but since we introduced the pagination mechanism,
we only could get the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;{resource}_link&lt;/span&gt;&lt;/code&gt; which tells us you have more
resources. In order to show this kind of total number to the end user, many
clouds have to collect all of the resources while they only have to display
the first page of the resource.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;The main use case is to have the administrators or users to know how many
resources they have in total without retrieving and accumulating them all.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Having the total count information in list API response is not only a
requirement for Cinder or OpenStack, it’s a common requirement for the
REST APIs, so find out what are others are doing may help us to have a
better API model for this case.&lt;/p&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;p&gt;Facebook API support the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;total_count&lt;/span&gt;&lt;/code&gt; attribute in their list
APIs &lt;a class="footnote-reference brackets" href="#id6" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. And this is their API response:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
  &lt;span class="s2"&gt;"paging"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt;
  &lt;span class="s2"&gt;"summary"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"total_count"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;JSON API org adds an example to demonstrate the usage of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;total-pages&lt;/span&gt;&lt;/code&gt; or
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;count&lt;/span&gt;&lt;/code&gt; in their recommended examples &lt;a class="footnote-reference brackets" href="#id7" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"meta"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"total-pages"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"count"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="s2"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
    &lt;span class="s2"&gt;"links"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"self"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"prev"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"next"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;StackExchange API also adds the total attribute in their
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Common&lt;/span&gt; &lt;span class="pre"&gt;Wrapper&lt;/span&gt; &lt;span class="pre"&gt;Object&lt;/span&gt;&lt;/code&gt; &lt;a class="footnote-reference brackets" href="#id8" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. And this is how their response
looks like:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="s2"&gt;"items"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
   &lt;span class="s2"&gt;"page"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="s2"&gt;"page_size"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="s2"&gt;"total"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Since we have already added the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;{resources}_links&lt;/span&gt;&lt;/code&gt; attribute into our list
API response. It makes more reasonable to have the amount info added into the
response (take volume for example):&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"volumes_links"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
  &lt;span class="s2"&gt;"volumes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
  &lt;span class="s2"&gt;"count"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;So, this bp proposes to add new attribute &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;count&lt;/span&gt;&lt;/code&gt; in our list APIs (
including index and detail).&lt;/p&gt;
&lt;p&gt;Based on our current pagination system &lt;a class="footnote-reference brackets" href="#id9" id="id4" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, if we add the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;count&lt;/span&gt;&lt;/code&gt;
attribute into our response body in default, the db’s query statement would
be executed twice for only one query which obviously has a performance
impact, considering not every request requires this kind of info, the
additional query parameter is required to turn this on when listing
resource:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;/v3/{tenant_id}/{resource}?with_count=true
/v3/{tenant_id}/{resource}/detail?with_count=true
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Also, this is recommended by OpenStack API-WG &lt;a class="footnote-reference brackets" href="#id10" id="id5" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;5&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For the first step we only plan to add the summary support for our main
resources: &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volumes&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;snapshots&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;backups&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;There are few alternative solutions for this requirement, let’s list and
compare them all here.&lt;/p&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;p&gt;Add amount information in response header:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The disadvantage of this is it will add some burden to the API customers,
we don’t have any history for adding useful content in response
headers. Also it makes more difficult for documentation.&lt;/p&gt;
&lt;ol class="arabic" start="2"&gt;
&lt;li&gt;&lt;p&gt;Add explicit API for each resources:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v3&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tenant_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This change involves a lot of modifications and creates several new APIs.
Adding this amount of APIs for such a simple API change is overdesign.&lt;/p&gt;
&lt;ol class="arabic" start="3"&gt;
&lt;li&gt;&lt;p&gt;Create a new API for different resources:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;V3&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tenant_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;BODY&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"volume"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"user_1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"other_filter"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"other_value"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For this change, one more API request is required if the end user wants to
know how many resources in total when listing resources.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;Microversion bump is required for this change.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="cinder-client-impact"&gt;
&lt;h3&gt;Cinder-client impact&lt;/h3&gt;
&lt;p&gt;All of the list commands will be upgraded to support this.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Since we will add additional &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;COUNT()&lt;/span&gt;&lt;/code&gt; statement if the list
APIs are requested with the summary option, there would be negative
performance impact on those APIs, especially when there are a lot
of data in database.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;tommylikehu(&lt;a class="reference external" href="mailto:tommylikehu%40gmail.com"&gt;tommylikehu&lt;span&gt;@&lt;/span&gt;gmail&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add summary option support in list APIs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add related unit testcases&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update cinder-client and OSC.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add unit tests to cover this change.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Update API documentation.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id6" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://developers.facebook.com/docs/graph-api/reference/v2.1/user/friends"&gt;https://developers.facebook.com/docs/graph-api/reference/v2.1/user/friends&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id7" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://jsonapi.org/examples/"&gt;http://jsonapi.org/examples/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id8" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id3"&gt;3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://api.stackexchange.com/docs/wrapper"&gt;https://api.stackexchange.com/docs/wrapper&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id9" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id4"&gt;4&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/cinder/blob/master/cinder/db/sqlalchemy/api.py#L2324"&gt;https://github.com/openstack/cinder/blob/master/cinder/db/sqlalchemy/api.py#L2324&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id10" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id5"&gt;5&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/api-wg/blob/64e3e9b07272f50353429dc51d98524642ab6d67/guidelines/counting.rst"&gt;https://github.com/openstack/api-wg/blob/64e3e9b07272f50353429dc51d98524642ab6d67/guidelines/counting.rst&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Tue, 25 Jan 2022 00:00:00 </pubDate></item><item><title>Support create volume from backup</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/queens/create-volume-from-backup.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/support-create-volume-from-backup"&gt;https://blueprints.launchpad.net/cinder/+spec/support-create-volume-from-backup&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This blueprint proposes support for creating a volume from backup.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Cinder has supported create volume from volume, snapshot and image.
But when considering create volume from backup, users have to create a
new volume first and then restore the volume with backup. Although
we can restore backup without volume id, in that case Cinder will
create a new volume in the background, but we still have some issues
because we don’t have any access to control the volume’s az, volume
type, size and many other attributes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;User can directly create volume from backup rather than create a new volume
and then restore it.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;This spec proposes to support create volume from backup, after this change
users can directly create a new volume with backup id as below:&lt;/p&gt;
&lt;div class="highlight-bash notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;$&lt;span class="w"&gt; &lt;/span&gt;cinder&lt;span class="w"&gt; &lt;/span&gt;create&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;size&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;--backup-id&lt;span class="w"&gt; &lt;/span&gt;&amp;lt;id&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;other_options&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Volume’s size is equal to the backup’s original volume size if size
option is omitted.&lt;/p&gt;
&lt;p&gt;Since we already introduced the generic backup implementation &lt;a class="footnote-reference brackets" href="#id3" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; for our
existing volume drivers, it makes sense to add this ability to our volume
drivers, so when create volume from backup, the request will be scheduled
to the volume backend as normal, and first we would try the vendor-specific
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;create_volume_from_backup&lt;/span&gt;&lt;/code&gt; method as below:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;create_volume_from_backup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;volume&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;backup&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="sd"&gt;"""Creates a volume from a backup."""&lt;/span&gt;

    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="ne"&gt;NotImplementedError&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;If the driver reports &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;NotImplemented&lt;/span&gt;&lt;/code&gt; or &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;NotSupported&lt;/span&gt;&lt;/code&gt;, Cinder will
directly create the raw volume at the backend and then schedule the request
to the backup service to restore the volume with backup.&lt;/p&gt;
&lt;p&gt;One of the differences between creating volume from snapshot and
creating volume from backup is the latter could be time consuming, so we need
to update the backup’s status to prevent possible usages by other requests.
For instance, when creating volume from backup the possible status for volume
and backup are:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="mf"&gt;1.&lt;/span&gt; &lt;span class="n"&gt;Volume&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;creating&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;available&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;
&lt;span class="mf"&gt;2.&lt;/span&gt; &lt;span class="n"&gt;Backup&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;restoring&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;available&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: We will use ‘creating’ instead of ‘restoring-backup’ for the
volume’s transition status here in order not to expose the creating detail.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Keep using current restore API or create and restore mechanism to cover
this use case.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;Microversion bump is required for this change.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="cinder-client-impact"&gt;
&lt;h3&gt;Cinder-client impact&lt;/h3&gt;
&lt;p&gt;Cinder-client will be updated to support create volume from backup.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;When creating a volume from backup and the vendor-specific method does
not exist, the creation process could take a little longer than
a typical creation due to the restore action.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Primary assignee:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;luqitao (&lt;a class="reference external" href="mailto:qtlu%40fiberhome.com"&gt;qtlu&lt;span&gt;@&lt;/span&gt;fiberhome&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;tommylikehu(&lt;a class="reference external" href="mailto:tommylikehu%40gmail.com"&gt;tommylikehu&lt;span&gt;@&lt;/span&gt;gmail&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Support create volume from backup in Cinder.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add related unit testcases.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add related tempest testcase.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update cinder-client and OSC.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;Depends on generic backup implementation &lt;a class="footnote-reference brackets" href="#id3" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add unit tests to cover creating volume from backup.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Both API documentation and CLI documentation should be updated.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id3" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/cinder-specs/blob/master/specs/queens/generic-backup-implementation.rst"&gt;https://github.com/openstack/cinder-specs/blob/master/specs/queens/generic-backup-implementation.rst&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Tue, 25 Jan 2022 00:00:00 </pubDate></item><item><title>Support availability zone in volume type</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/rocky/support-az-in-volume-type.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/support-az-in-volumetype"&gt;https://blueprints.launchpad.net/cinder/+spec/support-az-in-volumetype&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This blueprint proposes to support setting a volume type’s availability zones.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;In a newly deployed region environment, the volume type (SSD, HDD or others)
may only exist on part of the AZs, but end users have no idea which AZ is
allowed for one specific volume type and they can’t realize that only when
the volume failed to be scheduled to backend.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;Administrators can update the available AZs for volume type and UI or end
users can know valid volume types in current AZ.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;As the discussion result during Rocky PTG &lt;a class="footnote-reference brackets" href="#id2" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, we would propose to use
volume type’s &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;extra&lt;/span&gt; &lt;span class="pre"&gt;specs&lt;/span&gt;&lt;/code&gt; to support this. Since &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;extra&lt;/span&gt; &lt;span class="pre"&gt;specs&lt;/span&gt;&lt;/code&gt; is
designed for generic use, we would propose to introduce a reserved key
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;os-extended:availability_zones&lt;/span&gt;&lt;/code&gt; for extra specs. Administrator can
create/update this attribute in the format as below to support AZ in
volume type:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="s2"&gt;"volume_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"6685584b-1eac-4da6-b5c3-555430cf68ff"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"az_type"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"availability zone type 001"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"is_public"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"extra_specs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"os-extended:availability_zones"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"az1,az2,az3"&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: Our capability filter will skip any extra spec which has
key in the format of “prefix:key_name”.
Since this use case is more related to UI or other endpoint concerns, we
would also propose to support filter volume type via extra specs as well:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;Request example:
/v3/{project_id}/types?extra_specs={'os-extended:availability_zones':'az1'}
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Also, it’s mentionable that the extra spec availability zones will be
handled in a slightly different way when compared with the rest during
filtering. Cinder will always try inexact match for this specific value,
for instance, when extra spec &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;os-extended:availability_zones&lt;/span&gt;&lt;/code&gt; is set
as below, both &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;az1&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;az2&lt;/span&gt;&lt;/code&gt; are valid input for query:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="s2"&gt;"os-extended:availability_zones"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"az1,az2,az3"&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;In order to fully support type’s AZ in Cinder, there are also some changes
on Cinder framework.&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Now the intersection of AZs between volume type’s and other inputs (user
input, source resource or default configuration) will be calculated when
creating a new volume and 400 Bad Request will be raised if this
intersection is empty.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It’s possible now we could pass an AZ list to the scheduler when creating
or retyping, workflow and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;AvailabilityZoneFilter&lt;/span&gt;&lt;/code&gt; will be updated
to support this.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: Cinder will raise 400 Bad Request as well if type’s
availability_zones attribute is set but value is empty.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;p&gt;Now Cinder supports filter volume type with extra specs:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;GET: /V3/{tenant_id}/types?extra_specs={'spec_name':'spec_value'}

Response BODY:
{
    "volume_types": [{
        "name": "volume_type1",
        "description": "volume_type1",
        "extra_specs": {"spec_name": "spec_value"},
    }]
}
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;API version bump will be required for these changes.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="cinder-client-impact"&gt;
&lt;h3&gt;Cinder-client impact&lt;/h3&gt;
&lt;p&gt;Volume type’s CLIs will be updated corresponding to the API change
at server side.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;There would be a slight performance impact when filtering volume types
with extra specs.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;tommylikehu(&lt;a class="reference external" href="mailto:tommylikehu%40gmail.com"&gt;tommylikehu&lt;span&gt;@&lt;/span&gt;gmail&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Support availability zone and extra spec filtering in volume type API.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update cinder workflow to support availability zone lists.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add related unit testcases.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update cinderclient to support filter volume type with extra specs.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add unit tests to cover this change.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Update the API reference.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add administrator documentation to advertise the reserved key
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;os-extended:availability_zones&lt;/span&gt;&lt;/code&gt; and explain why&amp;amp;when&amp;amp;how
should this can be used.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id2" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://etherpad.openstack.org/p/cinder-ptg-rocky-wednesday"&gt;https://etherpad.openstack.org/p/cinder-ptg-rocky-wednesday&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Tue, 25 Jan 2022 00:00:00 </pubDate></item><item><title>Support filter backend based on operation type</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/rocky/support-filter-backend-on-operation-type.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/support-mark-pool-sold-out"&gt;https://blueprints.launchpad.net/cinder/+spec/support-mark-pool-sold-out&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This blueprint proposes to support filter backend based on operation type.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Now our filter and weigher plugins’ algorithm are all designed based on
two factors, backend information and user input. But there could be
another factor that may also affect the scheduler result, operation
type. For instance, if administrators want to disable some of the
backend pool only for creating new volume operation, it’s impossible
based on our current logic.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;We have discussed the concept of &lt;strong&gt;sold out&lt;/strong&gt; during Rocky PTG &lt;a class="footnote-reference brackets" href="#id2" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; and
that word is more related to administrative operation, when most of an
specific pool’s capacity has been consumed, administrators need the
functionality to mark the backend pool sold out, that is to say, it
will become unavailable for allocating new volumes, but end users still
can perform any operations on their existing resources (extend volume,
create snapshot).&lt;/p&gt;
&lt;p&gt;Adding this feature in cinder will help cloud vendors write their
own plugins which can filter backend based on the operation type as well
as backend information.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;New attribute &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;operation&lt;/span&gt;&lt;/code&gt; will be added into &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;RequestSpec&lt;/span&gt;&lt;/code&gt; object
and plugins can filter backend based on backend states as well as
request type:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;backend_passes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;backend_state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;filter_properties&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;#get request type from filter_properties&lt;/span&gt;
    &lt;span class="n"&gt;spec&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;filter_properties&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'request_spec'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt;
    &lt;span class="n"&gt;request_type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;spec&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'operation'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;request_type&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'create_volume'&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
        &lt;span class="c1"&gt;#check backend state when request is for creating new volume&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;backend_state&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;free_capacity_gb&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;MIN_REQUIRED_GB&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;request_type&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'extend_volume'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'retype_volume'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="c1"&gt;#perform other validation when request is ......&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: This spec doesn’t propose to update any plugin’s logic, the code
above only intends to demonstrate how the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;operation&lt;/span&gt;&lt;/code&gt; can be used.&lt;/p&gt;
&lt;p&gt;Based on our current features, the value of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;operation&lt;/span&gt;&lt;/code&gt; can be one of
these below:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;create_group&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;manage_existing&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;extend_volume&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;create_volume&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;create_snapshot&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;migrate_volume&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;retype_volume&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;manage_existing_snapshot&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;And we will inject scheduler manager’s corresponding methods in order to
append this info to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;RequestSpec&lt;/span&gt;&lt;/code&gt; automatically:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="nd"&gt;@append_operation&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;extend_volume&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;volume&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;new_size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reservations&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="n"&gt;request_spec&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;filter_properties&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;#other existing codes&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;The alternative is to implement a custom scheduler manager and configure it
in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;scheduler_manager&lt;/span&gt;&lt;/code&gt; and then use either a custom filter or the JSON
filter.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;RequestSpec&lt;/span&gt;&lt;/code&gt; will be updated to store this new attribute.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="cinder-client-impact"&gt;
&lt;h3&gt;Cinder-client impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Developers can develop new scheduler plugins based
on backend state as well as request type.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;tommylikehu(&lt;a class="reference external" href="mailto:tommylikehu%40gmail.com"&gt;tommylikehu&lt;span&gt;@&lt;/span&gt;gmail&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;operation&lt;/span&gt;&lt;/code&gt; to those actions which will be scheduled
to scheduler to perform filtering and weighing logic.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add unit tests to cover this change.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Update the developer document to mention the new attribute
will be delivered to scheduler plugins as well.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id2" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://etherpad.openstack.org/p/cinder-ptg-rocky-wednesday"&gt;https://etherpad.openstack.org/p/cinder-ptg-rocky-wednesday&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/308869/"&gt;https://review.openstack.org/#/c/308869/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Tue, 25 Jan 2022 00:00:00 </pubDate></item><item><title>Support Image Signature Verification</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/rocky/support-image-signature-verification.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/cinder-support-image-signing"&gt;https://blueprints.launchpad.net/cinder/+spec/cinder-support-image-signing&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Cinder currently does not support signature validation of downloaded signed
images. Equipping Cinder with the ability to validate image signatures will
provide end users with stronger assurances of the integrity of the image data
they are using to create volumes. This change will use the same data model for
image metadata as the accompanying functionality in Glance, which will allow
the end user to sign images and verify these image signatures upon
upload &lt;a class="footnote-reference brackets" href="#id9" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Previously, OpenStack’s protection against unexpected modification of images
was limited to verifying an MD5 checksum. While this may be sufficient for
protecting against accidental modifications, MD5 is a hash function, not an
authentication primitive &lt;a class="footnote-reference brackets" href="#id10" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, and thus provides no protection against
deliberate, malicious modification of images. An image could potentially be
modified in transit, such as when it is uploaded to Glance or transferred to
Cinder. An image that is modified could include malicious code.&lt;/p&gt;
&lt;p&gt;Currently, Glance has support for image signature verification upon upload,
but Cinder does not support the feature to ensure the integrity of the image
data before using it. Providing support for signature verification would allow
Cinder to verify the signature before creating volume from image. This feature
will secure OpenStack against the following attack scenarios:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Man-in-the-Middle Attack - An adversary with access to the network between
Cinder and Glance is altering image data as Cinder downloads the data from
Glance. The adversary is potentially incorporating malware into the image
and/or altering the image metadata.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Untrusted Glance - In a hybrid cloud deployment, Glance is hosted on
machines which are located in a physically insecure location or is hosted by
a company with limited security infrastructure. Adversaries may be able to
compromise the integrity of Glance and/or the integrity of images stored by
Glance through physical access to the host machines or through poor network
security on the part of the company hosting Glance.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Please note that our threat model considers only threats to the integrity of
images while they are in transit between the end user and Glance, while they
are at rest in Glance and while they are in transit between Glance and Cinder.
This threat model does not include, and this feature therefore does not
address, threats to the integrity, availability, or confidentiality of Cinder.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;A user wants a high degree of assurance that a customized image which they
have uploaded to Glance has not been accidentally or maliciously modified
prior to creating a volume from the image.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With this proposed change, Cinder will verify the signature of a signed image
while downloading that image. If the image signature cannot be verified, then
Cinder will not create a volume from the image and instead place the volume
into an error state. The user will begin to use this feature by uploading the
image and the image signature metadata to Glance via the Glance API’s
image-create method. The required image signature metadata properties are as
follows:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;img_signature - A string representation of the base 64 encoding of the
signature of the image data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;img_signature_hash_method - A string designating the hash method used for
signing. Currently, the supported values are  SHA-224, SHA-256, SHA-384 and
SHA-512. MD5 and other cryptographically weak hash methods will not be
supported for this field. Any image signed with an unsupported hash
algorithm will not pass validation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;img_signature_key_type - A string designating the signature scheme used to
generate the signature. For more detail on which are currently supported,
please check Glance’s documentation &lt;a class="footnote-reference brackets" href="#id15" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;7&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;img_signature_certificate_uuid - A string encoding the certificate
uuid used to retrieve the certificate from the key manager.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The image verification functionality in Glance uses the
cursive.signature_utils module to verify this signature metadata before
storing the image. If the signature is not valid or the metadata is
incomplete, this API method will return a 400 error status and put
the image into a “killed” state. Note that, if the signature metadata
is simply not present, the image will be stored as it would normally.&lt;/p&gt;
&lt;p&gt;The user would then create a volume from this image using the Cinder API’s
volume create method. If the verify_glance_signatures flag in cinder.conf is
set to ‘True’, Cinder will call out to Glance for the image’s properties,
which include the properties necessary for image signature verification.
Cinder will pass the image data and image properties to the signature
verification module, which will verify the signature. If signature
verification fails, or if the image signature metadata is either incomplete
or absent, creating volume from the image will fail and Cinder will log an
exception. If signature verification succeeds, Cinder will create volume
from the image and log a message indicating that image signature verification
succeeded along with detailed information about the signing certificate.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Since Nova has implemented this feature and all of the verification process
has been moved into &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cursive&lt;/span&gt;&lt;/code&gt; module &lt;a class="footnote-reference brackets" href="#id12" id="id4" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, it’s more convenient to support
this in Cinder now.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Verify image signature with certificate&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;We propose an initial implementation by incorporating &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cursive&lt;/span&gt;&lt;/code&gt; into
Cinder’s control flow for Creating volumes from images, and use new
configuration &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;verify_glance_signatures&lt;/span&gt;&lt;/code&gt; to turn this on or off.
Initially it will have two options (default is &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;enabled&lt;/span&gt;&lt;/code&gt;):&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;enabled&lt;/span&gt;&lt;/code&gt;: verify when image has complete signature metadata.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;disabled&lt;/span&gt;&lt;/code&gt;: verification is turned off.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: We have discussed to add &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;required&lt;/span&gt;&lt;/code&gt; option to introduce a
strict mode on verification, but this can’t be guaranteed as we can’t
do verification when image volume is cloned in backend. Strict mode will
still be considered when we can cover every approach.&lt;/p&gt;
&lt;p&gt;Upon downloading an image, Cinder will both check the new configuration
flag and image’s metadata. If needs, the module will perform image signature
verification using image properties passed to Cinder by Glance. If this fails,
or if the image signature metadata is incomplete or missing, Cinder will not
create the volume from the image. Instead, Cinder will throw an exception and
log an error. If the signature verification succeeds, Cinder will proceed with
creating the volume. The code sample is below:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;CONF&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;glance&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;verify_glance_signatures&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s1"&gt;'disabled'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
   &lt;span class="n"&gt;verifier&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;
   &lt;span class="n"&gt;image_meta_dict&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;show&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;image_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                               &lt;span class="n"&gt;include_locations&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="n"&gt;image_meta&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ImageMeta&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image_meta_dict&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="n"&gt;img_signature&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;image_meta&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'img_signature'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="n"&gt;img_sig_hash_method&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;image_meta&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
       &lt;span class="s1"&gt;'img_signature_hash_method'&lt;/span&gt;
   &lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="n"&gt;img_sig_cert_uuid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;image_meta&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
       &lt;span class="s1"&gt;'img_signature_certificate_uuid'&lt;/span&gt;
   &lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="n"&gt;img_sig_key_type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;image_meta&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
       &lt;span class="s1"&gt;'img_signature_key_type'&lt;/span&gt;
   &lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
       &lt;span class="n"&gt;verifier&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;signature_utils&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_verifier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
           &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="n"&gt;img_signature_certificate_uuid&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;img_sig_cert_uuid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="n"&gt;img_signature_hash_method&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;img_sig_hash_method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="n"&gt;img_signature&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;img_signature&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="n"&gt;img_signature_key_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;img_sig_key_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;cursive_exception&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SignatureVerificationError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
       &lt;span class="c1"&gt;#Image signature verification failed&lt;/span&gt;
   &lt;span class="c1"&gt;# Collect image data&lt;/span&gt;
   &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
       &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;verifier&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
           &lt;span class="n"&gt;verifier&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;verify&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
   &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;cryptography&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exceptions&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InvalidSignature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
       &lt;span class="c1"&gt;#Image signature verification failed&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: We will try different approaches when
creating volume from images, so we have to mention
this feature will not cover every approach especially
when volume is created at backend.&lt;/p&gt;
&lt;p&gt;To be clear, we will verify the image’s signature only when
image is downloaded from glance and content is copied to
volume on host. So when image volume is created via
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;clone_image&lt;/span&gt;&lt;/code&gt; or &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;clone_image_volume&lt;/span&gt;&lt;/code&gt; we will skip this
verification process regardless of configuration option and
provided signature metadata, in order not to confuse end users,
we will add verification flag &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;signature_verified&lt;/span&gt;&lt;/code&gt; in volume’s
image metadata when creating from image.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Verify certificate with trusted certificates&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This feature tries to find a way to determine if the certificate
used to generate and verify that signature is a certificate that
is trusted by the user, we could find more detail in Nova spec &lt;a class="footnote-reference brackets" href="#id13" id="id5" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;5&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.
In short, within that feature end user can also validate the image’s
certificate with the given trusted certificates (specified via API
or config option).
Considering the feature is in the process of being added to Nova
now, we will follow this up with another spec when it’s merged
into Nova for the purpose of consistency.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;An alternative to signing the image’s data directly is to support signatures
which are created by signing a hash of the image data. This introduces
unnecessary complexity to the feature by requiring an additonal hashing stage
and an additional metadata option. Due to the Glance community’s performance
concerns associated with hashing image data, the developers initially pursued
an implementation which produced the signature by signing an MD5 checksum
which was already computed by Glance. This approach was rejected by the Nova
community due to the security weaknesses of MD5 and the unnecessary complexity
of performing a hashing operation twice and maintaining information about both
hash algorithms.&lt;/p&gt;
&lt;p&gt;An alternative to using certificates for signing and signature verification
would be to use a public key. However, this approach presents the significant
weakness that an attacker could generate their own public key in the key
manager, use this to sign a tampered image, and pass the reference to their
public key to Cinder along with their signed image. Alternatively, the use of
certificates provides a means of attributing such attacks to the certificate
owner, and follows common cryptographic standards by placing the root of trust
at the certificate authority.&lt;/p&gt;
&lt;p&gt;An alternative to using the verify_glance_signatures configuration flag to
specify that Cinder should perform image signature verification is to use
a “verify_glance_signatures” type-key for a volume type to specify that
individual volume should be created from signed images. The user, when using
the Cinder CLI to create a volume from image, would specify a volume type
which includes a type-key “verify_glance_signatures=True” to indicate that
image signature verification should occur as part of the control flow for
creating the volume. This may be added in a later change, but will not be
included in the initial implementation. If added, the
“verify_glance_signatures” type-key option will work alongside the
configuration option approach. In this case, Cinder would perform image
signature verification if either the configuration flag is set, or if the user
has specified creating a volume of the volume type which includes
“verify_glance_signatures=True” type-key.&lt;/p&gt;
&lt;p&gt;Another alternative to using the verify_glance_signatures configuration flag
to specify that Cinder should perform image signature verification is amending
the Cinder create command to accept an additional parameter specifying whether
image signature verification should occur. This may be added in a later
change, but will not be included in the initial implementation. If added, the
additional parameter will work alongside the configuration option approach.
In this case, Cinder would perform image signature verification if either the
configuration flag is set, or if the user has specified creating a volume of
the additional parameter.&lt;/p&gt;
&lt;p&gt;We maybe only need to choose one of the above two alternatives.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;The accompanying work in Glance introduced additional Glance image properties
necessary for image signing. The initial implementation in Cinder will
introduce a configuration flag indicating whether Cinder should perform image
signature verification before booting an image.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;Cinder currently lacks a mechanism to validate images prior to creating
volumes from them. The checksum included with an image protects against
accidental modifications but provides little protection against an adversary
with access to Glance or to the communication network between Cinder and
Glance. This feature facilitates the creation of a logical trust boundary
between Cinder and Glance; this trust boundary permits the end user to have
high assurance that Cinder is creating a volume from an image signed by a
trusted user.&lt;/p&gt;
&lt;p&gt;Although Cinder will use certificates to perform this task, the certificates
will be stored by a key manager and accessed via Castellan.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;This change will involve adding log messages to indicate the success or
failure of signature verification and creation.&lt;/p&gt;
&lt;p&gt;A later change will involve notifying the user about failure in case signature
verification fails, this will use async error notification feature &lt;a class="footnote-reference brackets" href="#id11" id="id6" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;If the verification of a signature fails, then Cinder will not create a
volume from the image, and an error message will be logged and recorded.
The user can get the error messages through the log file or CLI command,
and know the reason for the error. In this case, the user will have to
edit the image’s metadata through the Glance API, or the Horizon interface;
or reinitiate an upload of the image to Glance with the correct signature
metadata in order to create a volume from the image.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;This feature will only be used if the verify_glance_signatures configuration
flag is set.&lt;/p&gt;
&lt;p&gt;When signature verification occurs there will be latency as a result of
retrieving certificates from the key manager through the Castellan interface.
There will also be CPU overhead associated with hashing the image data and
decrypting a signature using a public key.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;We will recommend you deploy Barbican service &lt;a class="footnote-reference brackets" href="#id14" id="id7" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;6&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; to store your
certificate information as other projects suggest, although you can integrate
any other secret manager service via Castellan &lt;a class="footnote-reference brackets" href="#id16" id="id8" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;8&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;ji-xuepeng
TommyLike(&lt;a class="reference external" href="mailto:tommylikehu%40gmail.com"&gt;tommylikehu&lt;span&gt;@&lt;/span&gt;gmail&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;)&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;None&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;The feature will be implemented in the following stages:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add functionality to Cinder which calls the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cursive&lt;/span&gt;&lt;/code&gt; module when Cinder
downloads a Glance image and the verify_glance_signatures configuration flag
is set.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Generate notification messages at the time of failure for signature
verification.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit tests and also, tempest tests will be added into
barbican-tempest-plugin to cover the case of create
volume from signed image.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Instructions for how to use this functionality will need to be documented.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;Cryptography API: &lt;a class="reference external" href="https://pypi.org/project/cryptography/0.2.2"&gt;https://pypi.org/project/cryptography/0.2.2&lt;/a&gt;&lt;/p&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id9" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/252462/"&gt;https://review.openstack.org/#/c/252462/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id10" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://en.wikipedia.org/wiki/MD5#Security"&gt;https://en.wikipedia.org/wiki/MD5#Security&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id11" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id6"&gt;3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/summarymessage"&gt;https://blueprints.launchpad.net/cinder/+spec/summarymessage&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id12" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id4"&gt;4&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://git.openstack.org/cgit/openstack/cursive"&gt;https://git.openstack.org/cgit/openstack/cursive&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id13" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id5"&gt;5&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://specs.openstack.org/openstack/nova-specs/specs/queens/approved/nova-validate-certificates.html"&gt;http://specs.openstack.org/openstack/nova-specs/specs/queens/approved/nova-validate-certificates.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id14" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id7"&gt;6&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://docs.openstack.org/barbican/latest/"&gt;https://docs.openstack.org/barbican/latest/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id15" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id3"&gt;7&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://docs.openstack.org/glance/pike/user/signature.html"&gt;https://docs.openstack.org/glance/pike/user/signature.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id16" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id8"&gt;8&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://wiki.openstack.org/wiki/Castellan"&gt;https://wiki.openstack.org/wiki/Castellan&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Tue, 25 Jan 2022 00:00:00 </pubDate></item><item><title>Support deferred volume deletion in the RBD driver</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/stein/support-deferred-deletion-in-rbd.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/rbd-deferred-volume-deletion"&gt;https://blueprints.launchpad.net/cinder/+spec/rbd-deferred-volume-deletion&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This spec proposes configurable support for deferred volume deletion in the
RBD driver, using the trash_* API calls, as introduced with the Luminous
version of Ceph.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Volume deletion in Cinder is synchronous: the c-vol worker thread deleting
a volume will return only when the backend confirmed the removal of the
volume. This approach ensures that the space used on the backend will at
most be equal to the quota of the corresponding project, and hence allows
for proper resource management. The current implementation of the RBD
driver follows this approach by using RBD’s ‘remove()’ API call.&lt;/p&gt;
&lt;p&gt;For deployments with thousands of volumes/users and large volumes (10-100TB)
this can create two potential issues:&lt;/p&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;p&gt;a c-vol worker thread will be blocked during deletion and depending
on the size of the volume, the speed of the backend, the number of
concurrent requests, and the total number of worker threads, this may
block other operations, makes the service seem unresponsive, and can
lead to timeouts.&lt;/p&gt;
&lt;p&gt;[1] was proposed to mitigate this problem by making the number of
native threads configurable and profit more efficiently from the
backend’s potential capabilities.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;users have to wait until the deletion is completed on the backend
before they can re-use the freed up quota/space – despite having
signalled to Cinder that the volume should be removed and the quota
be freed. For large volumes, this waiting time can be significant
(hours for large volumes) and has hence a corresponding negative
impact on the user experience.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;To address these issues, this spec proposes to optionally support
asynchronous volume deletion in the RBD driver.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;Administrators can optionally enable a deferred deletion: the Ceph backend
will acknowledge the deletion immediately adressing the two issues above.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;The proposal is to&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;amend the RBD driver to support deferred deletion by optionally calling
RBD’s ‘trash_move()’ rather than RBD’s ‘remove()’ in the driver’s
implementation of ‘delete_volume()’;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;add a periodic timer in the RBD driver to trigger a regular purge.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For this, the following additional config options would be needed:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;‘enable_deferred_deletion’ (default: ‘False’)&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;If enabled, RBD’s ‘thrash_move’ will be called rather than ‘remove’.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;‘deferred_deletion_delay’ (default: 0)&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Number of seconds before an image moved to trash is regarded as expired
and can be purged.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;‘deferred_deletion_purge_interval’ (default: 3600)&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Number of seconds between runs of the periodic timer to purge the
backend’s trash.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="cinder-client-impact"&gt;
&lt;h3&gt;Cinder-client impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;For the end users, deletions will appear to be instantaneous. The freed
up quota will become available immediately.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Volume deletions will become independent from the backend’s speed or the
size of the volumes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;As the deletion is deferred, the space occupied will not be freed immediately.
Deployers need to be aware that the maximum space needed can exceed the sum
of the allocated quota of all projects.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Arne Wiebalck (&lt;a class="reference external" href="mailto:arne.wiebalck%40cern.ch"&gt;arne&lt;span&gt;.&lt;/span&gt;wiebalck&lt;span&gt;@&lt;/span&gt;cern&lt;span&gt;.&lt;/span&gt;ch&lt;/a&gt;)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Update RBD driver to respect options for deferred deletions and
call ‘trash_move’ if enabled.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add periodic task to call ‘trash_purge’ for backend which have
deferred deletion enabled.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add related unit testcases.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add unit tests to cover this change.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add administrator documentation to advertise the option of deferred
deletions for RBD and explain why&amp;amp;when&amp;amp;how this should be used,
emphasizing in particular that by enabling this option the space of
deleted volumes will not be freed on the RBD backend until the trash
is purged.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/550858/"&gt;https://review.openstack.org/#/c/550858/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Tue, 25 Jan 2022 00:00:00 </pubDate></item><item><title>Remove the need for project_id from API endpoints</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/yoga/project-id-optional-in-urls.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/project-id-optional-in-urls"&gt;https://blueprints.launchpad.net/cinder/+spec/project-id-optional-in-urls&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Cinder currently assumes API URLs include an associated project_id. Including
a project_id in the URL is redundant because the project_id is typically
available in the keystone context for the API request. In addition, requiring
a project_id is incompatible with keystone’s notion of system scope, in which
an API is not associated with a specific project. System scoped API requests
will not have a project_id, and therefore the URL for those requests should
not include a project_id.&lt;/p&gt;
&lt;p&gt;Furthermore, cinder’s inclusion of a project_id in its API URLs is out of sync
with other OpenStack services. The Images (glance API v2), Compute (nova API
as of v2.16), Identity (keystone API v3) and Shared File Systems (manila API
as of v2.60) services do not require a project_id in their API URLs.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;A cloud administrator wishes to utilize keystone personas in order to grant
appropriate access permissions to users that are assigned to different roles,
e.g. lab operators and project administrators. Lab personnel are typically
required to manage system-wide cinder resources, such a storage backends and
volume types. However, these personnel should not have access to project
specific resources, such as the cinder volumes. Likewise, project
administrators need the ability to manage the resources owned by projects for
which they have been given responsibility, but should have limited access to
system wide resources, such as the ability to configure volume types.&lt;/p&gt;
&lt;p&gt;In order to support system scoped personas, the URL for API requests should
not be required to include a project_id.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;This spec proposes the cinder API be enhanced to not require a project_id in
the API’s URL. Inclusion of a project_id in the URL would be optional, which
means the proposed change retains backward compatibility. A new microversion
will be introduced so that clients may know whether inclusion of a project_id
in API URLs is optional or mandatory.&lt;/p&gt;
&lt;p&gt;The microversion will only be used as an indicator that the API can handle
URLs without project IDs, and this applies to all requests reqardless of the
microversion in the request.  For example, if the new proposed microversion is
v3.67, an API node serving v3.67 or greater will properly route requests
without project_id even if you ask for v3.0.  Likewise, it will properly route
requests to URLs containing project_id even if you ask for v3.67.&lt;/p&gt;
&lt;p&gt;The proposal does not introduce any behavioral or functional changes to the
API. The same API method will be invoked regardless of whether the URL
includes a project_id, and the actual project_id associated with the call will
be the one contained in the keystone context for the API request. The current
behavior of returning HTTP 400 will be retained if the request URL contains a
project_id that doesn’t match the one in the keystone context.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;A dummy project_id value (perhaps all zeroes) could be defined for use by
system scoped API requests. This would not be an elegant solution, and would
require changes in keystone.&lt;/p&gt;
&lt;p&gt;Cloud administrators could be required to create an actual project solely for
use when making system scoped API requests. This is also not elegant, a shifts
the burden of managing system scope onto cloud administrators.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;The behavior of each API method will be unchanged. However, the API routing
will be enhanced to provide duplicate routes to each method.&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;The existing route for which a project_id is in the URL&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A new route for when the URL does not include a project_id&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;There is no security impact because keystone will continue to provide an
authorization context for every API request, regardless of whether the request
URL includes a project_id.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="active-active-ha-impact"&gt;
&lt;h3&gt;Active/Active HA impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;End users typically interact with the cinder API through other clients, such
as the python-cinderclient, python-openstackclient, or openstacksdk. In that
regard, there is no direct impact on the end user.&lt;/p&gt;
&lt;p&gt;End users who interact with the API directly using tools such as &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;curl&lt;/span&gt;&lt;/code&gt; may
continue to include a project_id in the URL. They will have the option of not
including a project_id in the URL.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;Deployment tools that create cinder endpoints in the keystone catalog no
longer need to use project_id templating. Endpoints in the catalog should look
like this:&lt;/p&gt;
&lt;div class="highlight-console notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="gp"&gt;$ &lt;/span&gt;openstack&lt;span class="w"&gt; &lt;/span&gt;endpoint&lt;span class="w"&gt; &lt;/span&gt;list&lt;span class="w"&gt; &lt;/span&gt;--service&lt;span class="w"&gt; &lt;/span&gt;cinderv3&lt;span class="w"&gt; &lt;/span&gt;-c&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'Service Name'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-c&lt;span class="w"&gt; &lt;/span&gt;URL
&lt;span class="go"&gt;+--------------+---------------------------------+&lt;/span&gt;
&lt;span class="go"&gt;| Service Name | URL                             |&lt;/span&gt;
&lt;span class="go"&gt;+--------------+---------------------------------+&lt;/span&gt;
&lt;span class="go"&gt;| cinderv3     | http://192.168.100.30/volume/v3 |&lt;/span&gt;
&lt;span class="go"&gt;+--------------+---------------------------------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;rather than this:&lt;/p&gt;
&lt;div class="highlight-console notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="gp"&gt;$ &lt;/span&gt;openstack&lt;span class="w"&gt; &lt;/span&gt;endpoint&lt;span class="w"&gt; &lt;/span&gt;list&lt;span class="w"&gt; &lt;/span&gt;--service&lt;span class="w"&gt; &lt;/span&gt;cinderv3&lt;span class="w"&gt; &lt;/span&gt;-c&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'Service Name'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-c&lt;span class="w"&gt; &lt;/span&gt;URL
&lt;span class="go"&gt;+--------------+------------------------------------------------+&lt;/span&gt;
&lt;span class="go"&gt;| Service Name | URL                                            |&lt;/span&gt;
&lt;span class="go"&gt;+--------------+------------------------------------------------+&lt;/span&gt;
&lt;span class="go"&gt;| cinderv3     | http://192.168.100.30/volume/v3/$(project_id)s |&lt;/span&gt;
&lt;span class="go"&gt;+--------------+------------------------------------------------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Primary assignee: abishop&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Define a new microversion&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add API routes to connect API requests with no project_id in the URL to the
associated method&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add or enhance unit tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update devstack so the cinder endpoint doesn’t use project_id templating&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Existing tempest tests will certainly verify whether the API functions
correctly. The challenge is verifying both the legacy behavior, where URLs
include a project_id, and the new behavior when URLs don’t include a
project_id. One possiblity is to employ a periodic zuul job that specifically
tests the legacy behavior. The details can be worked out during the
development phase.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;The existing API reference is largely unaffected. This is because the
reference guide is unbranched, and older versions of cinder require a
project_id. A brief note will be added to explain the project_id in the API
reference is optional as of the new microversion.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;OpenStack’s &lt;a class="reference external" href="https://review.opendev.org/c/openstack/governance/+/815158"&gt;Support Common Operator &amp;amp; End User Personas&lt;/a&gt; community goal&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cinder’s &lt;a class="reference external" href="https://review.opendev.org/c/openstack/cinder-specs/+/809741"&gt;Secure RBAC Ready&lt;/a&gt; spec&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Thu, 11 Nov 2021 00:00:00 </pubDate></item><item><title>NVMeoF Multipathing</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/yoga/nvme-multipath.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/nvmeof-multipath"&gt;https://blueprints.launchpad.net/cinder/+spec/nvmeof-multipath&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Extend the NVMeoF connector to support two types of multipathing:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Native NVMeoF multipathing&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DeviceMapper based multipathing&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;At the time of writing, only TCP and RDMA protocols are supported and
contemplated by the spec (so it does not contemplate the case for other
transport protocols such as FC).&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently the NVMeoF connector only supports single pathed connections.&lt;/p&gt;
&lt;p&gt;The problem description can be summed up by the statement:
A single pathed connection is a single point of failure.&lt;/p&gt;
&lt;p&gt;For resiliency, and to catch up with industry standards, support for
multi pathed connections is needed, mitigating the single point of failure.&lt;/p&gt;
&lt;p&gt;Another potential benefit is performance while maintaining replication, such
as in cases where there is synchronous replication on the backend, and the
multipath mechanism can switch on failure.&lt;/p&gt;
&lt;p&gt;This can be done in either of two ways:&lt;/p&gt;
&lt;p&gt;NVMeoF ANA (Asynchronous Namespace Access) is the NVMeoF native way of doing
multipathing, and it offers an interesting set of features.
A spec is available for more under-the-hood details &lt;a class="footnote-reference brackets" href="#id2" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Using DeviceMapper for multipathing is an industry standard approach (while
NVMeoF ANA support is not yet) with connections such as iSCSI, and can be
equally utilized with NVMeoF connections.
The goal of DM component of this spec’s implementation is to bring the NVMeoF
connector up to speed with using DeviceMapper for multipathed connections.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;Whether via native multipath or DeviceMapper, the use case is the ability to
expose multipathed connections to volumes, mitigating connection single point
of failure and improving performance.&lt;/p&gt;
&lt;p&gt;For example, an NVMeoF volume has two paths (portals) and a multipath
connection is established to it. If one of the paths breaks (such as in a
partial network failure) - the attached device would remain functional,
whereas with single pathed connections, the device would become unavailable
to the host it was attached to.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;The multipathing implementation will be broken up into its two main component
features - Native and DM multipathing:&lt;/p&gt;
&lt;section id="phase-1-native"&gt;
&lt;h3&gt;Phase 1 (Native)&lt;/h3&gt;
&lt;p&gt;The NVMeoF connector will check the host’s multipath capability and report
it in the connector properties passed to the volume driver, this will also
allow any driver / backend specific handling.&lt;/p&gt;
&lt;p&gt;The value of &lt;cite&gt;/sys/module/nvme_core/parameters/multipath&lt;/cite&gt; can be &lt;cite&gt;Y&lt;/cite&gt; or &lt;cite&gt;N&lt;/cite&gt; -
this should be returned as a True or False &lt;cite&gt;nvme_native_multipath&lt;/cite&gt; property in
&lt;cite&gt;get_connector_properties&lt;/cite&gt; method from the &lt;cite&gt;NVMeOFConnector&lt;/cite&gt; connector class.&lt;/p&gt;
&lt;p&gt;The “new” NVMeoF connector API (introduced in Wallaby) supports passing
multiple portals for the same NVMeoF device. Currently only the first
successful connection is established.&lt;/p&gt;
&lt;p&gt;In multipath mode, the portals connection method should simply connect to
all portals by running the &lt;cite&gt;nvme connect&lt;/cite&gt; cli command for each one.&lt;/p&gt;
&lt;p&gt;The NVMe system under the hood will create invisible devices for each of the
portal connections, and expose a single multipath device on top of them.&lt;/p&gt;
&lt;p&gt;It should be noted that the native multipath spec requires the target portals
to expose the device under the same target NQN and namespace id for multipath
to happen. (This is the backend’s responsibility and should be transparent to
OpenStack code)&lt;/p&gt;
&lt;p&gt;Finally, the new device will be matched by its uuid as is already implemented
in the baseline single path connector.&lt;/p&gt;
&lt;p&gt;The connection information for a native multipath volume will look like:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'vol_uuid'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'...someuuid...'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'target_nqn'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'...somenqn...'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'portals'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'10.1.1.1'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4420&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'tcp'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'10.1.1.2'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4420&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'tcp'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Regarding &lt;cite&gt;enforce_multipath&lt;/cite&gt; - it is a DeviceMapper multipathing parameter
and it will not have any interaction with the native NVMe multipathing.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="phase-2-devicemapper"&gt;
&lt;h3&gt;Phase 2 (DeviceMapper)&lt;/h3&gt;
&lt;p&gt;For DeviceMapper multipathing, use &lt;cite&gt;dm_replicas&lt;/cite&gt; in the connection information
to specify all the replicas. This approach allows for multiple NQNs for one
synced volume, which is often a requirement for DM-based multipathing.&lt;/p&gt;
&lt;p&gt;&lt;cite&gt;dm_replicas&lt;/cite&gt; cannot be used together with &lt;cite&gt;volume_replicas&lt;/cite&gt; which is for RAID
replication only. The drivers should know not to pass that. If both are
passed, the operation should fail.&lt;/p&gt;
&lt;p&gt;As in the baseline connector, connect to all &lt;cite&gt;dm_replicas&lt;/cite&gt; (it is worth
mentioning that each replica could have multiple portals, essentially allowing
this DeviceMapper aggregation to run on top of native multipath devices)&lt;/p&gt;
&lt;p&gt;Once connections are established, DeviceMapper will handle the multipathing
under the hood (should be transparent to OpenStack code)&lt;/p&gt;
&lt;p&gt;DeviceMapper needs to recognize that two devices should be “merged”
It does so based on device id information
Therefore, it is the responsibility of the backend to expose devices with
id information that conforms to the device matching requirements
of DeviceMapper.&lt;/p&gt;
&lt;p&gt;Since DeviceMapper recognizes two devices should be “merged” based on device
id information (udev?) - it is the responsiblity of the backend to handle its
exposed devices to conform to the requirement.&lt;/p&gt;
&lt;p&gt;The connection information for a DeviceMapper multipath volume will look like:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'vol_uuid'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'...someuuid...'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'dm_replicas'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s1"&gt;'vol_uuid'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'...someuuid1...'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'target_nqn'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'...somenqn1...'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'portals'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="s1"&gt;'10.1.1.1'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4420&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'tcp'&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s1"&gt;'vol_uuid'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'...someuuid2...'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'target_nqn'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'...somenqn2...'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'portals'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="s1"&gt;'10.1.1.2'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4420&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'tcp'&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="connector-api-summary"&gt;
&lt;h3&gt;Connector API Summary&lt;/h3&gt;
&lt;p&gt;With this proposal, there will be multiple replication and/or multipath mode
permutations of operation for the connector:
- Single pathed connection
- Native multipathed connection
- RAID connection (single or multipathed)
- DeviceMapper connection (single or native multipath)&lt;/p&gt;
&lt;p&gt;Note: RAID on top of DM is not allowed as it is inconsistent with the
connection information API (and would need an unnecessary overcomplication of
it as well as the physical implementation). It could theoretically be added
one day based on need, but it is overkill on multiple levels.&lt;/p&gt;
&lt;p&gt;Single path connection information for cinder driver:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'vol_uuid'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'...someuuid...'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'target_nqn'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'...somenqn...'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'portals'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="s1"&gt;'10.1.1.1'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4420&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'tcp'&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Connection information for cinder driver that supports native multipathed
connections (os-brick will iterate them if a single path connection is
requested):&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'vol_uuid'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'...someuuid...'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'target_nqn'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'...somenqn...'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'portals'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'10.1.1.1'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4420&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'tcp'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'10.1.1.2'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4420&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'tcp'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;For DeviceMapper, the example below is given with no native multipath for the
replica devices. For these replica devices to do native multipathing, portals
for each of each device’s paths should be specified in the &lt;cite&gt;portals&lt;/cite&gt; list.&lt;/p&gt;
&lt;p&gt;Connection information for DeviceMapper:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'vol_uuid'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'...someuuid...'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'dm_replicas'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s1"&gt;'vol_uuid'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'...someuuid1...'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'target_nqn'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'...somenqn1...'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'portals'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="s1"&gt;'10.1.1.1'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4420&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'tcp'&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s1"&gt;'vol_uuid'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'...someuuid2...'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'target_nqn'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'...somenqn2...'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'portals'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="s1"&gt;'10.1.1.2'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4420&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'tcp'&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h2&gt;Alternatives&lt;/h2&gt;
&lt;p&gt;Both alternative for NVMeoF multipathing that I am aware of are described
in this spec: Native and DeviceMapper&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h2&gt;Data model impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h2&gt;REST API impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h2&gt;Security impact&lt;/h2&gt;
&lt;p&gt;Same as the baseline NVMeoF connector:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Sudo executions of &lt;cite&gt;nvme&lt;/cite&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;div class="line-block"&gt;
&lt;div class="line"&gt;Needs access for reading of root filesystem paths such as:&lt;/div&gt;
&lt;div class="line"&gt;&lt;cite&gt;/sys/class/nvme-fabrics/…&lt;/cite&gt;&lt;/div&gt;
&lt;div class="line"&gt;&lt;cite&gt;/sys/class/block/…&lt;/cite&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="active-active-ha-impact"&gt;
&lt;h2&gt;Active/Active HA impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h2&gt;Notifications impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h2&gt;Other end user impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h2&gt;Performance Impact&lt;/h2&gt;
&lt;p&gt;The main benefit is of increased I/O while maintaining replication - such as
in a synchronous replication active-passive failover multipath configuration.&lt;/p&gt;
&lt;p&gt;One performance impact should happen during attachments on the host, where
now multiple NVMeoF devices (rather than just one) would need to be connected,
and a new device exposed on top of them.&lt;/p&gt;
&lt;p&gt;Depending on the mode of multipath connection (for example active-active vs
active-passive) - there could be an increase in network resource usage for
the multipath device io.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h2&gt;Other deployer impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h2&gt;Developer impact&lt;/h2&gt;
&lt;p&gt;Driver developers that want to use NVMeoF will need to be aware of the
connector API - specifically the connection_information spec described&lt;/p&gt;
&lt;p&gt;It is also worth mentioning that storage backends (although transparent to
OpenStack code) will need to keep in mind the system level requirements
for whichever multipath mode they use (Native or DeviceMapper)&lt;/p&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Zohar Mamedov (zoharm)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Anyone Else&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;Phase 1 (Native):&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Connector properties check kernel supports native multipath&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Establish all (multiple) necessary connections to multipath volume and ensure
proper device is exposed.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Phase 2 (DeviceMapper):&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Ensure all sync replicated devices are connected.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ensure the proper DeviceMapper device is exposed.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;Baseline dependencies are same as baseline single pathed connector:
relevant nvmeof kernel modules, and nvme-cli&lt;/p&gt;
&lt;p&gt;For native NVMe multipathing, the kernel needs to support it&lt;/p&gt;
&lt;p&gt;For DeviceMapper multipathing, DeviceMapper needs to be operational&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit tests.
Also there is an upcoming gate job that will use LVM to test NVMeoF (where
multipath testing for it can be included there)&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Document the new connection_information API described in this spec - especially
for drivers to be able to follow and use it.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id2" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;ANA Spec - Section 8.1.3: &lt;a class="reference external" href="https://nvmexpress.org/wp-content/uploads/NVMe-NVM-Express-2.0a-2021.07.26-Ratified.pdf"&gt;https://nvmexpress.org/wp-content/uploads/NVMe-NVM-Express-2.0a-2021.07.26-Ratified.pdf&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Wed, 27 Oct 2021 00:00:00 </pubDate></item><item><title>Optimze upload volume to image for RBD backend</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/yoga/optimize-upload-volume-to-rbd-store.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/optimize-upload-volume-to-rbd-store"&gt;https://blueprints.launchpad.net/cinder/+spec/optimize-upload-volume-to-rbd-store&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This spec proposes to optimize the upload volume to image operation from cinder
rbd backend to glance rbd store by using COW cloning.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently when doing a upload volume to image operation and the source (cinder)
and destination (glance) backends are rbd, we don’t have any optimization
and the generic code path to copy data chunk by chunk is executed.
This can be improved by doing a COW clone as we do it incase of creating volume
from image &lt;a class="footnote-reference brackets" href="#id4" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;We want to improve the performance when uploading a volume from cinder rbd backend
to glance rbd store using COW cloning.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;The changes will be needed on both glance and cinder side.&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Glance&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Expose store type and rbd specific store info (like rbd pool name for glance
in this case) via stores info API &lt;a class="footnote-reference brackets" href="#id5" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.
This can be extended to other stores by providing store specific details with
the stores info API like we do with get pools API &lt;a class="footnote-reference brackets" href="#id6" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; on cinder side.
Further information regarding its implementation can be provided with a
glance side spec.&lt;/p&gt;
&lt;ol class="arabic simple" start="2"&gt;
&lt;li&gt;&lt;p&gt;Cinder&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Get the stores info from Glance and find the default store.
If the glance default store is &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;rbd&lt;/span&gt;&lt;/code&gt; and cinder is using &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;rbd&lt;/span&gt;&lt;/code&gt; backend to
upload the volume to image then we will proceed with the COW clone operation
from the volume pool to the images pool (pool name provided by glance) and
register the image location on glance side.&lt;/p&gt;
&lt;p&gt;We will also introduce a new config parameter &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;enable_clone_optimization&lt;/span&gt;&lt;/code&gt; to
enable/disable this optimization on cinder side. More information about it
can be found in &lt;a class="reference internal" href="#security-impact"&gt;Security impact&lt;/a&gt; section.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h2&gt;Alternatives&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h2&gt;Data model impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h2&gt;REST API impact&lt;/h2&gt;
&lt;p&gt;None. This is RBD driver specific feature.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h2&gt;Security impact&lt;/h2&gt;
&lt;p&gt;Since this optimization skips the writing of image that happens on the glance side, it will
also skip the checksum and hash value calculated in that scenario.
We will introduce a new config parameter &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;enable_clone_optimization&lt;/span&gt;&lt;/code&gt; to enable/disable
this optimization and also mention the security risks that comes with enabling it. By default,
it will be disabled.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="active-active-ha-impact"&gt;
&lt;h2&gt;Active/Active HA impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h2&gt;Notifications impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h2&gt;Other end user impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h2&gt;Performance Impact&lt;/h2&gt;
&lt;p&gt;Uploading volume to image in case of cinder RBD to glance RBD will be
significantly improved.&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Image size&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;2GB&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;3GB&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;5GB&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Time without COW clone&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;1min17Sec&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;1min15Sec&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;2min49Sec&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Time with COW clone&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;1.29Sec&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;2.32Sec&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;1.63Sec&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td/&gt;
&lt;td&gt;&lt;p&gt;&lt;strong&gt;-98%&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;strong&gt;-97%&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;strong&gt;-99%&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h2&gt;Other deployer impact&lt;/h2&gt;
&lt;p&gt;The Cinder service user will need to have read and write to the Glance pool.
Note that Read access might already be granted and only write access needs
to be provided.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h2&gt;Developer impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Rajat Dhasmana (whoami-rajat)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Query glance for stores info (After exposing details from glance side)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Do a COW clone if the volume to be uploaded is in glance RBD store
(volume is uploaded in glance default store)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h3&gt;Dependencies&lt;/h3&gt;
&lt;p&gt;Glance side changes are required to expose store type and RBD store info
like glance pool name.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h3&gt;Testing&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Unit tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tempest or manual testing for checking if RBD image dependency blocks
deletion of source resource&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Upload volume to image&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete the original volume&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;AND&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Upload volume to image&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create volume from image&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete the image&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h3&gt;Documentation Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id4" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://opendev.org/openstack/cinder/commit/edc11101cbc06bdce95b10cfd00a4849f6c01b33"&gt;https://opendev.org/openstack/cinder/commit/edc11101cbc06bdce95b10cfd00a4849f6c01b33&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id5" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://docs.openstack.org/api-ref/image/v2/index.html?expanded=list-stores-detail#list-stores"&gt;https://docs.openstack.org/api-ref/image/v2/index.html?expanded=list-stores-detail#list-stores&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id6" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id3"&gt;3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://docs.openstack.org/api-ref/block-storage/v3/?expanded=list-all-back-end-storage-pools-detail#list-all-back-end-storage-pools"&gt;https://docs.openstack.org/api-ref/block-storage/v3/?expanded=list-all-back-end-storage-pools-detail#list-all-back-end-storage-pools&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Wed, 22 Sep 2021 00:00:00 </pubDate></item><item><title>Make Cinder Consistent and Secure RBAC Ready</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/xena/s-rbac-ready.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/s-rbac-ready-x"&gt;https://blueprints.launchpad.net/cinder/+spec/s-rbac-ready-x&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Revise Cinder’s policy definitions to support the community-wide
Consistent and Secure RBAC effort.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Cinder policies currently rely only on roles and don’t recognize scope, which
was introduced into Keystone in Queens.  As a result, implementing something
like an administrator who can only perform nondestructive actions in Cinder
is very complicated and error-prone.
(See, for example, &lt;a class="reference external" href="https://docs.openstack.org/cinder/latest/configuration/block-storage/policy-config-HOWTO.html"&gt;Policy configuration HowTo&lt;/a&gt;
in the Cinder documentation.)&lt;/p&gt;
&lt;p&gt;Using token scope and other Keystone Queens-era improvements such as role
inheritance, it is possible to define policy rules that recognize a set of
useful “personas”.  If all OpenStack services define policy rules to support
this (which is the “consistent” part), operators will not have to rewrite
policies in an attempt to create such personas themselves, but can instead
use tested default policies (which is the “secure” part).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;Some examples:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;An operator wants to have an administrator who can perform only
nondestructive actions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;An operator wants to have different levels of end user in each project
(for example, a “project administrator” who can do more in the project
than just a “project member”).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Make changes to the cinder default policies so that the default configuration
recognizes the keystone ‘reader’ role and treats it appropriately.  This will
entail rewriting all policies that don’t govern “Admin API” calls.&lt;/p&gt;
&lt;p&gt;For Xena, we’ll implement three personas using project-scope only.  What
this means is that any cinder user must have a role on a project in order
to pass policy checks.  This is basically what we have now, except that
we’ll distinguish the ‘member’ role on a project as distinct from a ‘reader’
role on a project.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;What exactly “personas” are and what they can do relative to the Block
Storage API are described in the &lt;a class="reference external" href="https://docs.openstack.org/cinder/xena/configuration/block-storage/policy-personas.html"&gt;Policy Personas and Permissions&lt;/a&gt;
document.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Additionally, we’ll address the following issues:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;New tests will need to be added, because previously we only needed to
distinguish between a “cinder administrator” and an “end user”, whereas now
we’ll have to make distinctions between a larger number of “personas” who can
make API calls.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We currently have some unrestricted policies (that is, the check string is
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;""&lt;/span&gt;&lt;/code&gt;).  Their checkstrings will be rewritten to something more specific and
appropriate.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We currently have some single policies that govern create, read, update,
and delete operations on cinder resources.  These will need to be split
up into finer-grained policies so that a user with only a ‘reader’ role
can read a resource without modifying it.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;See the “Implementation Strategy” outlined in the &lt;a class="reference external" href="https://docs.openstack.org/cinder/xena/configuration/block-storage/policy-personas.html"&gt;Policy Personas and
Permissions&lt;/a&gt; for more details.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Do nothing.  This is not really an option, however, because in order to keep
backward compatibility with legacy policy configuration, it’s not possible
for some projects to use scoping and others to ignore it.  So if we don’t
upgrade our policy definitions, we will block all OpenStack clouds from
being able to use Consistent and Secure Policies.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;The ability to make various Block Storage API calls is already governed by
policies.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;Overall this should improve security by presenting operators a suitable
set of “personas” that will function consistently across project that they
can use out of the box instead of implementing their own.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="active-active-ha-impact"&gt;
&lt;h3&gt;Active/Active HA impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None, we already have to make calls out to keystone to validate tokens
and retrieve user privileges.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None, other than doing the implementation work.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;lbragstad
rosmaita&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;tosky
enriquetaso
abishop
eharney
geguileo
whoami-rajat
jobernar&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Natural language description of the (eventual) default configuration. This
will be helpful to operators, but has also located some deficiencies in
the current cinder policies. It also gives us something against which to
validate tests of the default policies.
&lt;a class="reference external" href="https://review.opendev.org/c/openstack/cinder/+/763306"&gt;https://review.opendev.org/c/openstack/cinder/+/763306&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Policy update patches:
&lt;a class="reference external" href="https://review.opendev.org/q/project:openstack/cinder+topic:secure-rbac"&gt;https://review.opendev.org/q/project:openstack/cinder+topic:secure-rbac&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing patches. Groundwork patch is
&lt;a class="reference external" href="https://review.opendev.org/c/openstack/cinder/+/805316"&gt;https://review.opendev.org/c/openstack/cinder/+/805316&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;We’ll work with the current structure in cinder of individual files
in the cinder/policies directory for specific sets of policies, and
add the tests to the same patch where the policies are redefined.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tempest testing. Groundwork patch is
&lt;a class="reference external" href="https://review.opendev.org/c/openstack/cinder-tempest-plugin/+/772915"&gt;https://review.opendev.org/c/openstack/cinder-tempest-plugin/+/772915&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Initial test patches:
&lt;a class="reference external" href="https://review.opendev.org/q/project:openstack/cinder-tempest-plugin+topic:secure-rbac"&gt;https://review.opendev.org/q/project:openstack/cinder-tempest-plugin+topic:secure-rbac&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None, the required changes in Keystone and oslo.policy merged long ago.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;We’ll need a flexible testing framework because we are going from 2
personas in Wallaby to 3 personas in Xena to 5 personas in Yoga, and
we will need to be sure that the deprecated policy checkstrings continue
to work appropriately until they are removed.  Thus some kind of
ddt-based approach where we have some base tests and run all the
different kinds of users through them makes a lot of sense.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;As a stretch goal, because of the complexity of the policy configuration,
it would be good to have testing in the cinder-tempest-plugin so that each
persona can be tested against a real Keystone instance.  This would also
allow using tempest for testing the consistency of the Secure and Consistent
RBAC across openstack projects.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;The primary documentation for Cinder will be:
&lt;a class="reference external" href="https://review.opendev.org/c/openstack/cinder/+/763306"&gt;https://review.opendev.org/c/openstack/cinder/+/763306&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;We expect that there will be more general documentation for operators
in the Keystone docs given the OpenStack-wide nature of this effort.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;Summary of the general status of the effort at the time of the Xena
PTG, including links to more information:
&lt;a class="reference external" href="http://lists.openstack.org/pipermail/openstack-discuss/2021-April/022117.html"&gt;http://lists.openstack.org/pipermail/openstack-discuss/2021-April/022117.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;What the personas are and how they are intended to work in Cinder are
described in &lt;a class="reference external" href="https://review.opendev.org/c/openstack/cinder/+/763306"&gt;https://review.opendev.org/c/openstack/cinder/+/763306&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Fri, 17 Sep 2021 00:00:00 </pubDate></item><item><title>Add volume re-image API</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/yoga/add-volume-re-image-api.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/add-volume-re-image-api"&gt;https://blueprints.launchpad.net/cinder/+spec/add-volume-re-image-api&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This blueprint proposes to add volume re-image API to enable the ability to
re-image a specific volume.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently, users can create a volume with a specific image, but once this
volume is created, the image of this volume can’t be changed anymore. If users
want to re-image a specific volume, they can only create a new volume with new
image, and then delete the old volume, which is not very convenient. However,
if the image-backed volume is already used as a boot volume which is already
attached to a server, it makes the case more complicated, because changing the
image in an attached root volume is &lt;a class="reference external" href="https://review.openstack.org/#/c/520660/"&gt;not supported&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In addition, as mentioned in nova spec ‘volume-backend-server-rebuild’ &lt;a class="footnote-reference brackets" href="#id5" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;,
if users want to rebuild a volume-backed server, they can complete it by using
re-image API, this way there is no new volume with new volume id, we don’t
have to worry about types, quota problem, etc.&lt;/p&gt;
&lt;p&gt;As the discussion result during Yoga PTG &lt;a class="footnote-reference brackets" href="#id6" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, the idea still makes sense and
we would propose to implement a new API to support this.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The user wants to re-image a volume without re-creating a new volume with new
volume id.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Nova wants a new API to re-image an attached root volume when the server is
rebuilt.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;This spec proposes to add a new ‘os-reimage’ action to volume actions API.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add a new ‘os-reimage’ action to volume actions API.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The request will be rejected if cinder microversion is not new enough to
support ‘os-reimage’ action.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As mentioned above, the main purpose of this spec is for Nova’s rebuild use
case. When Nova calls cinder for re-image then cinder will perform these following
steps:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;See nova side operations in the nova spec here
‘volume-backend-server-rebuild’ &lt;a class="footnote-reference brackets" href="#id5" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Receive the re-image request from nova and check if the volume is in
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;reserved&lt;/span&gt;&lt;/code&gt; state.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Perform the re-image operation. During this, the volume will transition
into &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;downloading&lt;/span&gt;&lt;/code&gt; state which is similar to the state when creating a
bootable volume from image (more detailed information is captured later in
this section).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a new ‘volume-reimaged’ external event and use it notify nova when the
re-image operation is complete, like we use for volume-extend.
See &lt;a class="reference external" href="https://review.opendev.org/c/openstack/nova/+/454322"&gt;perform_resize_volume_online&lt;/a&gt; for details.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;After successful completion of the re-image operation, nova will call cinder
to update the attachment with connector info.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cinder will update the attachment and return connection info to Nova.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;After Nova completes the connection with brick, Nova will make the attachment
complete call marking the volume &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;in-use&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;So, we propose to add a new microversion to support users to re-image a
specific volume with new image id. Only &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;reserved&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;available&lt;/span&gt;&lt;/code&gt; and
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;error&lt;/span&gt;&lt;/code&gt; volume can be re-imaged. The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;reserved&lt;/span&gt;&lt;/code&gt; volume can only be
re-imaged when the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;reimage_reserved&lt;/span&gt;&lt;/code&gt; parameter is &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;True&lt;/span&gt;&lt;/code&gt;. The volume
state will be changed to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;downloading&lt;/span&gt;&lt;/code&gt; first.&lt;/p&gt;
&lt;p&gt;Two separate policies will be introduced, one for re-imaging an &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;available&lt;/span&gt;&lt;/code&gt;
or &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;error&lt;/span&gt;&lt;/code&gt; volume and another for re-imaging an &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;reserved&lt;/span&gt;&lt;/code&gt; volume, the
default policies for these new actions are &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;SYSTEM_ADMIN_OR_PROJECT_MEMBER&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If the image status is not &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;active&lt;/span&gt;&lt;/code&gt;, image size or image min_disk size is
larger than volume size, will raise InvalidInput (400) error.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add a new &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;reimage&lt;/span&gt;&lt;/code&gt; cast rpc. This rpc is used to cast an async message
from cinder API to the cinder-volume service or cluster.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a new method for volume manager. There will be a new method for volume
manager which will be called ‘reimage’, this method will first download the
image from glance and then perform the re-image operation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add an external event &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volume-reimaged&lt;/span&gt;&lt;/code&gt; and call it to notify nova API
about completion of reimage operation.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We propose to only support the basic implementation in this spec, the
re-image method will call driver’s ‘copy_image_to_volume’ to re-write the
specific volume with new image. If the specific image is encrypted, then it
will call driver’s ‘copy_image_to_encrypted_volume’. It’s similar to what we
have done when we create volume from image.&lt;/p&gt;
&lt;p&gt;After the re-image operation is complete, the volume will set back to
original state, and all previously existing volume_glance_metadata of this
volume will be replaced with the metadata from new image.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;If the re-image operation fails, we will set a user message to give hints to
the user how they can recover from a potentially now corrupt boot volume and
the volume status will changed to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;error&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are also some other optimized mechanisms that should be considered to
support in future, but will not be implemented in this spec:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Re-image an &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;in-use&lt;/span&gt;&lt;/code&gt; volume. If we want to support it, we should make
sure this volume can be multi-attached, so that we can attach this volume to
a host to support copy image to volume. And also re-image an &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;in-use&lt;/span&gt;&lt;/code&gt;
volume is a very dangerous operation, we must make sure there is no IO,
onging or cached on VMs before we complete re-imaging, otherwise will damage
the volume data. We will not support this operation in this spec.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Re-image a volume from image cache. Currently, Cinder supports creating
a volume from image cache, which can improve the performance of
creating a volume from an image, we can also consider to add this
improvement in the advanced implementation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add image signature verification support when re-imaging a volume. There is
also a signature when we create volume from image, we will also support it
in the advanced implementation. This will be called out in the API reference
documentation as a limitation until it is implemented.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;If the users want to re-image a volume to same image, the users could revert
the volume to a snapshot created after image.&lt;/p&gt;
&lt;p&gt;But for different image, the users could first delete the volume and then
re-create a volume with a specific new image. And nova could orchestrate
creating a new root volume with the new image, then replace it during the
server rebuild operation, but there are several issue with that as mentioned
above like quota and the questions about what nova should do about the old
volume, you can see more detail information in ML &lt;a class="footnote-reference brackets" href="#id7" id="id4" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;A new microversion will be created to support volume ‘os-reimage’ action API&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The rest API look like this in v3:&lt;/p&gt;
&lt;div class="highlight-console notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="go"&gt;POST /v3/{project_id}/volumes/{volume_id}/action&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-json notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"os-reimage"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"image_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"71543ced-a8af-45b6-a5c4-a46282108a90"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;"reimage_reserved"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The &amp;lt;string&amp;gt; ‘image_id’ refers to the id of image.
No default value since this is a required parameter.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &amp;lt;boolean&amp;gt; ‘reimage_reserved’ refers to re-image a volume and ignore its
‘reserved’ status. The ‘available’ and ‘error’ volume can be re-imaged
directly, but the ‘reserved’ volume can only be re-imaged when this
parameter is ‘true’.
Defaults to ‘false’, this is an optional parameter.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The response body of it is like:&lt;/p&gt;
&lt;div class="highlight-json notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"volume"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"migration_status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"attachments"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"links"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="nt"&gt;"href"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http://10.79.144.144/volume/v3/ffc60994a7274553905e5e5a8f890ab3/volumes/d90bfc0e-babf-4478-a591-23ca883ba2be"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="nt"&gt;"rel"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"self"&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="nt"&gt;"href"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http://10.79.144.144/volume/ffc60994a7274553905e5e5a8f890ab3/volumes/d90bfc0e-babf-4478-a591-23ca883ba2be"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="nt"&gt;"rel"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bookmark"&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"availability_zone"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"nova"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"os-vol-host-attr:host"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ubuntubase@lvmdriver-1#lvmdriver-1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"encrypted"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"updated_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2018-09-26T01:55:41.084080"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"replication_status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"snapshot_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"d90bfc0e-babf-4478-a591-23ca883ba2be"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"size"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"user_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"f33299af48b44050b96bc51104f2290a"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"os-vol-tenant-attr:tenant_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ffc60994a7274553905e5e5a8f890ab3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"os-vol-mig-status-attr:migstat"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"metadata"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"downloading"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"volume_image_metadata"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nt"&gt;"container_format"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bare"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nt"&gt;"min_ram"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nt"&gt;"disk_format"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"qcow2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nt"&gt;"image_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cirros-0.3.5-x86_64-disk"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nt"&gt;"image_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"24d0c0c3-9e03-498c-926f-ac964cbe2e08"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nt"&gt;"checksum"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"f8ab98ff5e73ebab884d80c9dc9c7290"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nt"&gt;"min_disk"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nt"&gt;"size"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"13267968"&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"multiattach"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"source_volid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"consistencygroup_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"os-vol-mig-status-attr:name_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"bootable"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"true"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"created_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2018-09-26T01:55:38.735749"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;"volume_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"lvmdriver-1"&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The &amp;lt;string&amp;gt; ‘status’ will be ‘downloading’.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &amp;lt;dict&amp;gt; ‘volume_image_metadata’ refers to the image metadata of the
volume. It will include the original image until the re-image operation is
complete in cinder-volume.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Normal response codes: 202&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Error response codes: 400, 403, 404, 409&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;Two new policy rules will be introduced as noted in the &lt;a class="reference internal" href="#proposed-change"&gt;Proposed change&lt;/a&gt;
section.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;Notifications will be added for re-image volume.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;A new command, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cinder&lt;/span&gt; &lt;span class="pre"&gt;reimage&lt;/span&gt; &lt;span class="pre"&gt;&amp;lt;volume_id&amp;gt;&lt;/span&gt; &lt;span class="pre"&gt;&amp;lt;image_id&amp;gt;&lt;/span&gt; &lt;span class="pre"&gt;[--ignore-reserved]&lt;/span&gt;&lt;/code&gt;,
will be added to python-cinderclient. This command mirrors the underlying API
function.&lt;/p&gt;
&lt;p&gt;Callers of the new API will need to poll the status of the volume until it
goes back to its original status or &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;error&lt;/span&gt;&lt;/code&gt; in case the operation failed.
The only exception here is Nova which will be notified via external events
API and doesn’t need to poll for the re-image to be completed.&lt;/p&gt;
&lt;p&gt;Since this is a data path change, it will only modify the contents of volume and
dependent resources like snapshots or backups won’t be affected by it. Just
to keep in mind that restoring to an earlier backup/snapshot will also revert
the volume to the old image.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Rajat Dhasmana &amp;lt;&lt;a class="reference external" href="mailto:rajatdhasmana%40gmail.com"&gt;rajatdhasmana&lt;span&gt;@&lt;/span&gt;gmail&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;By supporting re-image volumes, we need to do the following changes:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add a new ‘os-reimage’ action to volume actions API.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a new ‘reimage’ cast rpc.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a new ‘reimage’ method in volume manager.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Adopt the new microversion in python-cinderclient.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set a user message in the event when the re-image fails.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a call to nova external events API with ‘volume-reimaged’ event&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit-tests, tempest and other related tests will be implemented.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Need to document the new behavior of the volume re-image, as well
as related client examples, etc.&lt;/p&gt;
&lt;p&gt;We also need to mention in the documentation that when the volume
is re-imaged, all current content on the volume will be &lt;em&gt;destroyed&lt;/em&gt;.
This is important as cinder volumes are considered to be persistent,
which is not the case with this operation.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id5" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id3"&gt;2&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.opendev.org/c/openstack/nova-specs/+/809621"&gt;https://review.opendev.org/c/openstack/nova-specs/+/809621&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id6" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://wiki.openstack.org/wiki/CinderYogaPTGSummary#Volume_re-image"&gt;https://wiki.openstack.org/wiki/CinderYogaPTGSummary#Volume_re-image&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id7" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id4"&gt;3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://lists.openstack.org/pipermail/openstack-operators/2018-March/014952.html"&gt;http://lists.openstack.org/pipermail/openstack-operators/2018-March/014952.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Fri, 17 Sep 2021 00:00:00 </pubDate></item><item><title>The Return of Make Cinder Consistent and Secure RBAC Ready</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/yoga/s-rbac-ready.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/s-rbac-ready-y"&gt;https://blueprints.launchpad.net/cinder/+spec/s-rbac-ready-y&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Revise Cinder’s policy definitions to support the
&lt;cite&gt;Consistent and Secure Default RBAC&lt;/cite&gt; community goal &lt;a class="footnote-reference brackets" href="#id9" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Cinder policies currently rely only on roles and don’t recognize scope, which
was introduced into Keystone in Queens.  As a result, implementing something
like an administrator who can only perform nondestructive actions in Cinder
is very complicated and error-prone.
(See, for example, &lt;a class="reference external" href="https://docs.openstack.org/cinder/latest/configuration/block-storage/policy-config-HOWTO.html"&gt;Policy configuration HowTo&lt;/a&gt;
in the Cinder documentation.)&lt;/p&gt;
&lt;p&gt;Using token scope and other Keystone Queens-era improvements such as role
inheritance, it is possible to define policy rules that recognize a set of
useful “personas”.  If all OpenStack services define policy rules to support
this (which is the “consistent” part), operators will not have to rewrite
policies in an attempt to create such personas themselves, but can instead
use tested default policies (which is the “secure” part).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;Some examples:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;An operator wants to have an administrator who can perform only
nondestructive actions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;An operator wants to have different levels of end user in each project
(for example, a “project manager” who can do more in the project
than just a “project member”).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;An operator wants to have an system administrator who can manage the
cinder services, but cannot mess with resources owned by projects that
the administrator isn’t a member of.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;An operator wants to have an customer support administrator who can can
perform admin-only actions on resources owned by various projects, but
who cannot modify cinder services.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;There’s a long comment in the &lt;a class="reference external" href="https://opendev.org/openstack/cinder/src/commit/fae0e8dcb430bfe2d00b5360c56aa2e936f5f78c/cinder/policies/base.py"&gt;base policy definition file&lt;/a&gt;
in the cinder code repository that gives a fairly precise description of
how the policy changes made during the Xena cycle would be continued into
Yoga.  Unfortunately, however, as services have begun implementing Consistent
and Secure RBAC, some problems in the initial proposal have been identified,
resulting in a direction change for the effort &lt;a class="footnote-reference brackets" href="#id10" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.  This means that the
above-mentioned strategy for cinder in the Yoga cycle &lt;a class="footnote-reference brackets" href="#id11" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; must be completely
revised.&lt;/p&gt;
&lt;p&gt;The direction change affects cinder in the following ways:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The “system-*” personas are defined to act on the service itself (not
on project-owned resources) to the greatest extent possible.  (In
Xena, these personas were envisioned to act as a cinder super-user and
hence be able to perform all operations, both on project resources and
on the system itself.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The “project-admin” persona is now intended to be an administrator (that
is, a representative of the operator–definitely not an end user) who can
perform admin type actions on project-owned resources (for example,
migrating a volume).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A new “project-manager” persona is introduced.  This is intended to be an
end user who has some extra privileges beyond those of a “normal” user
in a project.  For example, a project-manager could be given the ability
to set a volume type as the default type for the project.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In Yoga, we’ll do the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The Cinder &lt;cite&gt;Policy Personas and Permissions&lt;/cite&gt; document merged in Xena &lt;a class="footnote-reference brackets" href="#id12" id="id4" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;
contained forward-looking information about what would be done in Yoga.
Unfortunately, this is no longer accurate.  The stable/xena version of
this document should be revised to describe &lt;em&gt;only&lt;/em&gt; the Xena changes so
that operators aren’t misled about the direction the effort is taking.&lt;/p&gt;
&lt;p&gt;There is a patch up addressing this:
&lt;a class="reference external" href="https://review.opendev.org/c/openstack/cinder/+/818696"&gt;https://review.opendev.org/c/openstack/cinder/+/818696&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Cinder &lt;cite&gt;Policy Personas and Permissions&lt;/cite&gt; document in the Yoga
development branch will need to be revised:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The range of actions allowed to the “system-*” personas will be
restricted to operations on cinder services.  These will be
“system-scoped” actions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The range of actions allowed to the “project-admin” persona will
allow this person to perform administrative operations on resources
owned by any project on which this person has the ‘admin’ role.
These will be “project-scoped” actions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The “project-member” and “project-reader” actions will likely be
unchanged from Xena, though they will be explicitly “project-scoped”
in Yoga.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There will be some multiple scoped actions.  Both system- and project-
personas should be able to list volume types, for example (though
only a system-admin should be able to create a volume type).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Once the document has been revised, we’ll be able to add a ‘scope_types’
field to each policy rule.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Additionally, we’ll be able to update the check strings for all
policies.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ideally, when a project-admin makes a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;GET&lt;/span&gt; &lt;span class="pre"&gt;/v3/volumes?all_tenants=1&lt;/span&gt;&lt;/code&gt;
call, for example, the response should include the volumes owned by all
and only the projects on which that project-admin has the ‘admin’ role.
For Yoga, we will allow anyone with the ‘admin’ role to see the volumes
in &lt;em&gt;all&lt;/em&gt; projects (as is the case now).  (See the discussion of “Listing
project resources across the deployment” &lt;a class="footnote-reference brackets" href="#id13" id="id5" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;5&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; in the community goal
statement for why it’s being done this way for Yoga.)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;At this point, we will have completed Phase 1 &lt;a class="footnote-reference brackets" href="#id14" id="id6" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;6&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; of the community goal.
This will allow cinder to ship with the oslo.policy configuration option
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;enforce_scope=True&lt;/span&gt;&lt;/code&gt; in the Z release.  (The importance of this is that
Phase 3 &lt;a class="footnote-reference brackets" href="#id15" id="id7" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;7&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; of the community goal cannot be implemented until a service
requires &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;enforce_scope=True&lt;/span&gt;&lt;/code&gt;.)&lt;/p&gt;
&lt;p&gt;We will plan to do Phase 2 &lt;a class="footnote-reference brackets" href="#id16" id="id8" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;8&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; of the community goal during the Z
development cycle.  See the community goal document for details.&lt;/p&gt;
&lt;p&gt;As mentioned above, by completing Phase 1 in Yoga, we should also be in
a positon to complete Phase 3 during the Z development cycle.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Do nothing.  Despite all the work we did in Xena, this is still not really an
option, because it’s not possible for some projects to use scoping and others
to ignore it while at the same time having consistent personas across projects.
So if we don’t upgrade our policy definitions, we will block all OpenStack
clouds from being able to use Consistent and Secure Policies.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;The ability to make various Block Storage API calls is already governed by
policies.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;Overall this should improve security by presenting operators a suitable
set of “personas” that will function consistently across project that they
can use out of the box instead of implementing their own.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="active-active-ha-impact"&gt;
&lt;h3&gt;Active/Active HA impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None, we already have to make calls out to keystone to validate tokens
and retrieve user privileges.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None, other than doing the implementation work.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Primary assignee:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;rosmaita&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;abishop&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Other contributors:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;tosky&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;enriquetaso&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;eharney&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;geguileo&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;whoami-rajat&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;jobernar&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Update the Cinder &lt;em&gt;Policy Personas and Permissions&lt;/em&gt; document in the
stable/xena branch.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update the Cinder &lt;em&gt;Policy Personas and Permissions&lt;/em&gt; document in the
master for the Yoga policy changes described above.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the appropriate &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;scope_types&lt;/span&gt;&lt;/code&gt; to all policy rules.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update policy checkstrings to separate system policies from project
policies.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update all tests to reflect the above changes, adding new tests as necessary.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Client changes to support system scope:
&lt;a class="reference external" href="https://review.opendev.org/c/openstack/python-cinderclient/+/776469"&gt;https://review.opendev.org/c/openstack/python-cinderclient/+/776469&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None, the required changes to complete Phase 1 merged long ago in Keystone
and oslo.policy.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Continue to use the testing framework developed in Xena.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We continue to have the stretch goal (mentioned in the Xena spec) to have
testing for secure RBAC in the cinder-tempest-plugin, but we do not
consider it a requirement for successful completion of this spec.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;The primary user-facing documentation for Cinder is &lt;cite&gt;Policy Personas and
Permissions&lt;/cite&gt; in the &lt;cite&gt;Cinder Service Configuration Guide&lt;/cite&gt;.&lt;/p&gt;
&lt;p&gt;Additionally, we expect that there will be more general documentation for
operators in the Keystone docs given the OpenStack-wide nature of this effort.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id9" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://governance.openstack.org/tc/goals/selected/consistent-and-secure-rbac.html"&gt;https://governance.openstack.org/tc/goals/selected/consistent-and-secure-rbac.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id10" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://governance.openstack.org/tc/goals/selected/consistent-and-secure-rbac.html#direction-change"&gt;https://governance.openstack.org/tc/goals/selected/consistent-and-secure-rbac.html#direction-change&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id11" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id3"&gt;3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://opendev.org/openstack/cinder/src/commit/fae0e8dcb430bfe2d00b5360c56aa2e936f5f78c/cinder/policies/base.py#L193-L248"&gt;https://opendev.org/openstack/cinder/src/commit/fae0e8dcb430bfe2d00b5360c56aa2e936f5f78c/cinder/policies/base.py#L193-L248&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id12" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id4"&gt;4&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://docs.openstack.org/cinder/xena/configuration/block-storage/policy-personas.html"&gt;https://docs.openstack.org/cinder/xena/configuration/block-storage/policy-personas.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id13" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id5"&gt;5&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://governance.openstack.org/tc/goals/selected/consistent-and-secure-rbac.html#listing-project-resources-across-the-deployment"&gt;https://governance.openstack.org/tc/goals/selected/consistent-and-secure-rbac.html#listing-project-resources-across-the-deployment&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id14" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id6"&gt;6&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://governance.openstack.org/tc/goals/selected/consistent-and-secure-rbac.html#phase-1"&gt;https://governance.openstack.org/tc/goals/selected/consistent-and-secure-rbac.html#phase-1&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id15" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id7"&gt;7&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://governance.openstack.org/tc/goals/selected/consistent-and-secure-rbac.html#phase-3"&gt;https://governance.openstack.org/tc/goals/selected/consistent-and-secure-rbac.html#phase-3&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id16" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id8"&gt;8&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://governance.openstack.org/tc/goals/selected/consistent-and-secure-rbac.html#phase-2"&gt;https://governance.openstack.org/tc/goals/selected/consistent-and-secure-rbac.html#phase-2&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Fri, 17 Sep 2021 00:00:00 </pubDate></item><item><title>NVMe Connector Healing Agent</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/wallaby/nvme-agent.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/nvmeof-client-raid-healing-agent"&gt;https://blueprints.launchpad.net/cinder/+spec/nvmeof-client-raid-healing-agent&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Daemon that monitors NVMe connections and MDRAID arrays created by the
NVMe connector, identifies faulted volume replicas, requests new replicas
and replaces faulted replicas with new ones.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;This spec has been superseded by &lt;a class="reference internal" href="../xena/nvme-agent.html"&gt;&lt;span class="doc"&gt;NVMeoF Connection Agent&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;When the NVMe connector connects a replicated volume, OpenStack will see it
as one volume, and has no way of monitoring managing and healing the replicas
in these MDRAID arrays. This agent will take care of that.&lt;/p&gt;
&lt;p&gt;It will monitor the state of the MDRAID arrays and reconcile their physical
state on the host with expected state from the volume provisioner, replacing
broken legs.&lt;/p&gt;
&lt;p&gt;For backend volume replicas, it’s the storage array that takes care of
monitoring and replacing unhealthy replicas.&lt;/p&gt;
&lt;p&gt;NVMe MDRAID moves the data replication responsibility from the backend to
the consumer.&lt;/p&gt;
&lt;p&gt;Currently there’s no mechanism to monitor and heal these replicated volumes.&lt;/p&gt;
&lt;p&gt;We cannot do it on the Cinder side, because even if the Cinder driver detected
the issue and created a replacing volume, we have no mechanism to report the
connection information of the replacing volume to the consumer.&lt;/p&gt;
&lt;p&gt;So the monitoring and healing needs to be on the volume consumer side.&lt;/p&gt;
&lt;p&gt;This agent will also be greatly beneficial for scenarios where certain replicas
of an attached replicated volume go faulty, by notifying the volume provisioner
of the faulty devices, they can be marked as faulty to avoid using old data on
re-attachments and to replace them entirely.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;When working with replicated NVMe volumes that are attached to an instance
for a long time, one of the replicas may go faulty.
This agent will detect it and attempt to replace it (self heal the MDRAID,
without the need to detach and re-attach the volume).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Add an “NVMe agent” class that will be initialized by the NVMe connector
during volume connection on a host.&lt;/p&gt;
&lt;p&gt;Initializing this agent will spawn a monitoring task which will repeat
periodically. We are proposing this to be a native thread if possible,
but if necessary it can be an independent process.&lt;/p&gt;
&lt;p&gt;First proposal was to use python Event Scheduler &lt;cite&gt;sched.scheduler&lt;/cite&gt;, but other
alternatives, such as spawning a separate process communicated to via socket,
may be chosen instead.
One key problem that would need to be addressed by this selection is a scenario
where compute service goes down, while the VMs continue operating (and their
volumes remain attached) - we don’t want to lose this agent in this case.&lt;/p&gt;
&lt;p&gt;When initialized, the agent will read access information to the volume
provisioner from a pre-determined config file location, with vendor specific
format, the content of which should be provided there by the systems operator.&lt;/p&gt;
&lt;p&gt;The task will monitor NVMe devices and MDRAID arrays built over them.&lt;/p&gt;
&lt;p&gt;It will know which NVMe devices and MDRAID arrays to monitor based on metadata
from the volume provisioner (backend) - which it will have a custom interface
to.&lt;/p&gt;
&lt;p&gt;It will notify volume provisioner if necessary of failed devices.&lt;/p&gt;
&lt;p&gt;It will attempt to connect to new NVMe devices / replicas, replacing them
in the MDRAID.&lt;/p&gt;
&lt;p&gt;Typical self healing flow:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;volume replica goes faulty&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;agent notices faulty replica, reports to provisioner&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;provisioner marks replica as bad (so it wont be used later unless synced)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;agent keeps pulling volume information from provisioner&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;certain grace period passes, agent sees no state changes of faulty replica
from provisioner, so it sends explicit request to replace replica&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;provisioner replaces replica and updates volume information&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;agent pulls volume replica information, notices a replica has changed&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;agent carries out replica replacement&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Operator could use some own script to monitor connections and fix them manually&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;Will call NVMe connector methods that do sudo executions of &lt;cite&gt;nvme&lt;/cite&gt; and &lt;cite&gt;mdadm&lt;/cite&gt;
This will happen in the new agent task that will be spawned from os-brick.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="active-active-ha-impact"&gt;
&lt;h3&gt;Active/Active HA impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;To allow multiple vendor implementations, the specific methods / logic for:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;probing the volume provisioner&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;pulling / parsing volume metadata from provisioner&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;reporting volume state changes to provisioner&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;requesting provisioner to replace replica&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Will need to be implemented on a per vendor basis.&lt;/p&gt;
&lt;p&gt;The architecture is such that the agent will be a generic class that will
provide the interface, and the kioxia implementation will be the first
example of vendor-specific implementation.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Zohar Mamedov&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;zoharm&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;NVMe connector will launch monitoring task on connect_volume if not running.&lt;/p&gt;
&lt;p&gt;Task monitors NVMe devices and MDRAID arrays created by the connector.&lt;/p&gt;
&lt;p&gt;When a replica goes faulty (as well as other events such as disconnects)
call interface method for notifying volume provisioner.&lt;/p&gt;
&lt;p&gt;When replicated volume devices are changed by the volume provisioner,
reconcile the physical state of NVMe devices and MDRAID arrays on the host.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;We should be able to accept this with just unit tests.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Document that using NVMe connector with replicated volumes will optionally
launch this agent.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;Architectural diagram
&lt;a class="reference external" href="https://wiki.openstack.org/wiki/File:Nvme-of-add-client-raid1-detail.png"&gt;https://wiki.openstack.org/wiki/File:Nvme-of-add-client-raid1-detail.png&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Tue, 29 Jun 2021 00:00:00 </pubDate></item><item><title>Reset State Robustification</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/xena/reset-state-robustification.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/reset-state-robustification"&gt;https://blueprints.launchpad.net/cinder/+spec/reset-state-robustification&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;I have seen a number of users get volumes into “invalid” states by
not understanding how resetting the state of a volume interacts
with resetting the state of attachments.&lt;/p&gt;
&lt;p&gt;For example, on a volume with an attachment, run
“cinder reset-state –state available &amp;lt;vol&amp;gt;”&lt;/p&gt;
&lt;p&gt;What now?&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;Help prevent users who aren’t Cinder experts from shooting themselves
in the foot with reset-state.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;If a user requests to reset the state of a volume to something that
Cinder knows is not a valid state of the universe, reject the request
with a reason.&lt;/p&gt;
&lt;p&gt;If volume1 has an attachment active.
$ cinder reset-state –state available volume1
ERROR: Cannot reset-state to available because attachments still exist.&lt;/p&gt;
&lt;p&gt;$ cinder reset-state –state available volume1 –attach-status detached
(command succeeds)&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Cases to block:&lt;/dt&gt;&lt;dd&gt;&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;volume reset to available w/ attachments&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;snapshot reset to in-use with volume in available&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Sometimes a knowledgeable operator may need to reset the state anyway
and then manually make the current state valid. cinder-manage is the
place where forcing a change will be allowed instead of ‘–force’
flag in the API.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Hope users don’t do these things.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Handle the “reset to available while attached case” by forcefully
detaching the volumes instead of rejecting the request.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;os-reset-status actions on volumes, snaps, backups, groups,
will now return a 400 in some cases where they would previously
succeeded.  This does not require a microversion bump.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="active-active-ha-impact"&gt;
&lt;h3&gt;Active/Active HA impact&lt;/h3&gt;
&lt;p&gt;These checks in reset-state could concievably race against updates in
a cluster.  Will determine what that means when we get further into
implementation.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;Improves safety for deployers trying to clean up from issues in
their cloud.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;TusharTgite&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;eharney&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Implement a check for the
reset-state to available while attached case&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add code to cinder-manage to handle the case
where an operator needs to override the API
and reset the state anyway.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Research other sensible cases we could prevent for
volumes, snaps, groups, etc.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tempest test for a couple of the big cases&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;New tempest tests&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Should document common cases where this fails.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Original proposal: &lt;a class="reference external" href="https://review.opendev.org/c/openstack/cinder-specs/+/682456"&gt;https://review.opendev.org/c/openstack/cinder-specs/+/682456&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Tue, 29 Jun 2021 00:00:00 </pubDate></item><item><title>Sizing encrypted volumes</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/xena/sizing-encrypted-volumes.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/sizing-encrypted-volumes"&gt;https://blueprints.launchpad.net/cinder/+spec/sizing-encrypted-volumes&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;If you have an unencrypted volume and migrate to an encrypted type, it fails
because there isn’t enough space on the target to fit the entire source
volume. This happens because an encrypted volume must have a header, which
takes up some space.&lt;/p&gt;
&lt;p&gt;In fact, the exact amount of space lost isn’t clear, it may vary by
LUKSv1/LUKSv2 and PLAIN dm-crypt formats. It’s probably on the order of 1-2
MB, but we allocate space in GB. Whether you can do really fine-grained space
allocation or not probably depends on the backend containing the volume.
However, we also need to keep the gigabyte boundaries for accounting purposes
(usage, quotas, charges, etc.) because that’s what everyone’s tooling expects.&lt;/p&gt;
&lt;p&gt;In addition, drivers optimize migration in different ways, and since we
previously didn’t have a new size parameter, there’s no easy way to get this
info into the drivers.&lt;/p&gt;
&lt;p&gt;Taking everything into consideration, we could have a flag indicating that
it’s OK for the volume to be increased in size if it’s required for the
retype to succeed. This way we don’t go behind the user’s back – we fail if
the volume won’t fit, and allow them to retype to a new size if they want the
retype to succeed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;The main use-case here is when upgrading an old deployment and would like to
encrypt old volumes after that.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The manager.py will create a destination volume bigger &amp;lt;source-volume-size+1&amp;gt;
GB size if the flag ‘allow-resize==on_demand’ and the destination volume-type
is encrypted.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Driver-specific method ‘_copy_volume_data’ for copy volume data when using block
devices (i.e LVM will still use the actual _migrate_volume_generic). This method
will be called after _before_volume_copy during volume migration.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;RPC minor version for a new param
3.x - Add allow_resize to retype method and increase_size to migrate method.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a new optional field, “allow_resize”, to the os-retype action. Possible
values will be “on-demand” or “never” (which are the same as the current
“migration_policy” field).  If not specified, the default is “never”.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a new optional field, “increase_size”, to the os-migrate action. The
operator specifies how many GB to grow the volume (so the final size is current
size + increase_size).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the next parameters to Python-cinderclient for retype and migrate commands:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Retype: New flag &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;--allow-resize&lt;/span&gt;&lt;/code&gt; indicating that it’s OK for the volume to be
increased in size if it’s required for the retype to succeed.&lt;/p&gt;
&lt;div class="highlight-bash notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;Optional&lt;span class="w"&gt; &lt;/span&gt;Arguments:
--allow-resize&lt;span class="w"&gt; &lt;/span&gt;&amp;lt;never&lt;span class="p"&gt;|&lt;/span&gt;on-demand&amp;gt;
Allow&lt;span class="w"&gt; &lt;/span&gt;the&lt;span class="w"&gt; &lt;/span&gt;volume&lt;span class="w"&gt; &lt;/span&gt;to&lt;span class="w"&gt; &lt;/span&gt;be&lt;span class="w"&gt; &lt;/span&gt;increased&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;size&lt;span class="w"&gt; &lt;/span&gt;during&lt;span class="w"&gt; &lt;/span&gt;the&lt;span class="w"&gt; &lt;/span&gt;retype&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;the&lt;span class="w"&gt; &lt;/span&gt;system
decides&lt;span class="w"&gt; &lt;/span&gt;it&lt;span class="w"&gt; &lt;/span&gt;is&lt;span class="w"&gt; &lt;/span&gt;necessary.&lt;span class="w"&gt; &lt;/span&gt;This&lt;span class="w"&gt; &lt;/span&gt;argument&lt;span class="w"&gt; &lt;/span&gt;is&lt;span class="w"&gt; &lt;/span&gt;recommended&lt;span class="w"&gt; &lt;/span&gt;when&lt;span class="w"&gt; &lt;/span&gt;retyping&lt;span class="w"&gt; &lt;/span&gt;to
an&lt;span class="w"&gt; &lt;/span&gt;encryption&lt;span class="w"&gt; &lt;/span&gt;type.
...
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Migration: allow a new size to be specified during a volume migration. New
optional argument added &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;--increase-size'&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight-bash notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;Optional&lt;span class="w"&gt; &lt;/span&gt;Arguments:
--increase-size&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&amp;lt;size&amp;gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Number&lt;span class="w"&gt; &lt;/span&gt;of&lt;span class="w"&gt; &lt;/span&gt;GiBs&lt;span class="w"&gt; &lt;/span&gt;to&lt;span class="w"&gt; &lt;/span&gt;grow&lt;span class="w"&gt; &lt;/span&gt;the&lt;span class="w"&gt; &lt;/span&gt;volume&lt;span class="w"&gt; &lt;/span&gt;during&lt;span class="w"&gt; &lt;/span&gt;migration.
This&lt;span class="w"&gt; &lt;/span&gt;is&lt;span class="w"&gt; &lt;/span&gt;recommended&lt;span class="w"&gt; &lt;/span&gt;when&lt;span class="w"&gt; &lt;/span&gt;migrating&lt;span class="w"&gt; &lt;/span&gt;to&lt;span class="w"&gt; &lt;/span&gt;an&lt;span class="w"&gt; &lt;/span&gt;encrypted&lt;span class="w"&gt; &lt;/span&gt;host.
...
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The displayed size of the volume will be the actual size of the volume.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Leave everything as it is and don’t allow this kind of migration. To help users
add some workaround to the documentation (i.e. backup the volume and then restore
the volume to a bigger one). &amp;lt;1GB size increases won’t be allowed, as explained
in the problem description above.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Microversion bump&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;New parameters should be passed to retype and migrate commands as explained in
the ‘proposed change’ section.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None. If you’re allowed to migrate at all, you should be able to increase the size,
and if you’re allowed to retype, you should be able to allow-resize.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Sofia Enriquez &amp;lt;&lt;a class="reference external" href="mailto:lsofia.enriquez%40gmail.com"&gt;lsofia&lt;span&gt;.&lt;/span&gt;enriquez&lt;span&gt;@&lt;/span&gt;gmail&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Implement new logic in cinder&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement new logic in python-cinderclient&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unit-tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tempest tests&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit tests and current devstack-based jobs won’t be enough to test these
changes. At least two tests should be added to
cinder_tempest_plugin/api/volume/admin/test_volume_retype.py&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;retype unencrypted volume to LUKS type.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;retype encrypted LUKS volume to regular type.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Currently I’ve added some documentation notes warning about retyping an
unencrypted/encrypted volume. However, these notes should be replaced with
proper documentation.&lt;/p&gt;
&lt;p&gt;Notes to be removed
- &lt;a class="reference external" href="https://review.opendev.org/#/c/732988/"&gt;https://review.opendev.org/#/c/732988/&lt;/a&gt;
- &lt;a class="reference external" href="https://review.opendev.org/#/c/745199/"&gt;https://review.opendev.org/#/c/745199/&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://etherpad.opendev.org/p/sizing-encrypted-volumes"&gt;https://etherpad.opendev.org/p/sizing-encrypted-volumes&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Victoria Mid Cycle &lt;a class="reference external" href="https://wiki.openstack.org/wiki/CinderVictoriaMidCycleSummary"&gt;https://wiki.openstack.org/wiki/CinderVictoriaMidCycleSummary&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Victoria PTG &lt;a class="reference external" href="https://wiki.openstack.org/wiki/CinderVictoriaPTGSummary#Sizing_encrypted_volumes"&gt;https://wiki.openstack.org/wiki/CinderVictoriaPTGSummary#Sizing_encrypted_volumes&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Tue, 29 Jun 2021 00:00:00 </pubDate></item><item><title>Expose user-visible extra specs in volume types</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/xena/expose-cinder-user-visible-extra-specs-spec.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/expose-user-visible-extra-specs"&gt;https://blueprints.launchpad.net/cinder/+spec/expose-user-visible-extra-specs&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This spec proposes definition of a class of &lt;em&gt;user visible&lt;/em&gt; extra specs.
These will be shown to regular users (members or readers in a keystone
project) when they list extra specs or show volume types or extra specs.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Cinder only allows cloud administrators to see the extra specs in volume
types. This makes sense for specs that control knobs for use by drivers,
that select a particular backend, or that would otherwise reveal backend
specifics. But it is problematic for backend independent extra specs
like &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;multiattach&lt;/span&gt;&lt;/code&gt; or &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;RESKEY:availability_zones&lt;/span&gt;&lt;/code&gt; – specs that
carry critical information for regular users when they select volume
types to use as they create volumes.&lt;/p&gt;
&lt;p&gt;The traditional response to this problem has been that cloud
administrators should add this critical information to the volume-type
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;description&lt;/span&gt;&lt;/code&gt; field or provide it in the user documentation for their
cloud.&lt;/p&gt;
&lt;p&gt;Whatever one thinks of the adequacy of that response when the cloud
users are human beings, it clearly fails when the end user is an
automated agent.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;OpenShift cluster storage operators are automated agents that set up
Kubernetes Storage Classes on underlying infrastructure. When that
infrastructure is provided by OpenStack, the Cinder CSI operator will
create a Storage Class corresponding to each Cinder volume type.
OpenShift users in turn reference these Storage Classes in Persistent
Volume Claims when dynamically provisioning Persistent Volumes for use
by containerized applications.&lt;/p&gt;
&lt;p&gt;When provisioning a persistent volume via Cinder CSI with ReadWriteMany
access mode, the persistent volume claim should specify &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;block&lt;/span&gt;&lt;/code&gt;
volumeMode (default is &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;filesystem&lt;/span&gt;&lt;/code&gt;) and reference a Storage Class
corresponding to a Cinder volume type with a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;"multiattach":&lt;/span&gt; &lt;span class="pre"&gt;"&amp;lt;is&amp;gt;&lt;/span&gt; &lt;span class="pre"&gt;True"&lt;/span&gt;&lt;/code&gt;
extra spec.&lt;/p&gt;
&lt;p&gt;Because OpenShift administrators and all the software that runs on their
behalf are in the general case just regular OpenStack users rather
than OpenStack administrators, they currently lack the ability to
discover extra specs for volume types corresponding to their Storage
Classes and are hindered in their ability to “do the right thing” for
OpenShift users.&lt;/p&gt;
&lt;p&gt;Cinder CSI now has a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;topology&lt;/span&gt;&lt;/code&gt; feature as well where it will likely
make sense to be able to see &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;RESKEY:availability_zones&lt;/span&gt;&lt;/code&gt; extra specs when
setting up Storage Classes corresponding to volume types.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Define a set of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;user&lt;/span&gt; &lt;span class="pre"&gt;visible&lt;/span&gt;&lt;/code&gt; extra specs in the Cinder code and modify the
REST API view for showing extra specs to reveal these in policy based
request contexts. The initial set of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;user&lt;/span&gt; &lt;span class="pre"&gt;visible&lt;/span&gt;&lt;/code&gt; extra specs is
sufficient to establish a framework, and meet the immediate needs described in
the use cases. The set is intentionally small, and leverages existing extra
specs. The following extra spec keys are to be treated as &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;user&lt;/span&gt; &lt;span class="pre"&gt;visible&lt;/span&gt;&lt;/code&gt;:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;multiattach&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;RESKEY:availability_zones&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;replication_enabled&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The set of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;user&lt;/span&gt; &lt;span class="pre"&gt;visible&lt;/span&gt;&lt;/code&gt; extra specs will be a fixed list defined in the
Cinder code, and can be extended but only by enhancing the code. Future
updates can support additional volume characteristics that can be expressed with
an extra spec. For example, it might be useful for users to know whether a
volume type provides volumes that support online extend, but there currently
is no extra spec associated with that feature.&lt;/p&gt;
&lt;p&gt;The REST API behavior will be policy based, and not require a new
microversion. The existing policies for accessing extra specs will remain, but
the default values will be changed to grant access to any authorized user. A
new policy will determine whether access is granted to all extra specs, or
just &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;user&lt;/span&gt; &lt;span class="pre"&gt;visible&lt;/span&gt;&lt;/code&gt; extra specs.  The policies will allow users to view
extra specs, but the view will be restricted to the extra specs that are
considered &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;user&lt;/span&gt; &lt;span class="pre"&gt;visible&lt;/span&gt;&lt;/code&gt;. A new policy will control access to all extra
specs, including the ones that are &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;user&lt;/span&gt; &lt;span class="pre"&gt;visible&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The current policies (and their default values) for accessing extra specs are:&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Policy&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Default&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;volume_extension:access_types_extra_specs&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;admin-only&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;volume_extension:types_extra_specs:index&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;admin-only&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;volume_extension:types_extra_specs:show&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;admin-only&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The proposed policies, and their new default values, will be:&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Policy&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Default&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;volume_extension:access_types_extra_specs&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;any authorized user&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;volume_extension:types_extra_specs:index&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;any authorized user&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;volume_extension:types_extra_specs:show&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;any authorized user&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;volume_extension:types_extra_specs:read_sensitive&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;admin-only&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The new &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volume_extension:types_extra_specs:read_sensitive&lt;/span&gt;&lt;/code&gt; policy will
govern whether access is granted to all extra specs, or is limited to just
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;user&lt;/span&gt; &lt;span class="pre"&gt;visible&lt;/span&gt;&lt;/code&gt; extra specs. Hereafter in this spec, the new policy will
be abbreviated as &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;read_sensitive&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h2&gt;Alternatives&lt;/h2&gt;
&lt;p&gt;Build a new API to return user visible capabilities and features from
volume types without exposing them as “extra specs.” Although this
alternative would also solve the problem, it requires more code to
write, test, and document.&lt;/p&gt;
&lt;p&gt;Control exposure of each individual extra spec entirely by policy. It is
not clear how to do this without significant changes to the existing
REST API. Nor in our opinion is it desirable. There are clear cut
examples of backend independent capabilities and features that are
properly the business of any user who is authorized to create volumes, so
users should have a reasonable expectation that these can be discovered
without burdening the cloud administrator with the task of constructing
policies for them one by one.&lt;/p&gt;
&lt;p&gt;The new &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volume_extension:types_extra_specs:read_sensitive&lt;/span&gt;&lt;/code&gt; policy is
introduced, but the existing policies remain defaulting to admin-only. The
downside is this would require cloud administrators to modify the default
policies for the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;user&lt;/span&gt; &lt;span class="pre"&gt;visible&lt;/span&gt;&lt;/code&gt; extra specs to be available to non-
administrative API requests. However, the entire premise is that &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;user&lt;/span&gt;
&lt;span class="pre"&gt;visible&lt;/span&gt;&lt;/code&gt; extra specs are, by definition, intended to be visible to users.
Cloud administrators shouldn’t need to opt-in to reap the benefits of this
feature. Cloud administrators who wish to retain the current behavior, where
users are not authorized to see any extra specs, may do so by explicitly
setting these policies to admin-only (the previous default value).&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;volume_extension:access_types_extra_specs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;volume_extension:types_extra_specs:index&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;volume_extension:types_extra_specs:show&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h2&gt;Data model impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h2&gt;REST API impact&lt;/h2&gt;
&lt;p&gt;The REST API affected by this spec are:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;/v3/{project_id}/types&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;/v3/{project_id}/types/{volume_type_id}&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;/v3/{project_id}/types/{volume_type_id}/extra_specs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;/v3/{project_id}/types/{volume_type_id}/extra_specs/{key}&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The following examples document the behavior for a volume type with two
extra specs:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;multiattach&lt;/span&gt;&lt;/code&gt; (a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;user&lt;/span&gt; &lt;span class="pre"&gt;visible&lt;/span&gt;&lt;/code&gt; extra spec)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volume_backend_name&lt;/span&gt;&lt;/code&gt; (which will be visible only when the context
satisfies the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;read_sensitive&lt;/span&gt;&lt;/code&gt; policy)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="get-v3-project-id-types"&gt;
&lt;h3&gt;GET /v3/{project_id}/types&lt;/h3&gt;
&lt;p&gt;This REST API returns a list of volume types, and the following example
shows just a single volume type.
When the context doesn’t satisfy the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;read_sensitive&lt;/span&gt;&lt;/code&gt; policy, the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;extra_specs&lt;/span&gt;&lt;/code&gt; field is included but only &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;user&lt;/span&gt; &lt;span class="pre"&gt;visible&lt;/span&gt;&lt;/code&gt; entries are
present.&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Policy&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Context&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;volume_extension:access_types_extra_specs&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;True&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;volume_extension:types_extra_specs:read_sensitive&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;False&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"volume_types"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"6685584b-1eac-4da6-b5c3-555430cf68ff"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"qos_specs_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"vol-type-001"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"volume type 0001"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"os-volume-type-access:is_public"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"is_public"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"extra_specs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s2"&gt;"multiattach"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;is&amp;gt; True"&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;When the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;read_sensitive&lt;/span&gt;&lt;/code&gt; policy is satisfied (by default, this will be the
case only for administrators) the full list of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;extra_specs&lt;/span&gt;&lt;/code&gt; is returned.&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Policy&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Context&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;volume_extension:access_types_extra_specs&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;True&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;volume_extension:types_extra_specs:read_sensitive&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;True&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"volume_types"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"6685584b-1eac-4da6-b5c3-555430cf68ff"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"qos_specs_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"vol-type-001"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"volume type 0001"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"os-volume-type-access:is_public"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"is_public"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"extra_specs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s2"&gt;"multiattach"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;is&amp;gt; True"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"volume_backend_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"SecretName"&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="get-v3-project-id-types-volume-type-id"&gt;
&lt;h3&gt;GET /v3/{project_id}/types/{volume_type_id}&lt;/h3&gt;
&lt;p&gt;The REST API shows the details for the specified volume type, and the behavior
is similar to the to the /v3/{project_id}/types API.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;extra_specs&lt;/span&gt;&lt;/code&gt; field will contain any &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;user&lt;/span&gt; &lt;span class="pre"&gt;visible&lt;/span&gt;&lt;/code&gt; extra specs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;read_sensitive&lt;/span&gt;&lt;/code&gt; policy is satisfied, the full list of
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;extra_specs&lt;/span&gt;&lt;/code&gt; is returned.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="get-v3-project-id-types-volume-type-id-extra-specs"&gt;
&lt;h3&gt;GET /v3/{project_id}/types/{volume_type_id}/extra_specs&lt;/h3&gt;
&lt;p&gt;The policy will be updated to allow any authorized user access to this
API. But, similar to above, for non &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;read_sensitive&lt;/span&gt;&lt;/code&gt; requests the list of
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;extra_specs&lt;/span&gt;&lt;/code&gt; will be limited to those that are &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;user&lt;/span&gt; &lt;span class="pre"&gt;visible&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Policy&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Context&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;volume_extension:types_extra_specs:index&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;True&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;volume_extension:types_extra_specs:read_sensitive&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;False&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"extra_specs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"multiattach"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;is&amp;gt; True"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;If there are no &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;user&lt;/span&gt; &lt;span class="pre"&gt;visible&lt;/span&gt;&lt;/code&gt; extra specs defined for the specified
volume type, then an empty dictionary will be returned.&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"extra_specs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;When made by an administrator, the response will be the complete set of extra
specs (no change from current behavior).&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Policy&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Context&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;volume_extension:types_extra_specs:index&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;True&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;volume_extension:types_extra_specs:read_sensitive&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;True&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"extra_specs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"multiattach"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;is&amp;gt; True"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"volume_backend_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"SecretName"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="get-v3-project-id-types-volume-type-id-extra-specs-key"&gt;
&lt;h3&gt;GET /v3/{project_id}/types/{volume_type_id}/extra_specs/{key}&lt;/h3&gt;
&lt;p&gt;When the specified extra-specs {key} is in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;user&lt;/span&gt; &lt;span class="pre"&gt;visible&lt;/span&gt;&lt;/code&gt; set, the value
will be returned regardless of whether the requester satisfies the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;read_sensitive&lt;/span&gt;&lt;/code&gt; policy.&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Policy&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Context&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;volume_extension:types_extra_specs:show&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;True&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;volume_extension:types_extra_specs:read_sensitive&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"multiattach"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;is&amp;gt; True"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The response to requests for extra specs that are not &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;user&lt;/span&gt; &lt;span class="pre"&gt;visible&lt;/span&gt;&lt;/code&gt; will
depend on the context. If the request satisfies the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;read_sensitive&lt;/span&gt;&lt;/code&gt; policy
then the appropriate response is returned.&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Policy&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Context&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;volume_extension:types_extra_specs:show&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;True&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;volume_extension:types_extra_specs:read_sensitive&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;True&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"volume_backend_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"SecretName"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;But if the request does not satisfy the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;read_sensitive&lt;/span&gt;&lt;/code&gt; policy then the
API will return 404 NOTFOUND. Returning 404 (instead of 403) prevents leakage
of the names of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;read_sensitive&lt;/span&gt;&lt;/code&gt; extra spec keys.&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Policy&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Context&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;volume_extension:types_extra_specs:show&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;True&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;volume_extension:types_extra_specs:read_sensitive&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;False&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"itemNotFound"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;404&lt;/span&gt;
        &lt;span class="s2"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Volume Type 6685584b-1eac-4da6-b5c3-555430cf68ff has no extra specs with key volume_backend_name."&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h2&gt;Security impact&lt;/h2&gt;
&lt;p&gt;None. The set of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;user&lt;/span&gt; &lt;span class="pre"&gt;visible&lt;/span&gt;&lt;/code&gt; extra specs is hard coded and does not
include extra specs that reveal back end details.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="active-active-ha-impact"&gt;
&lt;h2&gt;Active/Active HA impact&lt;/h2&gt;
&lt;p&gt;None. REST API layer change with no locking or exclusion or service
restart implications.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h2&gt;Notifications impact&lt;/h2&gt;
&lt;p&gt;None – no asynchronous operations involved.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h2&gt;Other end user impact&lt;/h2&gt;
&lt;p&gt;Cinderclient and OSC and Horizon should not need changes. Regular
users will see some new information but no new fields are required.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h2&gt;Performance Impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h2&gt;Other deployer impact&lt;/h2&gt;
&lt;p&gt;No impact on OpenStack deployment tools or deployment planning/design.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h2&gt;Developer impact&lt;/h2&gt;
&lt;p&gt;No impact on OpenStack development outside the scope of this change.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Primary assignee: abishop&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Define list of user visible extra specs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Define the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;read_sensitive&lt;/span&gt;&lt;/code&gt; policy, and modify the existing default
policy rules that govern access to extra specs to allow access to any
authorized user.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update the API responses per this spec.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify unit tests to check for exposure of exactly and only the
user visible extra specs without &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;read_sensitive&lt;/span&gt;&lt;/code&gt; authorization.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tempest tests&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h3&gt;Dependencies&lt;/h3&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h3&gt;Testing&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;New tempest tests in cinder-tempest-plugin&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h3&gt;Documentation Impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add section to Cinder Administration that defines and lists user
visible extra specs. Describe the new &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;read_sensitive&lt;/span&gt;&lt;/code&gt; policy, and
explain the policy settings that will give an operator “legacy” behavior.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update API reference&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 24 Jun 2021 00:00:00 </pubDate></item><item><title>NVMeoF Connection Agent</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/xena/nvme-agent.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/nvmeof-connection-agent"&gt;https://blueprints.launchpad.net/cinder/+spec/nvmeof-connection-agent&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Daemon that monitors NVMeoF connections and MDRAID arrays created by the
new NVMeoF connector. It reports initiator-side events to the storage
orchestrator, identifies faulted volume replicas, requests new replicas and
replaces faulted replicas with newly assigned ones.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;When the NVMe connector connects a client-replicated volume, OpenStack will see
it as one volume, and has no way of monitoring managing and healing the
replicas in these MDRAID arrays. This agent will take care of that.&lt;/p&gt;
&lt;p&gt;Currently there’s no mechanism to monitor and heal these replicated volumes.
We cannot do it only on the Cinder driver side because currently there is no
integrated mechanism to detect initiator connection events and carry out
replica replacement on the compute node.&lt;/p&gt;
&lt;p&gt;For target-side volume replication (traditional approach), it is the storage
backend that takes care of monitoring and self healing.
The NVMe + MDRAID approach moves the data replication responsibility from the
storage backend to the consuming initiator (ie. compute node).&lt;/p&gt;
&lt;p&gt;So the monitoring and healing needs to be on the initiator / compute side.&lt;/p&gt;
&lt;p&gt;With this approach, the agent will monitor the NVMeoF connections and report
changes to the storage orchestrator / provisioner. It will monitor MDRAID arrays
and reconcile their physical state on the host with expected state from the
volume provisioner, replacing broken legs.&lt;/p&gt;
&lt;p&gt;Finally, orchestration decisions / optimizations will be carried by the volume
orchestrator / provisioner using reported information from agent monitoring.
Though this is outside the scope of the agent (it is storage backend
implemented functionality) - it is useful to mention here that it will handle
cases such as avoid using faulty replicas during re-attachment scenarios,
because in this design approach only the initiator node can detect the
replicas’ sync states of its MDRAID arrays.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;When working with replicated NVMeoF volumes that are attached to an instance
for a long time, one of the replicas may go faulty.
This agent will detect it and attempt to replace it, i.e., self heal the
MDRAID array, without the need to detach and re-attach the entire volume from
the instance.&lt;/p&gt;
&lt;p&gt;Additionally, the agent will detect and report connection and replica sync
state events to the storage orchestrator (or potentially other endpoints
that can make use of it) - which is gathered by the storage backend for making
storage provisioning / orchestration decisions, as well as for telemetry.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Add an agent entry point code to os-brick, such as:
&lt;cite&gt;os_brick/os-brick/cmd/agent.py&lt;/cite&gt;&lt;/p&gt;
&lt;p&gt;Add an &lt;cite&gt;entry_points&lt;/cite&gt; &lt;cite&gt;console_scripts&lt;/cite&gt; entry in os-brick’s &lt;cite&gt;setup.cfg&lt;/cite&gt;&lt;/p&gt;
&lt;p&gt;The agent main function will first initialize the agent by reading access
information to the volume orchestor / provisioner from a pre-defined config
file (such as &lt;cite&gt;/etc/nvme-agent/agent.conf&lt;/cite&gt; ?)&lt;/p&gt;
&lt;p&gt;Vendor specific params will be used and prefixed by the vendor prefix, such as:
&lt;cite&gt;kioxia_provisioner_ip&lt;/cite&gt;
&lt;cite&gt;kioxia_provisioner_port&lt;/cite&gt;
&lt;cite&gt;kioxia_provisioner_token&lt;/cite&gt;
&lt;cite&gt;kioxia_cert_file&lt;/cite&gt;&lt;/p&gt;
&lt;p&gt;Once initialized, the agent will start a periodic task that will do
the following:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Host probe / heartbeat to the storage orchestrator / provisioner&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pull volume metadata (connection and replication state) from provisioner&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Monitor NVMeoF devices and MDRAID arrays belonging to it&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Detect connection and replication state changes and report to provisioner&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Request replacements for faulty replicas&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reconcile replica states from provisioner (carry out the replacements)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Typical self healing flow:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;volume replica goes faulty&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;agent notices faulty replica, reports to provisioner&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;provisioner marks replica as bad (so it wont be used later unless synced)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;agent keeps pulling volume information from provisioner&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;certain grace period passes, agent sees no state changes of faulty replica
from provisioner, so it sends explicit request to replace replica&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;provisioner replaces replica and updates volume information&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;agent pulls volume replica information, notices a replica has changed&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;agent carries out replica replacement&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Operator could use some own scripts to monitor connections and replicated
arrays states, report detected events, and carry out replica replacements
manually.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;Sudo executions of &lt;cite&gt;nvme&lt;/cite&gt; and &lt;cite&gt;mdadm&lt;/cite&gt;
Needs access for reading of root filesystem paths such as:
&lt;cite&gt;/sys/class/nvme-fabrics/…&lt;/cite&gt;
&lt;cite&gt;/sys/class/block/…&lt;/cite&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="active-active-ha-impact"&gt;
&lt;h3&gt;Active/Active HA impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;If configured to run by the operator, this will be a new process running on
the compute node. Though it will spend most of its time sleeping, it will
wake up every 30 seconds to do its periodic tasks: probe the storage provisioner
and inspect nvme connections and mdraid states.&lt;/p&gt;
&lt;p&gt;These tasks are not compute intensive, with time mostly spent waiting for a
response from the storage provisioner, and the nvme and mdraid operations will
only have time complexity linear to the number of devices under the control of
the agent (which can be treated as constant due to a low upper limit per host).
And finally, the performance effect on the network will also be small, since it
will only be sending/receiving small amounts of (meta)data across the network.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;To allow multiple vendor implementations, the specific methods / logic for:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;probing / heartbeating the storage provisioner&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;pulling / parsing volume metadata from provisioner&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;reporting state changes to provisioner&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;requesting provisioner to replace replica&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These all involve communication with and functionality carried out by the
storage backend provisioner / orchestrator, will need to be implemented on
a per vendor basis.&lt;/p&gt;
&lt;p&gt;The architecture is such that the agent will be a generic daemon that will
define the interface, and the kioxia implementation will be the first
example of a vendor-specific implementation.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Zohar Mamedov&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;zoharm&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;Agent entry point and initialization.&lt;/p&gt;
&lt;p&gt;Agent periodic tasks:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Host probe / heart beat&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Monitoring (connection and replication event detection)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Report events to storage provisioner&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Connection and replication state re-conciliation&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;We should be able to accept this with just unit tests.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Document that with this feature os-brick will be coming with a console-script
that is used to launch this agent.&lt;/p&gt;
&lt;p&gt;Document how to configure the agent for usage.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;Presentation slides with architectural diagram on slide 2
&lt;a class="reference external" href="https://docs.google.com/presentation/d/1lPU8mQ7jJmr9Tybu5gXkbE7NC1ppkMnoBS4cgSFhzWc"&gt;https://docs.google.com/presentation/d/1lPU8mQ7jJmr9Tybu5gXkbE7NC1ppkMnoBS4cgSFhzWc&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Tue, 15 Jun 2021 00:00:00 </pubDate></item><item><title>Temporary Resource Tracking</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/xena/temp-resources.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/temp-resources"&gt;https://blueprints.launchpad.net/cinder/+spec/temp-resources&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Improve Cinder’s temporary resource tracking to prevent related quota issues.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Cinder doesn’t currently have a consistent way of tracking temporary resources,
which leads to quota bugs.&lt;/p&gt;
&lt;p&gt;In some cases temporary volumes use the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;temporary&lt;/span&gt;&lt;/code&gt; key in the admin metadata
table to mark them and in other cases we determine a volume is temporary based
on its &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;migration_status&lt;/span&gt;&lt;/code&gt; field, there are even cases where volumes are not
being marked as temporary.  Due to this roundabout way of marking temporary
volumes and having multiple options makes our Cinder code error prone, as is
clear by the number of bugs around it.&lt;/p&gt;
&lt;p&gt;As for temporary snapshots, Cinder doesn’t currently have any way of reliably
tracking them, so the code creating temporary resources assumes that everything
will run smoothly and the deletion code in the method will be called after
successfully completing the operation.  Sometimes that is not true, as the
operation could fail and leave the temporary resource behind, forcing users to
delete them manually, which messes up the quota, since the REST API delete call
doesn’t know it shouldn’t touch the quota.&lt;/p&gt;
&lt;p&gt;When we say that we don’t have a reliable way of tracking snapshots we refer to
the fact that even though snapshots have a name that helps identify them, such
as &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;[revert]&lt;/span&gt; &lt;span class="pre"&gt;volume&lt;/span&gt; &lt;span class="pre"&gt;%s&lt;/span&gt; &lt;span class="pre"&gt;backup&lt;/span&gt; &lt;span class="pre"&gt;snapshot&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;backup-snap-%s&lt;/span&gt;&lt;/code&gt;, these are
also valid snapshot names that a user can assign, so we cannot rely on them to
differentiate temporary snapshots.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;There are several cases where this feature will be useful:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Revert to snapshot is configured to use a temporary snapshot, but either the
revert fails or the deletion of the temporary volume fails, so the user ends
up manually deleting the snapshot, and the quota is kept in sync with
reality.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Creating a backup of an in-use volume when &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;backup_use_temp_snapshot&lt;/span&gt;&lt;/code&gt; is
enabled fails, or the deletion of the temporary resource failed, forcing the
user to manually deleting the snapshot, and the user wants the quota to be
kept in sync with reality.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A driver may have some slow code that gets triggered when cloning or creating
a snapshot for performance reasons but that would not be reasonable to
execute for temporary volumes.  An example would be the flattening of cloned
volumes on the RBD driver.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;The proposed solution is to have an explicit DB field that indicates whether a
resource should be counted towards quota or not.&lt;/p&gt;
&lt;p&gt;The field would be named &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;use_quota&lt;/span&gt;&lt;/code&gt; and it would be added to the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volumes&lt;/span&gt;&lt;/code&gt;
and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;snapshots&lt;/span&gt;&lt;/code&gt; DB tables.  We currently don’t have temporary backups, so no
field would be added to the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;backups&lt;/span&gt;&lt;/code&gt; DB table.&lt;/p&gt;
&lt;p&gt;This would replace the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;temporary&lt;/span&gt;&lt;/code&gt; admin metadata entry and the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;migration_status&lt;/span&gt;&lt;/code&gt; entry in 2 cycles, since we need to keep supporting
rolling upgrades where we could be running code that doesn’t know about the new
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;use_quota&lt;/span&gt;&lt;/code&gt; field.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;An alternative solution would be to use the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;temporary&lt;/span&gt;&lt;/code&gt; key in the volumes’
admin metadata table like we are doing in some case and create one such table
for snapshots as well.&lt;/p&gt;
&lt;p&gt;With that alternative DB queries could become more complex, unlike with the
proposed solution where they would become simpler.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;Adds a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;use_quota&lt;/span&gt;&lt;/code&gt; DB field of type &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Boolean&lt;/span&gt;&lt;/code&gt; to both &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volumes&lt;/span&gt;&lt;/code&gt; and
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;snapshots&lt;/span&gt;&lt;/code&gt; tables.&lt;/p&gt;
&lt;p&gt;It will have an online data migration to set the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;use_quota&lt;/span&gt;&lt;/code&gt; field for
existing volumes as well as an updated &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;save&lt;/span&gt;&lt;/code&gt; method for &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Volume&lt;/span&gt;&lt;/code&gt; and
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Snapshot&lt;/span&gt;&lt;/code&gt; OVOs that sets this field whenever they are saved.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;There won’t be any new REST API endpoint since the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;use_quota&lt;/span&gt;&lt;/code&gt; field is an
internal field and we don’t want users or administrators modifying it.&lt;/p&gt;
&lt;p&gt;But since this is useful information we will add this field to the volume’s
JSON response for all endpoints that return it, although with a more user
oriented name &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;consumes_quota&lt;/span&gt;&lt;/code&gt;:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create volume&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Show volume&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update volume&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;List detailed volumes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create snapshot&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Show snapshot&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update snapshot&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;List detailed snapshots&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="active-active-ha-impact"&gt;
&lt;h3&gt;Active/Active HA impact&lt;/h3&gt;
&lt;p&gt;None, since this mostly just affects whether quota code is called or not when
receiving REST API delete requests.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;The change requires a patch on the python-cinderclient to show the new returned
field &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;consumes_quota&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;There should be no performance detriment with this change, since the field
would be added at creation time and would not require additional DB queries.&lt;/p&gt;
&lt;p&gt;Moreover performance improvements should be possible in the future once we
remove compatibility code with the current temporary volume checks, for example
not requiring writing to the admin metadata table, making quota sync
calculations directly on the DB, etc.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;By default Volume and Snapshot OVOs will use quota on creation (set
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;use_quota&lt;/span&gt;&lt;/code&gt; to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;True&lt;/span&gt;&lt;/code&gt;) and when developers want to create temporary
resources that don’t consume quota on creation or release it on deletion will
need to pass &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;use_quota=False&lt;/span&gt;&lt;/code&gt; at creation time.&lt;/p&gt;
&lt;p&gt;Also when doing quota (adding or removing) new code will have to check this
field in Volumes and Snapshots.&lt;/p&gt;
&lt;p&gt;It will no longer be necessary to add additional admin metadata or check the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;migration_status&lt;/span&gt;&lt;/code&gt;, which should make it coding easier and reduce the number
of related bugs.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Gorka Eguileor (geguileo)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;DB schema changes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DB online migration and OVO changes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update existing operations that mark volumes as temporary to use the new
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;use_quota&lt;/span&gt;&lt;/code&gt; field.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update operations that are not currently marking resources as temporary to do
so with the new &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;use_quota&lt;/span&gt;&lt;/code&gt; field.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;REST API changes to return the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;use_quota&lt;/span&gt;&lt;/code&gt; field as &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;consumes_quota&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cinderclient changes.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;No new tempest test will be added, since the case we want to fix is mostly
around error situations that we cannot force in tempest.&lt;/p&gt;
&lt;p&gt;Unit tests will be provided as with any other patch.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;The API reference documentation will be updated.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;Proposed Cinder code implementation:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.opendev.org/c/openstack/cinder/+/786385"&gt;https://review.opendev.org/c/openstack/cinder/+/786385&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.opendev.org/c/openstack/cinder/+/786386"&gt;https://review.opendev.org/c/openstack/cinder/+/786386&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Proposed python-cinderclient code implementation:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.opendev.org/c/openstack/python-cinderclient/+/787407"&gt;https://review.opendev.org/c/openstack/python-cinderclient/+/787407&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Proposed code to leverage this new functionality in the RBD driver to not
flatten temporary resources:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.opendev.org/c/openstack/cinder/+/790492"&gt;https://review.opendev.org/c/openstack/cinder/+/790492&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Thu, 10 Jun 2021 00:00:00 </pubDate></item><item><title>Snapshotting attached volumes w/o force</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/xena/snapshot-attached-volumes.html</link><description>

&lt;p&gt;Include the URL of your launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/fix-snapshot-create-force"&gt;https://blueprints.launchpad.net/cinder/+spec/fix-snapshot-create-force&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Cinder requires passing the “force” flag to a snapshot create
call to create a snapshot from a volume while it is attached
to an instance.  This is unnecessary, as snapshotting attached
volumes results in crash-consistent snapshots, which are useful,
sufficient, and one of the most common cases of how snapshots
are used in the real world.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Most users and other software that create Cinder snapshots actually
want crash-consistent snapshots of attached volumes, so making this
an exception case is not productive.  Code is written to always
use “force”, and users learn that it is needed to create snapshots.&lt;/p&gt;
&lt;p&gt;In most virtualization platforms for many years, creating
crash-consistent snapshots of online disks is not an exception case,
it is a normal operation.  It should be in Cinder too.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;easier for end users&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;less surprising snapshot API for developers&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Introduce a new microversion that no longer uses a “force” flag
to control when snapshots can be created for a volume.&lt;/p&gt;
&lt;p&gt;This means that snapshot creation succeeds for volumes that are in the
“available” or “in-use” state.  The “force” parameter is no longer needed,
but “force=true” is accepted to reduce code changes required for users who are
currently passing this flag from their code.&lt;/p&gt;
&lt;p&gt;Snapshot creation with “force=false” will be rejected as invalid after
this new microversion.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Introduce a new microversion for this change&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Snapshot creation will succeed for in-use volumes w/o force flag added.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Passing force=True will succeed for in-use volumes as it does currently,
but this parameter is no longer needed for this case.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Passing force=False for snapshot creation is not allowed after the new
microversion.  This is presumably rarely used and removing it reduces
ambiguity about what “force=False” would mean when in-use volumes can
be snapshotted by default.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="active-active-ha-impact"&gt;
&lt;h3&gt;Active/Active HA impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;Minimal cinderclient changes&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Fewer snapshot create calls that return HTTP 400 resulting in the user
issuing a second snapshot create call w/ “force” added&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;eharney&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Fix snapshot-create&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;New API microversion&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tempest Tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Look at backup-create (similar problems)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;New tempest tests in cinder-tempest-plugin&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Minimal&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;/section&gt;
</description><pubDate>Fri, 19 Mar 2021 00:00:00 </pubDate></item><item><title>Include encryption_key_id in volume and backup details</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/wallaby/include-encryption-key-id-in-details.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/include-encryption-key-id-in-details"&gt;https://blueprints.launchpad.net/cinder/+spec/include-encryption-key-id-in-details&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This spec adds the encryption_key_id field to the volume and backup details
for volumes that are encrypted.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;The current API supplies volume details that include a simple boolean that
indicates whether a volume is encrypted. However, when a volume is encrypted,
the details do not include the associated Key Manager (e.g. Barbican)
encryption_key_id. This makes it difficult to correlate encryption keys stored
in Barbican with their associated volumes. Any operator workflow that might
benefit from knowing a volume’s encryption_key_id has to read the value from
the Cinder database.&lt;/p&gt;
&lt;p&gt;A similar situation applies to backups of an encrypted volume. These backups
include a clone of the volume’s encryption key, and the backup’s
encryption_key_id is not available via the API.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;1. An operator wishes to back up and export Cinder volumes and Barbican
secrets for disaster recovery (DR), and later restore the volumes. Knowing
each encrypted volume’s encryption_key_id will facilitate restoring the
correct encryption secret.&lt;/p&gt;
&lt;p&gt;2.1 A user or admin wants to identify the Barbican encryption keys used by
Cinder volumes and/or backups. This proposal will allow them to iterate over
the list of items, and note the encryption_key_id when present in its details.&lt;/p&gt;
&lt;p&gt;2.2 A user or admin wishes to know whether a Barbican secret is used by
Cinder. This is similar to 2.1, but more from Barbican’s perspective. Given
a list of Barbican secrets, the user or admin may want to now which service
is using the secret.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;This proposal would add a microversion to include the encryption_key_id field
in the volume and backup details. The field would be included in the datails
only when relevant:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The encryption_key_id is set (not null)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It isn’t the all-zeros value used by the obsolete fixed-key ConfKeyManager&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Operators continue to resort to accessing the Cinder database whenever they
need to know a volume’s or backup’s encryption_key_id.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The proposed change could be enhanced to require admin privileges.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;A new microversion will be created, and the encryption_key_id will be
added to the volume and backup details.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;On one hand, the proposed change will allow users to see the Key Manager
(Barbican) ID where the encryption secret is stored. But it’s important to
bear these factors in mind:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The encryption_key_id is just a UUID, and access to the actual secret is
protected by Barbican’s security policies.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A volume’s encryption_key_id is already present in the connection_info
returned by the volume attachment API.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="active-active-ha-impact"&gt;
&lt;h3&gt;Active/Active HA impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;The feature will not affect users beyond the fact that displaying the details
of an encrypted volume or backup will include the encryption_key_id field.&lt;/p&gt;
&lt;p&gt;The feature does not require changes in cinderclient, openstackclient or
openstack-sdk.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Alan Bishop &amp;lt;&lt;a class="reference external" href="mailto:abishop%40redhat.com"&gt;abishop&lt;span&gt;@&lt;/span&gt;redhat&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add a new microversion.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update the API documentation and code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add unit tests.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit tests provide sufficient coverage, and there are no plans for tempest
changes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Update the API documentation.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 17 Dec 2020 00:00:00 </pubDate></item><item><title>NVMe Connector Support MDRAID replication</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/wallaby/nvme-connector-md-support.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/nvme-of-add-client-raid-1"&gt;https://blueprints.launchpad.net/cinder/+spec/nvme-of-add-client-raid-1&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;NVMe connector replicated volume support via MDRAID.
Allow OpenStack to use replicated NVMe volumes that are distributed on
scale-out storage.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;When consuming block storage, resilience of the block volumes is required.
This can be achieved on the storage backend with NVMe and iSCSI though the
target will remain a single point of failure. And with multipathing, the HA
of paths to a target does not handle volume data replication.&lt;/p&gt;
&lt;p&gt;A storage solution exposing high performance NVMeoF storage would need a
way to handle volume replication. We propose achieving this by using RAID1
on the host, since the relative performance impact will be less significant
in such an environment and will be greatly outweighed by the benefits.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;When resiliency is needed for NVMeoF storage.&lt;/p&gt;
&lt;p&gt;Taking advantage of NVMe over a high performance fabric, gain benefits of
replication on the host while maintaining good performance.&lt;/p&gt;
&lt;p&gt;In this case volume replica failures will have no impact on the consumer,
and will allow for self healing to take place seamlessly.&lt;/p&gt;
&lt;p&gt;For developers of volume drivers, this will allow support for OpenStack
to use replicated volumes that they would expose in their storage backend.&lt;/p&gt;
&lt;p&gt;End users operating in this mode will benefit from performance of NVMe with
added resilience due to volume replication.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Expand the NVMeoF connector in os-brick to be able to take in connection
information for replicated volumes.&lt;/p&gt;
&lt;p&gt;When &lt;cite&gt;connect_volume&lt;/cite&gt; is called with replicated volume information, NVMe
connect to all replica targets and create a RAID1 over the devices.&lt;/p&gt;
&lt;a class="reference internal image-reference" href="https://wiki.openstack.org/w/images/a/ab/Nvme-of-add-client-raid1-detail.png"&gt;&lt;img alt="NVMe client RAID diagram" src="https://wiki.openstack.org/w/images/a/ab/Nvme-of-add-client-raid1-detail.png" style="width: 448px;"/&gt;
&lt;/a&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Replication can also be actively maintained on the backend side, which is
the way it is commonly done. However, with NVMe on a high performance fabric,
the benefits of handling replication on the consumer host can outweigh the
performance costs.&lt;/p&gt;
&lt;p&gt;Adding support for this also increases the type of backends we fully support,
as not all vendors will chose supporting replication on the backend side.&lt;/p&gt;
&lt;p&gt;And we can support both without any kind of impact on each one.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;NVMe Connector’s &lt;cite&gt;connect_volume&lt;/cite&gt; and &lt;cite&gt;disconnect_volume&lt;/cite&gt; param
&lt;cite&gt;connection_properties&lt;/cite&gt; can now also hold a &lt;cite&gt;volume_replicas&lt;/cite&gt; list, which will
contain necessary info for connecting to and identifying the NVMe subsystems
for then doing MDRAID replication over them.&lt;/p&gt;
&lt;p&gt;Each replica dict in &lt;cite&gt;volume_replicas&lt;/cite&gt; list must include the normal flat
connection properties.&lt;/p&gt;
&lt;p&gt;If &lt;cite&gt;volume_replicas&lt;/cite&gt; has only one replica, treat it as non-replicated volume.&lt;/p&gt;
&lt;p&gt;If &lt;cite&gt;volume_replicas&lt;/cite&gt; is ommitted, use the normal flat connection properties
for NVMe as in the existing version of this NVMe connector.&lt;/p&gt;
&lt;p&gt;non-replicated volume connection properties:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'uuid'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'96e25fb4-9f91-4c88-ab59-275fd354777e'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s1"&gt;'nqn'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'nqn.2014-08.org.nvmexpress:uuid:...'&lt;/span&gt;
 &lt;span class="s1"&gt;'portals'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
     &lt;span class="s1"&gt;'address'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'10.0.0.101'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="s1"&gt;'port'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'4420'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="s1"&gt;'transport'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'tcp'&lt;/span&gt;
 &lt;span class="p"&gt;}],&lt;/span&gt;
 &lt;span class="s1"&gt;'volume_replicas'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;replicated volume connection properties:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'volume_replicas'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
     &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'uuid'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'96e25fb4-9f91-4c88-ab59-275fd354777e'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s1"&gt;'nqn'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'nqn.2014-08.org.nvmexpress:uuid:...'&lt;/span&gt;
      &lt;span class="s1"&gt;'portals'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
          &lt;span class="s1"&gt;'address'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'10.0.0.101'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s1"&gt;'port'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'4420'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s1"&gt;'transport'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'tcp'&lt;/span&gt;
      &lt;span class="p"&gt;}]},&lt;/span&gt;
     &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'uuid'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'12345fb4-9f91-4c88-ab59-275fd3544321'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s1"&gt;'nqn'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'nqn.2014-08.org.nvmexpress:uuid:...'&lt;/span&gt;
      &lt;span class="s1"&gt;'portals'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
          &lt;span class="s1"&gt;'address'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'10.0.0.110'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s1"&gt;'port'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'4420'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s1"&gt;'transport'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'tcp'&lt;/span&gt;
      &lt;span class="p"&gt;}]},&lt;/span&gt;
&lt;span class="p"&gt;]}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;Requires elevated priviliges for managing MDRAID.
(Current NVMe connector already does sudo executions of nvme cli, so this
change will just add execution of &lt;cite&gt;mdadm&lt;/cite&gt;)&lt;/p&gt;
&lt;/section&gt;
&lt;section id="active-active-ha-impact"&gt;
&lt;h3&gt;Active/Active HA impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;Working in this replicated mode will allow for special case scenarios where for
example a MDRAID array with 4 replicas loses connection to two of the replicas,
keeps writing data to two remaining ones. Then, after a re-attach from a reboot
or a migration, for some reason now has access to only the two originally
lost replicas, and not the two “good” ones, then the re-created MDRAID array
will have old / bad data.&lt;/p&gt;
&lt;p&gt;The above can be remedied by storage backend awareness of devices going faulty
in the array. This is enabled by the NVMe monitoring agent, which can recognize
replicas going faulty in an array and notify the storage backend, which will
mark these replicas as faulty for the replicated volume.&lt;/p&gt;
&lt;p&gt;Multi attach is not supported for NVMe MDRAID volumes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Replicated volume attachments will be slower (need to build MDRAID array).
It’s a fair tradeoff, slower attachment for more resiliency.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;NVMe and MDRAID and their CLI clients (&lt;cite&gt;nvme&lt;/cite&gt; and &lt;cite&gt;mdadm&lt;/cite&gt;) need to be
available on the hosts for NVMe connections and RAID replication respectively.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Gives option for storage vendors to support replicated NVMeoF volumes via
their driver.&lt;/p&gt;
&lt;p&gt;To use this feature, volume drivers will need to expose NVMe storage that is
replicated and provide necessary connection information for it when using this
feature of the connector.&lt;/p&gt;
&lt;p&gt;This would not affect non-replicated volumes.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Zohar Mamedov&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;zoharm&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;All done in NVMe connector:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;In &lt;cite&gt;connect_volume&lt;/cite&gt; parse connection information for replicated volumes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Connect to NVMeoF targets and identify the devices.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create MD RAID1 array over devices.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Return symlink to MDRAID device.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;cite&gt;disconnect_volume&lt;/cite&gt; destroy the MDRAID.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;cite&gt;extend_volume&lt;/cite&gt; grow the MDRAID.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;NVMe and MDRAID and their CLI clients (&lt;cite&gt;nvme&lt;/cite&gt; and &lt;cite&gt;mdadm&lt;/cite&gt;) need to be
available on the hosts for NVMe connections and RAID replication respectively.
Fail gracefully if they are not found.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;In order to properly test this in tempest, programmatic access will be needed
to the storage backend. For example, to fail one of the drives of a replicated
volume.&lt;/p&gt;
&lt;p&gt;We could also slide by with just a check of connected NVMe subsystems
(&lt;cite&gt;nvme list&lt;/cite&gt;) and scan of MDRAID arrays (&lt;cite&gt;mdadm -D scan&lt;/cite&gt;) to see that multiple
NVMe devices were connected and a RAID was created.&lt;/p&gt;
&lt;p&gt;In either case tempest will need to be aware that the storage backend is
configured to use replicated NVMe volumes and only then do these checks.&lt;/p&gt;
&lt;p&gt;Aside from that, running tempest with NVMe replicated volume backend
will still fully test this functionality, it’s just the specific assertions
(nvme devices and RAID info) that would be different.&lt;/p&gt;
&lt;p&gt;Finally, we will start with unit tests, and have functional tests in os-brick
as a stretch goal.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Document that NVMe connector will now support replicated volumes and that
connection information of replicas is required from the volume driver to
support it.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;Architectural diagram
&lt;a class="reference external" href="https://wiki.openstack.org/wiki/File:Nvme-of-add-client-raid1-detail.png"&gt;https://wiki.openstack.org/wiki/File:Nvme-of-add-client-raid1-detail.png&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Fri, 11 Dec 2020 00:00:00 </pubDate></item><item><title>Store volume format info in Cinder</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/wallaby/store-volume-format-info.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/add-support-store-volume-format-info"&gt;https://blueprints.launchpad.net/cinder/+spec/add-support-store-volume-format-info&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently, there are several filesystem-based drivers in Cinder which rely
on auto detection of formats. Cinder does not store the actual format of
volume and supposes all volumes are “raw” format.&lt;/p&gt;
&lt;p&gt;One of such problems is seen when using glance cinder store with nfs as
cinder backend and the file to be copied is a qcow2 image. When performing
the extend operation, qemu-img uses the resize command which detects
the volume format as qcow2 by reading the image’s qcow2 header written into
the volume. This leads to unsuccessful creation of the image.
This is a problem because current code depends on auto detection of format
and if the user has written a qcow2 image into the volume, the driver thinks
it is a qcow2 volume (rather than qcow2 image stored in a raw volume) hence
causing complication.
Thus we need to store format info instead of auto detection.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;The “format” info will be added to “volume_admin_metadata” of volumes.
The “format” will be only set / updated for filesystem-based drivers, other
drivers will not contain this metadata.
The “format” field will be created by FS drivers at the time of volume creation
and is set to the format which the driver is configured to use.
The “format” info will be returned in the attachment get API in the
connection_info dict.
When cloning a volume, this field will be updated in the new volume’s metadata.
For existing volumes, we check if format exists in admin_metadata and if not,
we can perform &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;qemu-img&lt;/span&gt; &lt;span class="pre"&gt;info&lt;/span&gt;&lt;/code&gt; to get the format and store it in the
admin_metadata at that point.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Some of the fs type driver uses “qemu-img info” command to judge
the format of volume. However, this auto-detection method has many possible
error / exploit vectors. Because if the beginning content of a “raw” volume
happens to be a “qcow2” disk, auto detection method will judge this volume to be
a “qcow2” volume wrongly. This is the same issue which cases glance to fail
an image create operation when using cinder as a store.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;For volumes on filesystem-based drivers, there will be a related record in
volume_admin_metadata table. For this record, the key column is “format” and
the value is the volume’s format in volume_admin_metadata table.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;The “format” info will returned in attachment get API:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v3&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;attachments&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;attachment_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"attachment"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"3b8b6631-1cf7-4fd7-9afb-c01e541a073c"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="o"&gt;...&lt;/span&gt;
        &lt;span class="s2"&gt;"connection_info"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"format"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"raw"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="o"&gt;...&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;Implements the proper/complete fix for bug 1350504.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;Fixes problem where a user can cause a volume to become inoperable
by writing a qcow2 header into it.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;whoami-rajat&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;To support this feature, the work items are:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Store format info in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volume_admin_metadata&lt;/span&gt;&lt;/code&gt; table when creating or
cloning a volume in fs type drivers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify volume format when doing a snapshot delete (blockRebase) operation
on an attached volume.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pass format info when doing an extend operation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Return format field in the attachment get API in connection_info dict.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Related unit and functional tests.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Add documentation regarding the format field visible in the attachment get API
for fs drivers.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Mon, 02 Nov 2020 00:00:00 </pubDate></item><item><title>Specify availability_zone and volume_type for backup restore API</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/wallaby/specify-volume_type-and-availability_zone-for-backup-restore-API.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/availabilityzone-and-volumetype-for-backup-restore"&gt;https://blueprints.launchpad.net/cinder/+spec/availabilityzone-and-volumetype-for-backup-restore&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Add two optional parameters to specify availability_zone and volume_type for
cinder backup restore API to better support backup and restore across
availability zones.&lt;/p&gt;
&lt;p&gt;Backup across availability_zones is a typical scenario for disaster recovery:
say, backup driver located in AZ-1 is configured to backup data to backup
backend located in AZ-2.  When AZ-1 crashes, user tries to restore volume from
the backup data located in AZ-2.  It would be useful to provide parameters for
user to specify the availability_zone and the volume_type of the restore
volume.&lt;/p&gt;
&lt;p&gt;The availability_zone parameter will enable user to create a restore volume to
a specified availability_zone where the backup data is actually located.  The
geographical locality will enhance the performance for restore copy.&lt;/p&gt;
&lt;p&gt;While with the volume_type parameter, the backup restore API can provide more
options for user to create a restore volume, say, with rbd backup backend,
compared with LVM, user could choose to restore to a rbd volume, where restore
will do diff copy instead of full copy and thus enhance restore efficiency.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently, when user makes a request to restore a backup without volume_id, the
backup-restore API will create a restore volume with default volume_type and
default availability_zone.&lt;/p&gt;
&lt;p&gt;As the availability_zone is none, cinder scheduler will randomly pick up one
availability_zone to create this restore volume.  In one typical disaster
recovery scenario described above, restore volume with randomly selected
availability_zone may locate in an availability_zone geographically far away
from backup data.  In this way, restore might fail if the restore side backup
driver could not access backup data across availability_zones.  Even if backup
driver could access backup data remotely, cross-wan IO will cause a performance
penalty.  No matter for the sake of correctness or efficiency, user would like
to have control of specifying the availability_zone of restore volume.&lt;/p&gt;
&lt;p&gt;Without volume type option, the restore volume will be created with default
volume type and thus default volume backend.  Since the default volume backend
may not understand the backup data format, the backup driver may not be able to
take the most efficient way to restore from the backup data but will do a full
copy.  It is better to give user more options to enhance restore performance.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;There are customers who want to restore a backup in a certain backend and
availability_zone without any restore volume. The customers can specify the
volume_type and availability_zone to restore this backup.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;In order to solve this problem, we add two optional parameters to specify
volume_type and availability_zone for the backup-restore API.  The volume_type
parameter is to specify the volume backend of the restore volume.  The
availability_zone parameter is to specify the availability_zone where the
restore volume would locate in.  Thus, user could choose restore volume type
according to backup backend and choose restore volume location geographically
close to the backup data location.  This change will give user more options to
ensure restore correctness and enhance restore performance.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;dl&gt;
&lt;dt&gt;Modify REST API to restore backup:&lt;/dt&gt;&lt;dd&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;POST /v3.x/{tenant_id}/backups/{id}/action&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add volume_type and availability_zone in request body&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;JSON request schema definition:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="s1"&gt;'backup-restore'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'volume_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;volume_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'volume_type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;volume_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'availability_zone'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;availability_zone&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;Ensure type and AZ are included in the restore.start notification.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;End user will be able to restore a backup with specified volume_type and
availability_zone.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;This might allow cross-az restore scenarios that weren’t possible before,
which might cause network performance degradation.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;The deployer will be able to restore a backup with specified volume_type and
availability_zone.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;alan-bishop&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&amp;lt;None&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;TBD&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit tests and tempest tests will be provided.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Fri, 21 Aug 2020 00:00:00 </pubDate></item><item><title>Native Rest Block Driver</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/juno/restblock-driver.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/restblock-driver"&gt;https://blueprints.launchpad.net/cinder/+spec/restblock-driver&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;We, at scality, are working on a Linux native kernel driver: Rest Block Driver.
(it is on github, but still private as we want to reach a certain point before
releasing it). This is a kernel driver that is able to talk to a REST-based
storage service (we plan to eventually support multiple rest backends), in
order to attach the files from that storage as native block devices on the host
linux. One of the key points is that it allows a REST-based volume storage to
take advantage of linux’s block driver cache.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;As a company, we are interested in providing an Openstack integration to our
clients, and as such, we want to provide a new driver for cinder to drive and
make use of the aforementionned Rest Block Driver.&lt;/p&gt;
&lt;p&gt;This block driver currently offers the following simple features:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Mirror-server list management (failover and load balancing)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Provisioning (create/extend/delete)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Automatic attach/detach of volumes (practical for use within cinder)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Also, we have plans for a few features that should come shortly:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Storage Pool management to provide volumes from different storage pools.
Each pool will have their own list of mirrors to choose from.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Real failover implementation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Multiple back-ends support (for multiple REST-like protocols
implementations, ours being a CDMI implementation)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Native snapshot management&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;The Rest Block Driver is mostly controlled through the /sys file system. Thus,
most of the control operations will be implemented using the process utils
module. For the general feature implementation, here is how we plan to support
the multiple required features of a Cinder driver:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Provisioning (create/extend/delete) : natively supported by the kernel
driver&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Automatic attach of volumes at setup-time: Natively supported by the kernel
driver&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Snapshots (create/delete) : Supported through LVM tool classes/functions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Copy To/From Image: Supported thanks to image_utils&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Volume Cloning (from volume or from snapshot): Supported through copy utils&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Please not that this reflects the current state of the kernel driver, and might
evolve.&lt;/p&gt;
&lt;p&gt;In the future it will provide a way to manage the snapshots from the driver
itself, but it is not yet supported. Thus, the driver will use the lvm code
tools to manage thin snapshot provisioning and support snapshots for the
volumes exposed by our Rest Block Driver.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;Since this driver is controlled through the /sys file system, it requires
administrative privileges to be controlled (ie. to write/read from /sys files).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;As this is a 3rd-party provided driver, it implies setting up the said
software first. Other than that, only the new driver-specific configuration
values will be added.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&amp;lt;&lt;a class="reference external" href="mailto:dav.pineau%40gmail.com"&gt;dav&lt;span&gt;.&lt;/span&gt;pineau&lt;span&gt;@&lt;/span&gt;gmail&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;None&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;Provide a cinder driver leveraging both LVM for non-implemented features and
the driver itself for the natively supported features.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;The driver does not bring any modification to the existing APIs and behaviors.
As such, no new tempest tests should be required in our understanding.&lt;/p&gt;
&lt;p&gt;As this driver relies on a vendor-specific software, the gate obviously cannot
test the driver. We are currently setting up third-party CI testing for both
our previous driver (Scality Sofs) and this new one.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Tue, 09 Jun 2020 00:00:00 </pubDate></item><item><title>Support volume local cache</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/victoria/support-volume-local-cache.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/support-volume-local-cache"&gt;https://blueprints.launchpad.net/cinder/+spec/support-volume-local-cache&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This blueprint proposes to add support of volume local cache in cinder and
os-brick. Cache software such as open-cas &lt;a class="footnote-reference brackets" href="#id4" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;5&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; can use fast NVME SSD or
persistent memory (configured as block device mode) to cache for slow remote
volumes.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently there are different types of fast NVME SSDs, such as Intel Optane
SSD, with latency as low as 10 us. What’s more, persistent memory which aim to
be SSD size but DRAM speed gets popupar now. Typical latency of persistent
memory would be as low as hundreds of nanoseconds. While typical latency of
remote volume for a VM can be at the millisecond level (iscsi / rbd). So these
fast SSDs or persistent memory can be mounted locally on compute nodes and used
as a cache for remote volumes.&lt;/p&gt;
&lt;p&gt;In order to do the cache, three projects need to be changed. These are cinder,
os-brick, and Nova. Meanwhile related hardware should be added in system, e.g.
high performance SSD or persistent memory. The mechanism is similar to volume
encryption where dm-crypt is used. Cache software support would be added in
os-brick and Nova will call os-brick when it is trying to attach a volume,
os-brick then calls the cache software to setup the cache for the volume. After
that, a new virtual block device would be created and laying upon the original
block device. os-brick will expose this new virtual block device to Nova,
meanwhile the original block device mount point will remain unchanged. All of
the cache setup and teardown would be handled within os-brick.&lt;/p&gt;
&lt;p&gt;A property would be added in the extra specs of the volume type. If a volume
type has extra-spec of “cacheable”, then it means the related volumes can be
cached in compute node locally.&lt;/p&gt;
&lt;p&gt;Like all the local cache solution, multi-attach cannot be supported. This is
because cache on node1 doesn’t know the changes made to backend volume by
node2. So cinder should guarantee these two properties cannot be set at the
same time.&lt;/p&gt;
&lt;p&gt;Considering VM migration, cache software should not format the source volume
(the volume to be cached). So cache software such as bcache cannot be used.
This spec only supports open-cas. open-cas is easy to use, you just need to
specify a block device as the cache device, and then can use this device to
cache other block devices. This is transparent to upper layer and lower layer.
Regarding upper layer, guest doesn’t know it is using an emulated block device.
Regarding lower layer, backend volume doesn’t know it is cached, and the data
in backend volume will not have extra change because of cache. That means even
if the cache is lost for some reason, the backend volume can be mounted to
other places and become available immediately. open-cas supports the cache
modes below:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Write-Through (WT): write to cache and backend storage at the same time. So
the data is fully synced in cache and backend storage. There will not be any
data corruption when cache becomes invalid.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Write-Around (WA): like Write-Through, but only cache for volume blocks that
are already in cache.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Write-Invalidate (WI): write to backend storage and invalidate cache&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Write-Back (WB): write to cache and lazy write to backend storage. This mode
has better write performance but is possible to lose data because the latest
data is in cache, but may not be flushed to the backend storage.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Write-Only (WO): like write-back, but only cache write, will not cache read.
So this mode also has the possibility to lose data.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The first three modes are suitable for scenarios that data integrity must be
guaranteed, every write io is both written to cache and backend storage. In
these modes it is just like read-only cache feature in ceph. No operation would
be blocked. e.g. VM live migration, snapshot taking, volume backup and others
can be done as usual. Cache software can also be changed to others rather than
open-cas at any time because there’s no dirty data in cache at any time. This
is suitable for read intensive scenario, but it will be no benefit for write io
because every write io need to go to backend storage everytime for data
integrity.&lt;/p&gt;
&lt;p&gt;The last two modes are suitable for scenarios that have high requirements for
both read/write performance, but low requirements for data integrity. E.g. some
test environment. In these two modes, all operations that depend on the backend
volume containing full data would not work safely. So VM live migration,
snapshot, volume backups, consistency groups, etc, cannot works safely because
there may be still dirty data in cache. At least, operator need to stop the
disk io by some way and flush the cache(via casadm) before doing these
operations. Cache software also cannot be changed to others except all dirty
data has been flushed to backend.&lt;/p&gt;
&lt;p&gt;Cache mode can be got from cache instance ID via cache admin tool. Nova passes
available cache instances ID list to os-brick, so os-brick knows the cache mode
of the cache instances. This spec would make os-brick refuse to attach volume
with last two cache modes. But cache mode is set outside of OpenStack, Cinder /
os-brick cannot control cache mode being modified after volume attached. But it
would be well documented that Write-Back (WB) and Write-Only (WO) mode is
dangerous and operators should fully know what they are doing when trying to
set to these cache modes.&lt;/p&gt;
&lt;p&gt;Some storage backends may support discard/TRIM functionality, but cache
software doesn’t have sense of this. Cache software evicts data based on policy
like ‘lru’(this is the default policy of open-cas).&lt;/p&gt;
&lt;p&gt;Some storage client, compute node, may enable multipath for volumes, e.g.
iscsi/fc volumes. Volume local cache would not work with multipath, with the
same reason of multi-attach. os-brick detects multipath via function
get_volume_paths() and would not set cache for volume with multipath.&lt;/p&gt;
&lt;p&gt;No restrictions would be introduced on retyping a ‘cacheable’ volume. This is
because retyping includes two steps: 1) attach new volume 2) detach old volume.
So old volume would be released from caching, new volume would be cached.&lt;/p&gt;
&lt;p&gt;This is the shared cache, and the number of volumes to be cached is unlimited.
A volume be cached does not mean it will occupy space in cache. The volumes
with hot IO will consume more cache space, meanwhile volumes with no IO will
not occupy any space in cache devce. The data in cache would be evicted when
the data getting cold or other volume’s IO getting hot.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;In read intensive scenarios, e.g. AI training, VM volume local cache will
significantly boost the storage performance (throughput, and especially disk
io latency)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;In order to do volume local cache:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;In Nova, end user selects a flavor that is advertised as having a
volume-local-cache so guest can be landed in a server with cache capability.
The end user should expect different performance based on what server flavor
was chosen. More information such as error handling, user message, etc, are
out of scope of this spec and would be defined in Nova spec &lt;a class="footnote-reference brackets" href="#id3" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In Cinder, volume type that is ‘cacheable’ should be selected.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It is Cinder which determines and sets the ‘cacheable’ property. A volume
marked as “cacheable” doesn’t mean it must be cached, it just means it is
eligible to be cached. Nova calls os-brick to set cache for the volume only
when the volume has the property of ‘cacheable’.&lt;/p&gt;
&lt;p&gt;Cache mode is bound to cache instance. So different cache instances can have
different cache modes. All cached volumes share same cache mode if they are
cached by the same cache instance. The operator can change cache mode
dynamically, using cache software management tool. So cache mode setting is out
of OpenStack and is not controlled by OpenStack. Operator should not change
cache to unsafe mode. os-brick just accepts the cache name and cache instance
IDs from Nova.&lt;/p&gt;
&lt;p&gt;cache_name identifies which cache software to use, currently it only supports
‘opencas’. Nova knows what cache name is, based on which cache software is
enabled in compute node.&lt;/p&gt;
&lt;p&gt;Each compute node can have more than one cache instances. os-brick can weight
each cache instance passed in, by e.g. total cache size, how many free space,
etc, via cache admin tool(casadm), and select the best one.&lt;/p&gt;
&lt;p&gt;Some storage types support “extend volume” which triggered from cinder side.
e.g. via command “cinder extend …”. It works normally when the volume is not
“in-use”. But if the volume is attached and “in-use”, os-brick would not
support to extend and just raise NotImplementedError for the volume with
cacheable volume_type. This is because open-cas don’t support volume extending
dynamically in current release. But “Resize Instance” feature which triggered
from Nova still can work, because volume will be detached and then re-attached
during “”Resize Instance”.&lt;/p&gt;
&lt;p&gt;The final solution would be like:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;                       &lt;span class="n"&gt;Compute&lt;/span&gt; &lt;span class="n"&gt;Node&lt;/span&gt;

&lt;span class="o"&gt;+---------------------------------------------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                                                         &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                        &lt;span class="o"&gt;+-----+&lt;/span&gt;    &lt;span class="o"&gt;+-----+&lt;/span&gt;    &lt;span class="o"&gt;+-----+&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;VM1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;VM2&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;VMn&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                        &lt;span class="o"&gt;+--+--+&lt;/span&gt;    &lt;span class="o"&gt;+--+--+&lt;/span&gt;    &lt;span class="o"&gt;+-----+&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                           &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+---------------------------------------------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                           &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;+---------+&lt;/span&gt;         &lt;span class="o"&gt;+-----+----------+-------------+&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;Nova&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="n"&gt;QEMU&lt;/span&gt; &lt;span class="n"&gt;Virtio&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;+-+-------+&lt;/span&gt;         &lt;span class="o"&gt;+-----+----------+----------+--+&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;                       &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;attach&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;detach&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;                 &lt;span class="o"&gt;+-----+----------+------+&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;+-+-------+&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;dev&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;cas1&lt;/span&gt;  &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;dev&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;cas2&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;osbrick&lt;/span&gt; &lt;span class="o"&gt;+---------+&lt;/span&gt;                       &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;+---------+&lt;/span&gt; &lt;span class="n"&gt;casadm&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="nb"&gt;open&lt;/span&gt; &lt;span class="n"&gt;cas&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                     &lt;span class="o"&gt;+-+---+----------+------+&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                       &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                       &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="n"&gt;Storage&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;+--------+&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;+-----+----+&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;rbd&lt;/span&gt;   &lt;span class="o"&gt;+---------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;dev&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;sdd&lt;/span&gt; &lt;span class="o"&gt;+----------+&lt;/span&gt;  &lt;span class="n"&gt;Vol1&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;+----------+&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;+---------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;+-----+-----+&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;Vol2&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Fast&lt;/span&gt; &lt;span class="n"&gt;SSD&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;+-----+----+&lt;/span&gt;   &lt;span class="n"&gt;iscsi&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;fc&lt;/span&gt;&lt;span class="o"&gt;/...&lt;/span&gt;      &lt;span class="o"&gt;+---------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;+-----------+&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;dev&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;sdc&lt;/span&gt; &lt;span class="o"&gt;+-------------+-------+&lt;/span&gt;  &lt;span class="n"&gt;Vol3&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                           &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;+----------+&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;+---------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                           &lt;span class="o"&gt;|&lt;/span&gt;                             &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;Vol4&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                     &lt;span class="o"&gt;+-----+----+&lt;/span&gt;    &lt;span class="n"&gt;iscsi&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;fc&lt;/span&gt;&lt;span class="o"&gt;/...&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;+---------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;dev&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;sdb&lt;/span&gt; &lt;span class="o"&gt;+--------------------------------+&lt;/span&gt;  &lt;span class="n"&gt;Vol5&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                     &lt;span class="o"&gt;+----------+&lt;/span&gt;                        &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;+---------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                                                         &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;.....&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+---------------------------------------------------------+&lt;/span&gt;       &lt;span class="o"&gt;+---------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Changes would include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Add “cacheable” property in extra-spec of volume type&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Volume local cache cannot work with multiattach. So when adding “cacheable”
to extra-spec, cinder should check if “multiattach” property exists or not.
If “multiattach” exists, then cinder should refuse to add “cacheable”
property to volume type, and vice versa.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fill “cacheable” property in connection_info. So os-brick can know whether
a volume can be cached or not.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a common framework for different cache software in os-brick. This
framework should be flexible to support different cache software.&lt;/p&gt;
&lt;p&gt;1) A base class - CacheManager would be added and the main functions would
be:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;__init__()&lt;/p&gt;
&lt;p&gt;This function would accept the parameters from Nova. Parameters include:&lt;/p&gt;
&lt;p&gt;root_helper - used for cache software management tools.&lt;/p&gt;
&lt;p&gt;connection_info - containing device path&lt;/p&gt;
&lt;p&gt;cache_name - specify the cache software name, currently only support ‘opencas’&lt;/p&gt;
&lt;p&gt;instance_ids - specify cache instances that can be used. os-brick chooses a
best one among these instances&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;attach_volume()&lt;/p&gt;
&lt;p&gt;This function would be called by Nova (in function _connect_volume) to
setup cache for a volume when it is trying to attach the volume.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;detach_volume()&lt;/p&gt;
&lt;p&gt;This function would be called by Nova (in function _disconnect_volume) to
release the cache when it is trying to detach a volume.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;2) In __init__.py, a map of cache software and its python class would be
added. So os-brick can find the correct class based on cache name.&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;CACHE_NAME_TO_CLASS_MAP = {&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;“opencas”: ‘os_brick.caches.opencas.OpenCASEngine’,
…&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Meanwhile a function like _get_engine() would be added to go through the
map to find the correct class.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the support for open-cas in os-brick.&lt;/p&gt;
&lt;p&gt;Implement functions attach_volume/detach_volume for open-cas.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Code work flow would be like:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;            Nova                                        osbrick

                                              +
         +                                    |
         |                                    |
         v                                    |
   attach_volume                              |
         +                                    |
         |                                    |
         +                                    |
       attach_cache                           |
             +                                |
             |                                |
             +                                |
 +-------+ volume_with_cache_property?        |
 |               +                            |
 | No            | Yes                        |
 |               +                            |
 |     +--+Host_with_cache_capability?        |
 |     |         +                            |
 |     | No      | Yes                        |
 |     |         |                            |
 |     |         +-----------------------------&amp;gt; attach_volume
 |     |                                      |        +
 |     |                                      |        |
 |     |                                      |        +
 |     |                                      |      set_cache_via_casadm
 |     |                                      |        +
 |     |                                      |        |
 |     |                                      |        +
 |     |                                      |      return emulated_dev_path
 |     |                                      |        +
 |     |                                      |        |
 |     |         +-------------------------------------+
 |     |         |                            |
 |     |         v                            |
 |     |   replace_device_path                |
 |     |         +                            |
 |     |         |                            |
 v     v         v                            |
                                              |
attach_encryptor and                          |
rest of attach_volume                         +
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Volume local cache lays upon encryptor would have better performance, but
expose decrypted data in cache device. So based on security consideration,
cache should lay under encryptor in Nova implementation.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Assign local SSD to a specific VM. VM can then use bcache internally against
the ephemeral disk to cache their volume if they want.&lt;/p&gt;
&lt;p&gt;The drawbacks may include:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Can only accelerate one VM. The fast SSD capability cannot be shared by
other VMs. Unlike RAM, SSD normally is in TB level and large enough to
cache for all the VMs in one node.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The owner of the VM should setup cache explicitly. But not all the VM
owners want to do this, and not all the VM owners have the knowledge to do
this. But they for sure want that the volume performance to be better by
default.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a dedicated cache cluster. Mount all the cache (NVME SSD) in the cache
cluster as a big cache pool. Then allocate a certain amount of cache to a
specific volume. The allocated cache can be mounted on compute node through
NVMEoF protocol. Then use cache software to do the same cache.&lt;/p&gt;
&lt;p&gt;But this would be the compete between local PCIe and remote network. The
disadvantage of doing it like this is: the network of the storage server
would be a bottleneck.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Latency: Storage cluster typically provides volumes through iscsi/fc
protocol, or through librbd if ceph is used. The latency would be at the
millisecond level. Even with NVME over TCP, the latency would be hundreds
of microseconds, depending on the network topology. In contrast, the
latency of NVME SSD would be around 10 us, take Intel Optane SSD p4800x as
example.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cache can be added in backend storage side, e.g. in ceph. Storage server
normally has its own cache mechanism, e.g. using memory as cache, or using
NVME SSD as cache.&lt;/p&gt;
&lt;p&gt;Similiar with above solution, latency is the disadvantage.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Cache software will remove the cached volume data from cache device when
volume is detached. But normally it would not erase the related sectors in
cache device. So in theory the volume data is still in cache device before it
is overwritten. Unless the cache device is plugged out, otherwise it is
acceptable because the volume itself is also mounted and visible on host OS.
Volume with encryption doesn’t have this issue if encryption laying upon
volume local cache.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Latency of VM volume would be reduced&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Need to configure cache software in compute node&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The support for other cache software can be added by other developers later&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Liang Fang &amp;lt;&lt;a class="reference external" href="mailto:liang.a.fang%40intel.com"&gt;liang&lt;span&gt;.&lt;/span&gt;a&lt;span&gt;.&lt;/span&gt;fang&lt;span&gt;@&lt;/span&gt;intel&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Implement a common framework for supporting different cache software&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Support open-cas&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unit test be added&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit-tests, tempest and other related tests will be implemented.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Test case in particular: leverage DRAM to simulate fast ssd, act as the cache
for open-cas; Use fio to do the 4k block size rand read test; Compare the
result of volume with / without cache. The expected behavior is: cached
volume would get lower latency.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Documentation will be needed. User documentation on how to use cache software
to cache volume.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;[1] &lt;a class="reference external" href="https://review.opendev.org/#/c/663549/"&gt;https://review.opendev.org/#/c/663549/&lt;/a&gt;
[2] &lt;a class="reference external" href="https://review.opendev.org/#/c/663542/"&gt;https://review.opendev.org/#/c/663542/&lt;/a&gt;
[3] &lt;a class="reference external" href="https://review.opendev.org/#/c/700799/"&gt;https://review.opendev.org/#/c/700799/&lt;/a&gt;&lt;/p&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id3" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;4&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.opendev.org/#/c/689070/"&gt;https://review.opendev.org/#/c/689070/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id4" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;5&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://open-cas.github.io/"&gt;https://open-cas.github.io/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Wed, 20 May 2020 00:00:00 </pubDate></item><item><title>Support modern compression algorithms in cinder backup</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/victoria/support-modern-compression-algorithms-in-cinder-backup.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/support-modern-compression-algorithms-in-cinder-backup"&gt;https://blueprints.launchpad.net/cinder/+spec/support-modern-compression-algorithms-in-cinder-backup&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This blueprint proposes to add support of modern compression algorithms like
zstd to cinder backup.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Cinder backup currently supports only gzip and bzip2 to compress/decompress the
volume data during backup and restore operation.&lt;/p&gt;
&lt;p&gt;It should support other compression algorithms as well because efficiency of
compression entirely depends on cloud provider’s environment and choice. Some
may want fast compression compromising the compression ratio, so to provide more
choices to cloud provider, it will be good to add support of other algorithm
like zstd.&lt;/p&gt;
&lt;p&gt;Zstandard(zstd) gives high compression ratio(comparable to zlib) with very much
fast speed. It’s now used as package compression algorithm for arch linux.&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://facebook.github.io/zstd/"&gt;https://facebook.github.io/zstd/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Some general benchmark result is available on the website introduced above, or
lzbench website.&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/inikep/lzbench/"&gt;https://github.com/inikep/lzbench/&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Cinder backup with high-speed compression algorithm&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;add zstd algorithm package details in requirements.txt.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;add the support of zstd algorithm in get compressor routine of cinder backup.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Cinder backup and restore operation gets faster.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Size of backup data may be bigger than zlib or bz2 compression algorithm
(depends on content of data volume)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Simple performance test result I have done&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Server spec: 8core CPU, 16GB memory&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Backup store is NFS-backend on localhost (i.e. small network bottleneck)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Backup/restore a 16GB volume created from a Windows image (qcow2
12001017856 bytes)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Measured backup/restore time backup data size, and size ratio versus size of
qcow2 (considering as approximate amount of data in the volume)
The smaller the better for all values.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CPU usage for algo other than zstd is about 100% to 110% (i.e. Using only
one core.) where max usage is 800% (= 8cores * 100%).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CPU usage for zstd is about 80% to 400% (utilizes multi cores).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Famous algorithm like gzip may performs better if offloaded to hardware.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Algorithm&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;backup time(sec)&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;restore time(sec)&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;size(bytes)&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;v.s. qcow2(%)&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;none&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;205.8&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;109.2&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;17218167818&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;143.5&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;gzip&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;743.2&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;141.5&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;6658990044&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;55.5&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;bz2&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;2102.5&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;742.2&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;6480248772&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;54.0&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;zstd(to be added)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;196.2&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;100.2&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;6286227236&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;52.4&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;lz4(for reference)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;211.0&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;113.0&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;7903490364&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;65.9&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;The python module &lt;a class="reference external" href="https://pypi.org/project/zstd/"&gt;zstd&lt;/a&gt; is required to use
zstd compression algorithm.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Primary assignee: Kazufumi Noto&lt;/p&gt;
&lt;p&gt;Other contributors: None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add the package details to cinder/requirements.txt.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement the code to add support of zstd compression.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documents need to be updated to reflect the added support.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add test cases to create backup using zstd compression.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit tests will be added to create backup using zstd compression.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;The following documents need to be updated to reflect the added support:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;cinder sample configuration file in configuration reference.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://facebook.github.io/zstd/"&gt;https://facebook.github.io/zstd/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/inikep/lzbench/"&gt;https://github.com/inikep/lzbench/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Fri, 08 May 2020 00:00:00 </pubDate></item><item><title>Backup Multi-Backends Configuration</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/victoria/backup-backends-configuration.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/backup-backends-configuration"&gt;https://blueprints.launchpad.net/cinder/+spec/backup-backends-configuration&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Add a new config section for backup configuration options to unify the way how
we do it with volume drivers and support multiple backup drivers in one
service.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Right now we’ve got all backup-specific configuration options defined in the
[DEFAULT] section:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;DEFAULT&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;backup_driver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cinder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;backup&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;drivers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ceph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CephBackupDriver&lt;/span&gt;
&lt;span class="n"&gt;backup_ceph_user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cinder&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;backups&lt;/span&gt;
&lt;span class="n"&gt;backup_ceph_pool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;volume&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;backups&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;It leads to mix of backup-specific config options and Cinder general
configuration. This approach also doesn’t support backups multi-backend.
Operators can configure multiple backup backends only by configuring several
cinder-backup services.&lt;/p&gt;
&lt;p&gt;Current approach blocks Generic backup implementation because drivers
self.configuration won’t be able to see required configuration which are
defined in the [DEFAULT] section.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;The main use-case here is to decouple backup-specific configuration from the
[DEFAULT] section and introduce a backup_type.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;The new config option called ‘enabled_backup_backends’ will contain a
list of enabled backup backends. This will implement the same approach as we
have for volumes with ‘enabled_backends’ config option.&lt;/p&gt;
&lt;p&gt;All backup-related configuration will be moved into the new backend-specific
section:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;DEFAULT&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;enabled_backup_backends&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ceph_backup&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ceph_backup_ssd&lt;/span&gt;
&lt;span class="n"&gt;default_backup_type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ceph&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;backup&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ceph_backup&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;backup_driver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cinder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;backup&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;drivers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ceph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CephBackupDriver&lt;/span&gt;
&lt;span class="n"&gt;backup_ceph_user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cinder&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;backups&lt;/span&gt;
&lt;span class="n"&gt;backup_ceph_pool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;volume&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;backups&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ceph_backup_ssd&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;backup_driver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cinder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;backup&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;drivers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ceph&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CephBackupDriver&lt;/span&gt;
&lt;span class="n"&gt;backup_ceph_user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cinder&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;backups&lt;/span&gt;
&lt;span class="n"&gt;backup_ceph_pool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;volume&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;backups&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ssd&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The old-style backup configuration will be supported at least for one release
to follow all deprecation policies.&lt;/p&gt;
&lt;p&gt;With multi-backups configuration we want to introduce backup types too. It
will help us to use all multi-backend advantages. Backup types will follow the
same approach as volume types have:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;__DEFAULT__ backup type will be introduced and all existing backups will be
migrated to this backup type.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;cite&gt;default_backup_type&lt;/cite&gt; config option will be introduced.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Backup types will have own extra specs.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Leave everything as-is and introduce some hacks in the code to get volume
drivers working as a backup drivers in the scope of Generic Backup feature.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;New tables for backup types will be introduced. We’ll follow the same approach
as for volume types which works well for Cinder:&lt;/p&gt;
&lt;p&gt;BackupType
+————–+————–+
|   Field      |     Type     |
+————–+————–+
| created_at   | datetime     |
| updated_at   | datetime     |
| id           | varchar(36)  |
| name         | varchar(255) |
| description  | varchar(255) |
| deleted      | boolean      |
| is_public    | boolean      |
+————–+————–+&lt;/p&gt;
&lt;p&gt;BackupTypeProjects
+—————-+————–+
|   Field        |     Type     |
+—————-+————–+
| created_at     | datetime     |
| updated_at     | datetime     |
| id             | varchar(36)  |
| project_id     | varchar(36)  |
| backup_type_id | varchar(36)  |
| deleted        | boolean      |
+—————-+————–+&lt;/p&gt;
&lt;p&gt;BackupTypeExtraSpecs
+—————-+————–+
|   Field        |     Type     |
+—————-+————–+
| created_at     | datetime     |
| updated_at     | datetime     |
| key            | varchar(255) |
| value          | varchar(255) |
| deleted        | boolean      |
+—————-+————–+&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;New API endpoints  will be implemented for backup types. It should be similar
like volume type API.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Backup creation procedure will contain few more database calls but it should
not affect performance a lot.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;Operators should configure backups using a new mechanism and migrate from
old-style configuration.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;e0ne&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add a new ‘enabled_backup_backends’ config option and deprecate old-style
config&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify the backup manager to honor new configuration&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add some unit tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Devstack should be able to configure cinder backups in a new way&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Operator documentation should be updated&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;API reference should be updated&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Existing tempest tests will cover new functionality&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Update documentation to describe new config option&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;New REST API endpoints will be documented&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/backup-backends-configuration"&gt;https://blueprints.launchpad.net/cinder/+spec/backup-backends-configuration&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://specs.openstack.org/openstack/cinder-specs/specs/mitaka/scalable-backup-service.html"&gt;https://specs.openstack.org/openstack/cinder-specs/specs/mitaka/scalable-backup-service.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://specs.openstack.org/openstack/cinder-specs/specs/train/untyped-volumes-to-default-volume-type.html"&gt;https://specs.openstack.org/openstack/cinder-specs/specs/train/untyped-volumes-to-default-volume-type.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Wed, 11 Mar 2020 00:00:00 </pubDate></item><item><title>Add backup id to volume’s metadata</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/ussuri/add_backup_id_to_volume.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/add-volume-backup-id"&gt;https://blueprints.launchpad.net/cinder/+spec/add-volume-backup-id&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently, the end user can see the source (source by snapshot or image etc.)
from the new volume created. But when the end user has restored a backup
volume, in the volume show response, we cannot see its source. This can
cause a lot of confusion for end users.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;As an end user, I would like to know the restored volume comes from which
backup resource.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add the property &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;src_backup_id&lt;/span&gt;&lt;/code&gt; to the volume’s metadata,
to record from which backup the new volume was created from.
When restoring from a chain of incremental backups, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;src_backup_id&lt;/span&gt;&lt;/code&gt;
is set to the last incremental backup used for the restore.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Once added to the volume metadata, the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;src_backup_id&lt;/span&gt;&lt;/code&gt; will appear on
any API response that displays volume metadata:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;the volume-show response (GET /v3/{project_id}/volumes/{volume_id})&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;the volume-list-detail response (GET /v3/{project_id}/volumes/detail)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;the volume-metadata-show response
(GET /v3/{project_id}/volumes/{volume_id}/metadata)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;the volume-metadata-show-key response, only if the key is &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;src_backup_id&lt;/span&gt;&lt;/code&gt;
(GET /v3/{project_id}/volumes/{volume_id}/metadata/{key})&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="vendor-specific-changes"&gt;
&lt;h3&gt;Vendor-specific changes&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None.
The volume-show, volume-list-detail, and volume-metadata-show
responses are currently defined to contain a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;metadata&lt;/span&gt;&lt;/code&gt; element that
is either JSON null or a JSON object consisting of a list of key/value pairs.
The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;src_backup_id&lt;/span&gt;&lt;/code&gt; will appear in this list for appropriate volumes,
but this respects the current API and does not require a new microversion.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Xuan Yandong&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;src_backup_id&lt;/span&gt;&lt;/code&gt; to the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volume&lt;/span&gt;&lt;/code&gt; metadata&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add related unit tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add related functional test&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add tempest tests&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Release note should point out that since this is stored in the volume
metadata, it can be modified or removed by end users, so operators should
not rely upon it being present for administrative or auditing purposes.&lt;/p&gt;
&lt;p&gt;Add a similar note somewhere in the admin docs, probably a page about
volume metadata written by Cinder (which may not currently exist).
In addition to reminding admins that end users can overwrite volume
metadata, should explain how to read the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;src_backup_id&lt;/span&gt;&lt;/code&gt; (particularly
the part about what id is used when restoring from incremental backups).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Fri, 31 Jan 2020 00:00:00 </pubDate></item><item><title>Support to query cinder resources filter by time comparison operators</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/ussuri/query-cinder-resources-filter-by-time-comparison-operators.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/support-to-query-cinder-resources-filter-by-time-comparison-operators"&gt;https://blueprints.launchpad.net/cinder/+spec/support-to-query-cinder-resources-filter-by-time-comparison-operators&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Support users can query resources by specifying the time comparison
operators along with created_at or updated_at, and cinder will return all
which matches the time condition.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Cinder (also other projects, like heat and neutron) API only support filtering
resources by discrete values, even though cinder resources have timestamp
fields, users can only query resources operated at given time,
not during given period. Users may be interested in resources operated in a
specific period for monitoring or statistics purpose but currently they have to
retrieve and filter the resources by themselves.
This change can bring facility to users and also improve the efficiency of
timestamp based query.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;In large scale environment, lots of resources were created in system,
for tracing the change of resource, user or manage system only need to get
those resources which was creatded or changed from some time point, instead of
querying all resources every time to see which was changed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Introduce six time comparison operators along with created_at or updated_at
fields for retrieving resources more flexible. User needs to specify the
operator first, a colon (:) as a separator, and then the time.
One step closer, we will also support multi-operators querying at once, a
comma (,) as the separator.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Operator ‘gt’: Return results more recent than the specified time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Operator ‘gte’: Return any results matching the specified time and also any
more recent results.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Operator ‘eq’: Return any results matching the specified time exactly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Operator ‘neq’: Return any results that do not match the specified time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Operator ‘lt’: Return results older than the specified time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Operator ‘lte’: Return any results matching the specified time and also
any older results.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;As discussed in ‘Problem description’ section, user can retrieve and then
filter resources by themselves, but this approach is neither convenient nor
efficient. Leaving filtering work to database can utilize the optimization
of database engine and also reduce data transmitted from server to client.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;List API will accept new query string parameters. User can pass the operator
and time to the list API url to retrieve resources created or updated since or
prior to a specific time.
This changes also need to bump the microversion of API to keep forward
compatibility.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;GET /v3/{project_id}/volumes/{detail}?updated_at=gt:2016-01-01T01:00:00,lt:2016-12-01T01:00:00&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;Python client may add help to inform users this new filter. Python client
support dynamic assigning search fields so it is easy for it to
support this new filter.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;As discussed in ‘Alternatives’ section, performance can be improved for
timestamp based query by utilizing database engine. Additional, it also can add
index to improve querying performance.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;wanghao&amp;lt;&lt;a class="reference external" href="mailto:sxmatch1986%40gmail.com"&gt;sxmatch1986&lt;span&gt;@&lt;/span&gt;gmail&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add API filter&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add querying support in sql&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add related test&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Unit test to test if those filters can be correctly applied.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tempest test if change filter work correctly from API perspective.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;The cinder API documentation will need to be updated to reflect the REST
API changes.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;[1]: &lt;a class="reference external" href="https://developer.openstack.org/api-ref/image/v2/?expanded=list-images-detail#v2-comparison-ops"&gt;https://developer.openstack.org/api-ref/image/v2/?expanded=list-images-detail#v2-comparison-ops&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Mon, 13 Jan 2020 00:00:00 </pubDate></item><item><title>Support Glance multiple stores</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/ussuri/support-glance-multiple-backend.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/support-glance-multiple-backend"&gt;https://blueprints.launchpad.net/cinder/+spec/support-glance-multiple-backend&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This blueprint proposed to support Glance multiple stores.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;In Rocky and Stein, Glance has added the ability to configure multiple stores
as an EXPERIMENTAL feature &lt;a class="footnote-reference brackets" href="#id4" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. This feature is on schedule to be fully
supported in the Train cycle. This way an operator can configure more than one
of similar or different kind of stores and use one as a default store. If a
store is not specified at the time of uploading an image then the image will be
stored in default store.&lt;/p&gt;
&lt;p&gt;In case of Cinder upload-volume-to-image, if no changes are made to Cinder,
even if multiple stores are configured, the volume image will always be
uploaded to the default store. This does not cause any issues, but does not
allow an operator to take advantage of Glance multiple stores.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;An operator is offering multiple Glance image stores distinguished by some
desirability metric (as explained to end users in each store’s description)
and wants a user to have the option to select which of these stores will be
used to store an image created from a Cinder volume.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Define a field named ‘image_service:store_id’ in the volume-type extra-specs.
Using ‘image_service’ as the namespace for the ‘store_id’ key signals to the
scheduler that this field should be ignored when scheduling a volume build.&lt;/p&gt;
&lt;p&gt;The value is the store ‘id’ as indicated in the Image Service API v2 stores
discovery response:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;GET $IMAGE_API_URL/v2/info/stores

{
    "stores": [
        {
            "id":"reliable",
            "description": "Has a good transfer speed/price ratio"
        },
        {
            "id":"fast",
            "description": "Fast store with short transfer time",
            "default": true
        },
        {
            "id":"cheap",
            "description": "Inexpensive store for seldom used images"
        }
    ]
}
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;There was discussion at the Train Forum and PTG concerning the validation of
extra_specs &lt;a class="footnote-reference brackets" href="#id5" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, so the question arises of how that would impact the proposed
usage of extra_specs for the Glance store information.  If the validation
implementation follows the Kilo spec &lt;a class="footnote-reference brackets" href="#id6" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, validation will happen in the REST
API.  The validation code could filter out the ‘image_service:store_id’ field
before validating the other fields with the appropriate Cinder backend driver.
Additionally, the code could validate the ‘image_service:store_id’ setting by
making the Image Service API stores-info call and verfiying that value occurs
as an element of the list given by the JSONPath &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;$.stores[*].id&lt;/span&gt;&lt;/code&gt; in the
response.  (This would be &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;["reliable",&lt;/span&gt; &lt;span class="pre"&gt;"fast",&lt;/span&gt; &lt;span class="pre"&gt;"cheap"]&lt;/span&gt;&lt;/code&gt; in the example
above.)&lt;/p&gt;
&lt;p&gt;An objection to this proposal is that the Glance store should be associated
directly with the image-type, and not hidden in with the extra-specs.
Consider, however, how this would look to end users.  If the new field is made
part of the volume_type, it would be handled like the ‘qos_specs_id’, and the
type-show response would look something like this:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"volume_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"A new type"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"extra_specs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"9f319ace-a53c-40cb-8171-f12c4547baaf"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"is_public"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"a_new_type"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"os-volume-type-access:is_public"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"qos_specs_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"image_service:store_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;A null value here means that the default Glance image store will be used, but
this is confusing to end users because a natural interpretation of the null
value is that this volume_type does not allow images to be uploaded to Glance.
If we use the extra_specs, however, a volume type using the default Glance
image store would look like:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"volume_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Volume type using Glance default store"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"extra_specs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"volume_backend_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"lvmdriver-1"&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"686cc9f0-f4ca-4a5a-b113-eeb57d3977fd"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"is_public"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"lvmdriver-1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"os-volume-type-access:is_public"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"qos_specs_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Which is exactly the same as we have currently, while a volume type that
wants to specify a store would look like this:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"volume_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Volume type specifying a Glance store"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"extra_specs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"volume_backend_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"lvmdriver-1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"image_service:store_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"cheap"&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"686cc9f0-f4ca-4a5a-b113-eeb57d3977fd"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"is_public"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"lvmdriver-1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"os-volume-type-access:is_public"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"qos_specs_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Which, as you’d expect, only brings the Glance store ID to your attention if
something different than the usual case is being specified.&lt;/p&gt;
&lt;p&gt;Additionally, this proposal would require no changes to the Cinder data
model or the REST API, though these considerations are secondary to the
usability implications discussed above.&lt;/p&gt;
&lt;section id="vendor-specific-changes"&gt;
&lt;h3&gt;Vendor-specific changes&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Make the ‘image_service:store_id’ a property of the volume_type instead of
an extra_specs field.  While this would respect the intention of extra_specs
describing properties of the Cinder backend, it has the usability issues
mentioned in the &lt;a class="reference internal" href="#proposed-change"&gt;Proposed change&lt;/a&gt; section and would require a new API
microversion and a database change.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a new Cinder configuration option ‘store’ under the ‘glance’ section to
upload all the volume images to a specific glance store. If this option is
not present then all the volume images will be uploaded to default glance
store. This solution will be efficient if operator doesn’t want to expose the
use of uploading volume image to specific store to end user. This will be a
very simple change and doesn’t require any Block Storage API change or change
in python-cinderclient.&lt;/p&gt;
&lt;p&gt;This alternative has the downside that all images of Cinder volumes must be
stored in the same store.  If an operator has taken the trouble to configure
multiple stores in Glance, presumably there is end-user demand to use
different stores for different purposes, and presumably such an operator will
want block storage users to be able to take advantage of the Glance multiple
stores feature.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a new microversion to the volume-upload-to-image API to support uploading
a volume image to a specific glance store of an end user’s choice.  This
could be done by adding a new input request parameter ‘store’ to the
volume-upload-to-image API.  If the ‘store’ option is not specified in a
request then the image will be uploaded to the default store.  This has the
advantage that an end user will be able to choose any of the available Glance
stores.&lt;/p&gt;
&lt;p&gt;This alternative has the disadvantage that the end user will have to make the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;GET&lt;/span&gt; &lt;span class="pre"&gt;/v2/info/stores&lt;/span&gt;&lt;/code&gt; call to the Image API to discover the store
identifiers in use in a particular cloud.  It also has the disadvantage that
it works differently from Cinder’s support of multiple back ends, where the
backend a volume is stored in is determined by the volume type.  It would be
better to use a workflow more familiar to Cinder users.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None.  User experience will be consistent with current practice, where an end
user selects a volume type based on specific features exposed by the cloud
operator.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;abhishek-kekane&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;brian-rosmaita&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add ‘image_service:store_id’ handling to the Cinder create-image-from-volume
workflow&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add related tests&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add related unittest&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add related functional test&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add tempest tests&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Operators documentation should be updated according to spec implementation.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id4" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://docs.openstack.org/glance/rocky/admin/multistores.html"&gt;https://docs.openstack.org/glance/rocky/admin/multistores.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id5" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://etherpad.openstack.org/p/denver-forum-cinder-improving-drvr-cap-rep"&gt;https://etherpad.openstack.org/p/denver-forum-cinder-improving-drvr-cap-rep&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id6" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id3"&gt;3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.opendev.org/#/c/131280/"&gt;https://review.opendev.org/#/c/131280/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Mon, 13 Jan 2020 00:00:00 </pubDate></item><item><title>Datera Driver</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/juno/datera-driver.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/datera-driver"&gt;https://blueprints.launchpad.net/cinder/+spec/datera-driver&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Datera storage driver in Cinder.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Integration for Datera storage is not available in OpenStack.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Add a Cinder driver that can allow OpenStack services communicate with Datera
storage for both vHost and ISCSI.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;n/a&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;n/a&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;n/a&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;n/a&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;n/a&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;n/a&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;n/a&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;The deployer needs to set the cinder.conf to the right &lt;cite&gt;volume_driver&lt;/cite&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;volume_driver=cinder.volume.drivers.datera.DateraDriver&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;ISCSI would require setting up &lt;cite&gt;san_ip&lt;/cite&gt;, &lt;cite&gt;san_login&lt;/cite&gt; and &lt;cite&gt;san_password&lt;/cite&gt;
appropriately.&lt;/p&gt;
&lt;p&gt;vHost would have dependencies on using Linux-IO with the vHost fabric module.
The target_helper in the cinder.conf needs to be set to lio_vhost.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;n/a&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;thingee&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Write driver with ISCSI support.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Write unit tests for ISCSI support.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Provide cert tests with ISCSI support.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Write driver with vhost support.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Write unit tests for vhost support.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Provide cert tests with vhost support.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Provide CI with ISCSI and/or vhost support.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Need vHost connector [1].&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CI testing&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;n/a&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;[1] - &lt;a class="reference external" href="https://review.opendev.org/#/c/103048/"&gt;https://review.opendev.org/#/c/103048/&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Fri, 27 Dec 2019 00:00:00 </pubDate></item><item><title>Support clone_image from Glance cinder backend</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/liberty/clone-image-in-glance-cinder-backend.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/clone-image-in-glance-cinder-backend"&gt;https://blueprints.launchpad.net/cinder/+spec/clone-image-in-glance-cinder-backend&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;When Glance cinder store is enabled, the glance image can store locations of
cinder volume. When a raw image is cinder volume backed, we can efficiently
create a new volume from the image by cloning the backing volume, instead of
downloading the image from Glance. We can also make upload-to-image from a
volume efficient by creating a cloned volume and add its location to an image.&lt;/p&gt;
&lt;p&gt;Note that downloading the cinder-backed image from Glance is not currently
supported, but this feature is proposed. &lt;a class="footnote-reference brackets" href="#id4" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Creating a new volume from an image, and uploading a volume to an image take
long time due to image transfer.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sharing volume data among tenant is not currently supported in Cinder.
To share the volume data, we need to upload it to Glance once.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Share volume templates (e.g. operating system volumes) among tenants via
cinder volume backed images.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Each projects can create new instances via the image rapidly. If storage
array supports thin-provisioning, the disk space could also be efficient.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;When the allowed_direct_url_schemes in cinder.conf contain ‘cinder’,
on creating a volume from an image:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;Check if the image metadata satisfy the following conditions:&lt;/dt&gt;&lt;dd&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The image format is raw.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The image has locations in the format of ‘cinder://&amp;lt;volume-id&amp;gt;’&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Any of the specified volume is on the same host as a new volume.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The image owner and the volume owner is the same (to avoid accessing
volumes not shared by the image owner).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If all the conditions are met, clone the specified volume.
When the requested size is larger than the image, extend the new volume.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Otherwise, download the image to a new volume.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;On uploading a volume to an image:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;If image format is raw and image_upload_use_cinder_backend is enabled in
cinder.conf, clone the volume and register its location to the image &lt;a class="footnote-reference brackets" href="#id5" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;If image_upload_use_internal_tenant is set to True, the cloned volume is
placed in the internal tenant.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Otherwise, upload the volume data to Glance.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Generic image cache has the same effect in some situations. However, the
proposed feature and generic image cache can co-exist to cover the different
situations.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Image cache does not speed up uploading, but this feature make it efficient.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;image cache can handle non-raw format images (it stores the converted image
in image volumes), but this proposed feature doesn’t handle it so far.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;When the cloned volume is stored in the internal tenant, it could potentially
be a risk if someone was able to get a hold of its credentials or access the
image-volumes. Care will have to be taken to ensure it isn’t accessible by
normal users.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;This improves the performance of uploading and download of the image,
especially storage array can provide efficient volume cloning.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;Some configuration options need to be set to enable this feature.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;glance_api_version = 2&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;allowed_direct_url_schemes must contain ‘cinder’&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;image_upload_use_cinder_backend = True (new)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;image_upload_use_internal_tenant = True / False (new)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In Glance, cinder backend must be enabled and show_multiple_locations must be
set to True.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;tsekiyama&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;None&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Efficient download from cinder volume backed image&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Efficient upload to image&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;p&gt;To enabling the other components to download the cinder volume backed images,
Glance should have the changes &lt;a class="footnote-reference brackets" href="#id4" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit tests for download from cinder backed image&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unit tests for upload to image&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Documentation about how to enable this feature should be added.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id4" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id3"&gt;2&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;Proposal for Glance to support download from/upload to Cinder backend&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;glance-specs: &lt;a class="reference external" href="https://review.opendev.org/#/c/183363"&gt;https://review.opendev.org/#/c/183363&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;glance patch(adding rootwrap): &lt;a class="reference external" href="https://review.opendev.org/"&gt;https://review.opendev.org/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;glance_store patch: &lt;a class="reference external" href="https://review.opendev.org/#/c/166414"&gt;https://review.opendev.org/#/c/166414&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id5" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;Proposed change for Cinder&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.opendev.org/#/c/201754/"&gt;https://review.opendev.org/#/c/201754/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Fri, 27 Dec 2019 00:00:00 </pubDate></item><item><title>Copy volume to image in multiple stores of glance</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/ussuri/copy-image-in-multiple-stores.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/copy-image-in-multiple-stores"&gt;https://blueprints.launchpad.net/cinder/+spec/copy-image-in-multiple-stores&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This specs propose to send base image reference to glance on volume
upload to image API.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;In Train, Glance has added the ability to configure multiple stores
&lt;a class="footnote-reference brackets" href="#id6" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. This way an operator can configure more than one of similar or
different kind of stores and use one as a default store. If a store
is not specified at the time of uploading an image then the image
will be stored in default store.&lt;/p&gt;
&lt;p&gt;In Train, I have proposed a spec &lt;a class="footnote-reference brackets" href="#id7" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; where cinder can specify the glance
store via the volume-type. The store specified in volume-type will be
passed to glance using &lt;cite&gt;x-image-meta-store&lt;/cite&gt; header. Even operator
specifies the glance store identifier in volume-type it will only allow
volume image to be uploaded to single specified store and does not allow
for co-location of the image. Also, it depends on the operator configuring
the volume-type extra-specs to define a preferred Glance store; if the
operator doesn’t take this step, all uploads go to the default Glance store.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;At the moment, if cloud provider decided to upgrade their cloud to Train
release to use the ability of glance of configuring multiple store and the
base image from which volume is created resides in multiple stores
of glance, then if the operator has not defined a glance store in the
volume-type extra specs, the image created from volume will always
be uploaded to default store and there is no way to replicate/copy these
image bits to all the stores where base image is uploaded. As a result,
operators today need to perform a number of manual steps in order
to replicate/copy image bits on glance stores despite using the
‘enabled_backends’ configuration option. For this purpose, he/she need
to manually copy the newly created image from volume in all stores and
register these others locations URL with the image using the glance API.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;When a volume is created from an image, Cinder currently stores the
image_uuid in the volume_image_metadata. When Cinder upload volume to
image is requested cinder should pass the ‘image_uuid’ as a header
‘x-openstack-base-image-ref’ to glance, so that glance can identify the
store(s) in which the original image is located. Cinder is also storing
this glance store information in volume types &lt;a class="footnote-reference brackets" href="#id7" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, where the store
identifier associated with volume-type will be passed as a header
‘x-image-meta-store’ to glance to upload the image created from volume to
that specific store.&lt;/p&gt;
&lt;p&gt;If a volume is created from an image and Cinder passes both the
‘x-image-meta-store’ and ‘x-openstack-base-image-ref’ headers, Glance will
ignore the ‘x-openstack-base-image-ref’ header and will use the store_id
specified in the ‘x-image-meta-store’ header.&lt;/p&gt;
&lt;p&gt;If volume is not bootable and store information is available in
volume type then glance will use store associated with volume type to upload
the image created from volume.&lt;/p&gt;
&lt;p&gt;If volume is not bootable and store information is not available in
volume type then glance will use ‘default store’ to upload the image
created from volume.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Continue with passing store information using volume types &lt;a class="footnote-reference brackets" href="#id7" id="id4" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="active-active-ha-impact"&gt;
&lt;h3&gt;Active/Active HA impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;whoami-rajat&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;abhishek-kekane&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Pass image uuid stored in ‘volume_image_metadata’ as header to glance&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add related tests&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Depends on implementation of ‘Support Glance multiple stores’ &lt;a class="footnote-reference brackets" href="#id7" id="id5" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add related unittest&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add related functional test&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add tempest tests&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Operators documentation should be updated according to spec implementation.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id6" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://docs.openstack.org/glance/rocky/admin/multistores.html"&gt;https://docs.openstack.org/glance/rocky/admin/multistores.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id7" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id2"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id3"&gt;2&lt;/a&gt;,&lt;a role="doc-backlink" href="#id4"&gt;3&lt;/a&gt;,&lt;a role="doc-backlink" href="#id5"&gt;4&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://specs.openstack.org/openstack/cinder-specs/specs/train/support-glance-multiple-backend.html"&gt;http://specs.openstack.org/openstack/cinder-specs/specs/train/support-glance-multiple-backend.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Fri, 22 Nov 2019 00:00:00 </pubDate></item><item><title>Dynamic Reconfiguration after Modfications of cinder.conf</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/untargeted/dynamic_reconfiguration.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/dynamic-reconfiguration/"&gt;https://blueprints.launchpad.net/cinder/+spec/dynamic-reconfiguration/&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;As it stands, whenever changes are made to the Cinder configuration file all
cinder services need to be restarted in order to pick up the new
configuration setup. In a real world environment, a user does not want to
be dealing with services shutting down and spinning back up when some aspect
of configuration gets changed. In order to stay consistent with this,
constantly running services that can be dynamically updated as changes are
made provides a much more realistic view of how users interact with services.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Allows developers testing a new configuration option to change what the
option is set to and test without having to restart all the Cinder services.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Allows developers to test new functionality implemented in a driver by
enabling and disabling configuration options in cinder.conf without
restarting Cinder services each time the option value is changed from
‘disabled’ to ‘enabled’.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Allows admins to manage ip addresses for various backends in cinder.conf
and have the connections dynamically update.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;SIGHUP Approach: The administrator will send the SIGHUP signal to be caught by
the Cinder processes.  The processes would then be instrumented to catch the
signal, drain in progress actions and reload the configuration file. This will
also take care of re-initializing the drivers. It still requires the
administrator to take an additional manual step to send the SIGHUP after
changing the configuration file. This approach requires deployers to update
their sysinit scripts to support reloading the processes. Overall, this is a
cleaner approach because everything is shut down, the memory is cleaned up,
and then the sysinit scripts will take care of reloading the processes.&lt;/p&gt;
&lt;p&gt;Note: This is all done on a per host basis; in a multinode setup, the signal
will need to be sent to each node. Currently in Active/Active environments
this is a sizable issue that needs to be investigated.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Manual Approach: Continue to manually restart Cinder services when changes
are made to settings in the cinder.conf file. This is the current approach
and is what we are trying to get around.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reload &amp;amp; Restart Approach: First each process would need to finish the
actions that were ongoing. Next the db and RPC connections would need to
be dropped and then all caches and all driver caches would need to be
flushed before reloading. This approach adds a lot of complexity and lots of
possibilities for failure since each cache has to be flushed- things could
get missed or not flushed properly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;File Watcher: Code will be added to the cinder processes to watch for
changes to the cinder.conf file. Once the processes see that changes have
been made, the process will drain and take the necessary actions to
reconfigure itself and then auto-restart. This capability could also be
controlled by a configuration option so that if the user didn’t want dynamic
reconfiguration enabled, they could just disable it in the cinder.conf file.
This approach is dangerous because it wouldn’t account for configuration
options that are saved into variables. To fix these cases, there would be a
sizeable impact for developers finding and replacing all instances of
configuration variables and in doing so a number of assumptions of
deployment, configuration, tools, and packaging would be broken.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;In order to edit the cinder.conf file, the user must have root authority.
So, there is not an additional security impact.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;There would need to be notifications of when the reload starts and ends.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;Update sysinit scripts to support the new ‘cinder-&amp;lt;service&amp;gt; reload’
command.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Test functionality with vendor’s drivers to ensure correct behavior.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;kendall-nelson&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Secondary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;jacob-gregor&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Implement handling of SIGHUP signal
- Ensure caches are cleared
- Dependent vars are updated
- Connections are cleanly dropped&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Write Unit tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing on a variety of drivers&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update devref to describe SIGHUP/reload process&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;We will need to update documentation to describe the new capability.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;Weekly Meeting Logs[1]&lt;/p&gt;
&lt;p&gt;[1]http://eavesdrop.openstack.org/meetings/cinder/2016/cinder.2016-03-16-16.01.log.txt&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Wed, 28 Aug 2019 00:00:00 </pubDate></item><item><title>Generic backup implementation</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/untargeted/generic-backup-implementation.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/generic-backup-implementation"&gt;https://blueprints.launchpad.net/cinder/+spec/generic-backup-implementation&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Generic backup implementation will allow us to use any supported volumes
backend as backup storage. So we won’t need to implement specific backup driver
for supported backends.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;We’ve got different backup and volume drivers now. That’s why we have to
re-implement the part of volume driver as backup driver if we want to use
the same storage for backups.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Be able to use any cinder-supported storage backend for backups.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Implmement generic backup implementation in a base volume driver like we did
for volume migrations. After this vendors could easily implement
storage-assistant backups for their drivers.&lt;/p&gt;
&lt;p&gt;We will have base backup drivers class for storages like Swift, Google Cloud
Storage, etc which will implement only backup-related features.&lt;/p&gt;
&lt;p&gt;It will allow a volume backed up to storage A to be restored to a volume
on any storage B.&lt;/p&gt;
&lt;p&gt;Cinder should not allow to use the same storage both for volume and backups.
In such case, backup driver initialization should fail. If storage supports
different pools Cinder will allow to create backup on the same storage but in
the different pool.&lt;/p&gt;
&lt;p&gt;We don’t need to have ‘backup and volumes in the same storage’ feature in
Cinder even configurable because we can use snapshots or clone volume for it.
Backups should be in different storage or at least in another pool.&lt;/p&gt;
&lt;p&gt;As a generic implementation, cinder will use the same mechanism as generic
volume migraion:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;create volume on a destination storage&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;attach both source and destination volumes to a cinder node&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;use ‘dd’ tool to copy volume data&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;detach both volumes from a cinder node&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In case if volume is ‘in-use’ we’ll create temporary snapshot and do backup
from it.&lt;/p&gt;
&lt;p&gt;We can’t use ‘clone volume’ feature between different storages.&lt;/p&gt;
&lt;section id="vendor-specific-changes"&gt;
&lt;h3&gt;Vendor-specific changes&lt;/h3&gt;
&lt;p&gt;Vendors or drivers maintainers could implement vendor-specific backup
implementation to use storage API for faster backup process.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Follow the current approach with separate volumes and backups drivers.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Backups are likely to be faster to block backends than to swift. It means
backup to block storage could be faster than a backup to object storage.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;Operator should be able to configure backups storage and cinder backup driver.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Volume drivers could implement vendor-specific backup implementation&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Ivan Kolodyazhny &amp;lt;&lt;a class="reference external" href="mailto:e0ne%40e0ne.info"&gt;e0ne&lt;span&gt;@&lt;/span&gt;e0ne&lt;span&gt;.&lt;/span&gt;info&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Volume Driver maintainers&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;TDB&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tempest tests should be implemented in a new feature group&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Operators documentation should be updated according to spec implementation.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://eavesdrop.openstack.org/meetings/cinder/2016/cinder.2016-08-10-15.59.html"&gt;http://eavesdrop.openstack.org/meetings/cinder/2016/cinder.2016-08-10-15.59.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Wed, 28 Aug 2019 00:00:00 </pubDate></item><item><title>Volume Rekey</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/train/volume-rekey.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/volume-rekey"&gt;https://blueprints.launchpad.net/cinder/+spec/volume-rekey&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Cinder supports volume encryption with keys stored in Barbican.&lt;/p&gt;
&lt;p&gt;This spec tracks some improvements we can make in how we handle
encryption keys.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;When cloning volumes, cinder clones the encryption key as well,
so multiple volumes are unlockable with the same encryption key.&lt;/p&gt;
&lt;p&gt;We can make this encryption scheme more robust by changing the
encryption key upon volume clone, so that cloned volumes are not
unlockable with the key of the source volume.&lt;/p&gt;
&lt;p&gt;This is possible since we encrypt volumes using LUKS. Changing the
key does not require re-encrypting the volume.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;Security hardening for volume encryption.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;When a volume is cloned, attach it as part of the clone process,
and change the encryption key using LUKS tools.&lt;/p&gt;
&lt;p&gt;The rest of the clone process continues as normal afterward.&lt;/p&gt;
&lt;p&gt;My current implementation does this by calling a new
rekey_volume() method in the create_volume flow, which uses
“cryptsetup luksChangeKey”.  This should work for any iSCSI/FC
drivers, which already must perform a similar attachment when
creating a volume from an image.&lt;/p&gt;
&lt;p&gt;Some work (planned for after Train) is still needed to make this
work for RBD, because there does not seem to be a qemu-img tool
that can change encryption keys, and cryptsetup requires a local
block device.  This leaves us with two options for RBD:
a) use krbd mapping to get a block device
b) use rbd-nbd to get a block device&lt;/p&gt;
&lt;p&gt;NBD is not widely supported in relevant OSes, so krbd looks like
the choice there.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Volume encryption is better hardened against threats due to
compromise of a single encryption key.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="active-active-ha-impact"&gt;
&lt;h3&gt;Active/Active HA impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Slightly more time to clone encrypted volumes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;eharney&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Implement this for iSCSI/FC drivers&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Test with the LVM driver&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In a later release…
* Implement this for RBD
- Requires some additional effort
* Consider additional cases where this concept would be useful
- Volume transfer
- Backup restoration (?)&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Will be on by default and therefore tested by tempest tests
that clone encrypted volumes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Wed, 12 Jun 2019 00:00:00 </pubDate></item><item><title>Generalized filtered listing on resources</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/pike/generalized_list_filters.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/generalized-filtering-for-cinder-list-resource"&gt;https://blueprints.launchpad.net/cinder/+spec/generalized-filtering-for-cinder-list-resource&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;We continue adding various filter options to the Cinder List API’s.  Things
like “filter results by x=y”.  This results in a good deal of code being
added for one-off preferences or user convenience.  It also means that we
continue to bump micro-versions for such additions and create more versions
of the API than we probably care to document, test and maintain.&lt;/p&gt;
&lt;p&gt;What’s annoying about this is that it’s not even that we’re adding things
to the server side, we’re instead just popping things off of the params
in the request body based on what micro-version is specified.&lt;/p&gt;
&lt;p&gt;The biggest area of churn for this sort of thing is in the client side of
things.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;Filters are convenient for operators doing things with large clouds.  It’s
certainly a nice-to-have feature to be able to do things like just ask
Cinder for a list of all volumes with an &lt;cite&gt;error&lt;/cite&gt; status, or that are
&lt;cite&gt;bootable&lt;/cite&gt; or the latest, suggestion all those that are attached to host
xyz.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;In order to add these today, we add a specific arg to the clients, and then
we add specific arg parsing on the Cinder API server to interpret and parse
these args.  These parsed arguments are then just used to build a filter that
we pass in to the sql call to get_volumes (or get_&amp;lt;resource&amp;gt;).&lt;/p&gt;
&lt;p&gt;Rather than continuing to add these for the various resources in an ad-hoc
manner, this spec proposes a generalized filtered-list mechanism.  Rather
than add a specific filter by name over and over, instead provide a single
&lt;cite&gt;filter&lt;/cite&gt; argument that supplies Key Value pairs to be used to build the
db query filter.  There’s likely some concern that people won’t &lt;em&gt;know&lt;/em&gt; what
valid filter keys are, for that we can also provide a &lt;cite&gt;list-filters&lt;/cite&gt; command
that could be used in an introspective sort of way, querying the object model
for the valid filter items and returning it to the caller.&lt;/p&gt;
&lt;p&gt;The &lt;cite&gt;list-filters&lt;/cite&gt; component is derived from an Admin provided list of valid
and enabled filters for end users to access.  This obviously serves two
purposes:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Advertise what filters are enabled/available to the end user&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Gives the Cloud Operator the ability to pick what filters are enabled&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;It’s important to note that not all clouds will want to expose filters like
backend-host and other internals that shouldn’t typically be leaked to the
end user.&lt;/p&gt;
&lt;p&gt;What’s interesting about this is from the API Servers perspective we don’t
even really care about any of this.  We can already pass in filters via
the params in the request body and this just works.  If you’re using curl
this just works already as is.  If you are using the client you’d just need
a way to expose it properly:
(&lt;a class="reference external" href="https://gist.github.com/j-griffith/f455e51d3e597af96bfe7022974b5bd9"&gt;https://gist.github.com/j-griffith/f455e51d3e597af96bfe7022974b5bd9&lt;/a&gt;)&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;We could certainly continue doing what we’re doing now and just adding
specific filter arguments to the clients and the API, but I don’t think
that’s sustainable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We could provide a generalized “filters” (pick a better name) controller
that could be called directly and then call the specified resource item
with filters.  This would mean you would do things like:
&lt;cite&gt;cinder list-filters –resource volume&lt;/cite&gt;  to get a list of valid filter
items for a volume (volumes should be the default).&lt;/p&gt;
&lt;p&gt;&lt;cite&gt;cinder list-filters –resource snapshot&lt;/cite&gt; for snapshots, etc.&lt;/p&gt;
&lt;p&gt;But then have something like a &lt;cite&gt;cinder [&amp;lt;resource&amp;gt;-]list –filters xyz=abc&lt;/cite&gt;
which would go to a resource list controller and then call the resource
controller appropriately.&lt;/p&gt;
&lt;p&gt;This might be a good way to reduce some duplicate code and churn even further
but it may require just as much work and code as just having each resource
have it’s own “–filters” options to the list commands.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;Other than adding the ability to view the valid filter keys we don’t
even need to change anything on the Cinder server side currently.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None that I’m aware of&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;Life would be better&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Life would be better&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;john-griffith&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add the filters arg to the client&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the ability to query the API server
for valid filters for a resource&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;We will need to update documentation to describe the new capability,
although I expect anybody not using the client may already be exposing
this on their own.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;/section&gt;
</description><pubDate>Thu, 23 May 2019 00:00:00 </pubDate></item><item><title>Leverage compression accelerator</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/train/leverage-compression-accelerator.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/leverage-compression-accelerator"&gt;https://blueprints.launchpad.net/cinder/+spec/leverage-compression-accelerator&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This blueprint proposes to leverage hardware compression accelerator to
accelerate the image compression when uploading volume to glance as image.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;When trying to upload volume to glance as image, currently all the format
transformation is done by software and the performance is not good.&lt;/p&gt;
&lt;p&gt;For example, when uploading a volume of size 30GB with 12GB data resides,
select qcow2 as the target image format, currently the tool used to do the
transformation is qemu-img. This has below problems:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Low compression rate
After transforming, the output size is 12GB.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;High CPU consuming
During the transforming, CPU usage is about 100%-170% (~ two cores).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Long duration
The time to transform the volume is about 23 seconds.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;As a contrast, if using hardware accelerator to do the format transformation,
choose ‘gzip’ as the target format, the performance is much better. Take Intel
QAT as the accelerator for example, performance data would be:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Compression rate
After transforming, the output size is 2.3GB.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CPU consuming
During the transforming, CPU usage is about 97% (one core).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Duration
The time to transform the volume is about 9 seconds.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;So the compressed size is only a quarter of its original size, but takes less
than half the time.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;User wants to upload volume to glance as a compressed image&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Add a new container format ‘compressed’&lt;/p&gt;
&lt;p&gt;Cinder don’t have an enum to control container format list, rather than disk
format. But cinder will have specific steps for the ‘compressed’ container
format. Refer to below changes.&lt;/p&gt;
&lt;p&gt;The disk format remains unchanged by this spec, it can be any type in enum in
cinder.api.schemas.volume_actions.volume_upload_image.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add an option to enable/disable the image compression support&lt;/p&gt;
&lt;p&gt;If there’s no hardware accelerator exists, then it will fallback to software
solution to do the compression. But this will consume CPU resource. So this
spec will add an option to control if the compression feature be enabled or
not.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add compression tool of famous hardware accelerators into file volume.filters&lt;/p&gt;
&lt;p&gt;The compression tool such as ‘qzip’ will be added in volume.filters so that
it can be run by root wrapper&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Show ‘compressed’ in the container format list when selecting a volume to
upload&lt;/p&gt;
&lt;p&gt;This need to be done in cinder client and horizon.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Check if there are some hardware accelerators exist in the system&lt;/p&gt;
&lt;p&gt;Go through the accelerator tool list to find if any hardware accelerator
exist. If none exist, failover to software solution if compressed format
is selected.&lt;/p&gt;
&lt;p&gt;This will be done in ./cinder/image/accelerator.py, and at last, will call
the driver of accelerator to check the existence.&lt;/p&gt;
&lt;p&gt;Refer to:
&lt;a class="reference external" href="https://review.opendev.org/#/c/668825/1/cinder/image/accelerator.py"&gt;https://review.opendev.org/#/c/668825/1/cinder/image/accelerator.py&lt;/a&gt;
Function: is_engine_ready
&lt;a class="reference external" href="https://review.opendev.org/#/c/668825/1/cinder/image/accelerators/qat.py"&gt;https://review.opendev.org/#/c/668825/1/cinder/image/accelerators/qat.py&lt;/a&gt;
Function: is_accel_exist&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Do image compression after convert_image but before uploading to glance&lt;/p&gt;
&lt;p&gt;Call the existing accelerator’s tool to do the compression. e.g. if Intel QAT
device is identified, then call qzip here to do the compression. If no
accelerator identified, then fallback to software solution, using the tool
gzip to do the decomression.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Do image decompression after downloading from glance but before convert_image&lt;/p&gt;
&lt;p&gt;When creating volume from image, call hardware accelerator to do the
decompression. If hw accelerator doesn’t exist, then fallback to software
solution, using the tool gzip to do the decomression&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Another way is to use the improved processor with software solution only, such
as gzip. But the cost would be high vs dedicated hardware accelerator, and have
no performance benefit.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;Add the image type of “compressed” when uploading volume to image&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Less CPU comsuming if hardware accelerator available&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Less conversion time if hardware accelerator available&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Smaller image size&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Need to install the driver and utility tool of the accelerator&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Can configurate the option to enable/disable compression capability&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Developers that want to add support for other accelerators need to add
their tool to root wrap&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Liang Fang &amp;lt;&lt;a class="reference external" href="mailto:liang.a.fang%40intel.com"&gt;liang&lt;span&gt;.&lt;/span&gt;a&lt;span&gt;.&lt;/span&gt;fang&lt;span&gt;@&lt;/span&gt;intel&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;During image conversion, switch to hardware accelerator if possible&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement a common framework for hw leverage in image conversion&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement a typical hw accelerator in image conversion&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unit test be added&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit-tests, tempest and other related tests will be implemented.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Test case in particular: when creating a volume from an image with
container_format == ‘compressed’, but the image contains some format other than
what Cinder supports. The expected behavior is to fail gracefully.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Documentation will be needed. User documentation on how to use accelerator
and developer documentation on how to add an additional accelerator&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;&lt;span class="target" id="id1"&gt;[1]&lt;/span&gt; &lt;a class="reference external" href="https://review.opendev.org/#/c/668825/"&gt;https://review.opendev.org/#/c/668825/&lt;/a&gt;
&lt;span class="target" id="id2"&gt;[2]&lt;/span&gt; &lt;a class="reference external" href="https://review.opendev.org/#/c/668943/"&gt;https://review.opendev.org/#/c/668943/&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Sun, 14 Apr 2019 00:00:00 </pubDate></item><item><title>Untyped volumes to default volume type</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/train/untyped-volumes-to-default-volume-type.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/untyped-volumes-default-volume-type"&gt;https://blueprints.launchpad.net/cinder/+spec/untyped-volumes-default-volume-type&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This blueprint proposes to use a default volume type instead of allowing users
to create untyped volumes.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently a user is able to create a volume without any volume type, since
a volume’s characteristics are defined by a volume type, creating untyped
volumes shouldn’t be allowed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;Most users use volume types, and our code is simpler and less buggy if we
just always attach volume types to volumes, so we should just force all
deployments to use volume types.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;This spec proposes the following changes :&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create a default volume type during cinder database migration or on cinder
services start time. The default volume type will have no extra specs
assigned to it and will be named &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;__DEFAULT__&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If a volume type named &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;__DEFAULT__&lt;/span&gt;&lt;/code&gt; already exists, the deployer
needs to rename or remove it before upgrading&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add an online migration to convert all untyped volumes and snapshots to
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;__DEFAULT__&lt;/span&gt;&lt;/code&gt; volume type&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set a default value &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;__DEFAULT__&lt;/span&gt;&lt;/code&gt; for &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;default_volume_type&lt;/span&gt;&lt;/code&gt; config
option so the default value is picked when it is unset in cinder.conf&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Don’t allow deletion of the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;__DEFAULT__&lt;/span&gt;&lt;/code&gt; volume type via type-delete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Updating of volume type (&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;__DEFAULT__&lt;/span&gt;&lt;/code&gt;) will be handled by MANAGE_POLICY
which defaults to admin-only&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Mandate specifying volume type while creating volumes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Do this as a behind-the-scenes DB migration rather than relying on manual
intervention with upgrade checkers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Do this as a best-effort-if-it’s-safe operation in the volume manager,
which would migrate most deployments, and skip those that are ruled out for whatever reason.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;All volumes created without specifying the volume-type parameter
will be associated with the default volume type.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Untyped Volumes and Snapshots will be assigned &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;__DEFAULT__&lt;/span&gt;&lt;/code&gt;
volume type&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Users will no longer be able to create a volume with None volume type.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Rajat Dhasmana &amp;lt;&lt;a class="reference external" href="mailto:rajatdhasmana%40gmail.com"&gt;rajatdhasmana&lt;span&gt;@&lt;/span&gt;gmail&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Eric Harney &amp;lt;&lt;a class="reference external" href="mailto:eharney%40redhat.com"&gt;eharney&lt;span&gt;@&lt;/span&gt;redhat&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;By restricting untyped volumes, we need to do the following changes:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add an upgrade check to verify that current deployment doesn’t contain
any volume type named &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;__DEFAULT__&lt;/span&gt;&lt;/code&gt; else the upgrade will fail&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;__DEFAULT__&lt;/span&gt;&lt;/code&gt; volume type at the time of cinder db migration or
service start time&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add upgrade check to verify no type named &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;__DEFAULT__&lt;/span&gt;&lt;/code&gt; exists before
upgrading&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add an online migration to convert all untyped volumes and snapshots to
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;__DEFAULT__&lt;/span&gt;&lt;/code&gt; volume type&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Related code changes to associate default_volume_type to volumes if no
volume type is specified by user&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit-tests, tempest and other related tests will be implemented.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Need to update volume type related docs.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Wed, 10 Apr 2019 00:00:00 </pubDate></item><item><title>Add project_id attribute to group and group snapshot response</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/stein/add-project-id-to-group-and-group-snapshot-response.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/add-project-id-to-group-groupsnapshot-response"&gt;https://blueprints.launchpad.net/cinder/+spec/add-project-id-to-group-groupsnapshot-response&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This blueprint proposes to add &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;project_id&lt;/span&gt;&lt;/code&gt; attribute to the response
body of list groups with detail, list group snapshots with detail,
show group detail and show group snapshot detail APIs.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Currently, the group and group snapshot show response doesn’t include
project_id.
It is an important parameter while differentiating between multiple groups
and multiple group snapshots in horizon.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;As horizon is adding tabs for groups and group snapshots listing
with detail in the admin panel[1], it requires project_id as a
response parameter from the groups and group snapshots API.
It is similar to what is implemented in volumes and snapshots list.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;This spec proposes to add &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;project_id&lt;/span&gt;&lt;/code&gt; attribute to the response
body of list groups with detail, list group snapshots with detail,
show group detail and show group snapshot detail APIs.&lt;/p&gt;
&lt;p&gt;Add a new microverion API to add &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;project_id&lt;/span&gt;&lt;/code&gt; attribute to the
response body of list groups with detail, list group snapshots with
detail, show group detail and show group snapshot detail APIs:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;List groups with detail GET /v3/{project_id}/groups/detail&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;List group snapshots with detail GET /v3/{project_id}/group_snapshots/detail&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Show group detail GET /v3/{project_id}/groups/{group_id}&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Show group snapshot detail GET /v3/{project_id}/group_snapshots/{group_snapshot_id}&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;Add a new microversion in Cinder API.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;List groups with detail:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v3&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;groups&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;detail&lt;/span&gt;
&lt;span class="n"&gt;Response&lt;/span&gt; &lt;span class="n"&gt;BODY&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"groups"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
        &lt;span class="o"&gt;...&lt;/span&gt;
        &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"7ccf4863071f44aeb8f141f65780c51b"&lt;/span&gt;
    &lt;span class="p"&gt;}]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;List group snapshots with detail:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v3&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;group_snapshots&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;detail&lt;/span&gt;
&lt;span class="n"&gt;Response&lt;/span&gt; &lt;span class="n"&gt;BODY&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"group_snapshots"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
        &lt;span class="o"&gt;...&lt;/span&gt;
        &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"7ccf4863071f44aeb8f141f65780c51b"&lt;/span&gt;
    &lt;span class="p"&gt;}]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Show group detail:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v3&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;groups&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;group_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;Response&lt;/span&gt; &lt;span class="n"&gt;BODY&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"group"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
        &lt;span class="o"&gt;...&lt;/span&gt;
        &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"7ccf4863071f44aeb8f141f65780c51b"&lt;/span&gt;
    &lt;span class="p"&gt;}]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Show group snapshot detail:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v3&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;group_snapshots&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;group_snapshot_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;Response&lt;/span&gt; &lt;span class="n"&gt;BODY&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"group_snapshot"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
        &lt;span class="o"&gt;...&lt;/span&gt;
        &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"7ccf4863071f44aeb8f141f65780c51b"&lt;/span&gt;
    &lt;span class="p"&gt;}]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Calling this method shows &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;project_id&lt;/span&gt;&lt;/code&gt; for a group or group snapshot.
It is intended for admins to use, which is used to display the project_id to which
the group or group snapshot belongs, and controlled by &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;GROUP_ATTRIBUTES_POLICY&lt;/span&gt;&lt;/code&gt;
or &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;GROUP_SNAPSHOT_ATTRIBUTES_POLICY&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Rajat Dhasmana &amp;lt;&lt;a class="reference external" href="mailto:rajatdhasmana%40gmail.com"&gt;rajatdhasmana&lt;span&gt;@&lt;/span&gt;gmail&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add a new microversion.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;project_id&lt;/span&gt;&lt;/code&gt; to the response body of list groups with detail,
list group snapshots with detail, show group detail and show group
snapshot detail APIs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the related unit tests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update related list groups with detail, list group snapshots with
detail, show group detail and show group snapshot detail api doc.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit-tests and other related test should be implemented&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;[1] &lt;a class="reference external" href="https://blueprints.launchpad.net/horizon/+spec/cinder-generic-volume-groups"&gt;https://blueprints.launchpad.net/horizon/+spec/cinder-generic-volume-groups&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 21 Feb 2019 00:00:00 </pubDate></item><item><title>Enable multiattach of volumes</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/queens/enable-multiattach.html</link><description>

&lt;p&gt;Include the URL of your launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/multi-attach-v3-attach"&gt;https://blueprints.launchpad.net/cinder/+spec/multi-attach-v3-attach&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The ability to attach a volume to multiple hosts/servers simultaneously
is a use case that has been asked for over the years.  The implementation
of the Attach workflow in Cinder however made this somewhat difficult and
less than robust.&lt;/p&gt;
&lt;p&gt;With the new Cinder Attachment API’s &lt;a class="footnote-reference brackets" href="#id2" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; this is
a bit easier because Attachments are treated as independent objects.&lt;/p&gt;
&lt;p&gt;This spec proposes a set of changes to enable and control the use of
multiattach volumes from the Cinder side.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently we refuse to attach a volume that is already attached (in-use).
There are situations where a cloud user may have deployed a clustered
file-system on a Cinder volume and they would like the ability to attach
a volume to multiple hosts/servers at the same time.&lt;/p&gt;
&lt;p&gt;Note that Cinder is not providing any sort of Filesystem checks or sharing
overlays on the volume, it’s completely up to the user to handle this and
determine if they can in fact attach a volume to multiple locations without
incurring filesystem/data corruption.&lt;/p&gt;
&lt;p&gt;The problem that we are proposing to solve with this spec is simply to enable
the ability to attach a volume to multiple locations, and provide the cloud
operator with policies to enable/disable the functionality for the cloud.  We
do NOT offer any mechanism to keep a user from corrupting their data or doing
something terrible.&lt;/p&gt;
&lt;section id="terminology"&gt;
&lt;h3&gt;Terminology&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Multi-Attach RO:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;The ability to attach a volume as one would normally do (Read Write access)
and then to attach that volume to another host(s)/server(s) in Read Only
mode.  Note, this is actually tricky because this typically will require that
the consumer (ie Nova/KVM) knows how to set and enforce Read Only on an
attached volume.&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Multi-Attach RW:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;The ability to attach a volume as one would normally do (Read Write access)
and then to attach that volume to another host(s)/server(s).  In this case
there is no differentiation between the initial attachment and any subsequent
attachments.  They are all treated as independent items and are all Read
Write volumes with no real distinction beyond what’s provided with a single
attachment.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;The ability to set Read Only options on attachments will be handled as seperate
work in the from of an argument to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;attachment-create&lt;/span&gt;&lt;/code&gt;.  That feature is
not considered part of the scope of this spec and will be handled independently.&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Multi-Attach Capable Backend:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Some backend devices just flat out may not support this.  Those that do are
considered to be “Multi-Attach Capable” backend devices and need to report
this in their capabilities.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Example Volume Types to communicate Multi Path info:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;{
‘multiattach’: ‘&amp;lt;is&amp;gt; True’,
}&lt;/p&gt;
&lt;p&gt;It will be up to the Cinder scheduler to determine if the policy allows these
types of volumes to be created, and it will then be up to the driver to form
the corresponding Connection and Volume attributes appropriately in it’s
model returns.&lt;/p&gt;
&lt;p&gt;Again NOTE we will NOT allow retype of multiattachment setting for an &lt;cite&gt;in-use&lt;/cite&gt;
volume.&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;There are products that can be used like Oracle RAC that
would make things like H/A databases via a shared Block device possible which
is something of interest.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The other use case that’s been proposed is the
ability to have things like passive stand-by servers/volumes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Analyzing/Fleecing an Instance from another Instance or host&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;section id="multiattach-policy"&gt;
&lt;h3&gt;MultiAttach policy&lt;/h3&gt;
&lt;p&gt;Create a Cinder policy that enables/disables the ability to multi-attach
a volume.  This policy is a global policy for the endpoint and simply either
enables or disables the capability.&lt;/p&gt;
&lt;p&gt;Additionally we’ll want a specific policy to enable/disable the ability to
multiattach bootable volumes (volume with the bootable parameter set True).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="multiattach-capable-volume-type"&gt;
&lt;h3&gt;MultiAttach capable volume type&lt;/h3&gt;
&lt;p&gt;In order to ensure that a volume is created on a backend that supports multiple
attachments, it will need to be created on a backend that allows this.  The
only way to safely control this is be requiring that a type of
“multiattach” is created and used on volume creation.&lt;/p&gt;
&lt;p&gt;If an additional attach request is made to a volume that is NOT of the type
multi-attach enabled the request should fail as the volume is already in-use,
and either a new volume should be created of the correct type, or the volume
should be retyped.  Of course if the policy allows and the type is correct the
additional attachment request should be processed and the existing
attachment(s) are left active and NOT interrupted.&lt;/p&gt;
&lt;p&gt;To avoid various corner cases and confusion for users in what’s allowed and
what’s not, this spec proposes we set a hard-code rule that disallows the
retyping of attachment parameters of an &lt;cite&gt;in-use&lt;/cite&gt; volume.  Regardless of what
those changes are; multi–&amp;gt;non-multi, non-multi–&amp;gt;multi.&lt;/p&gt;
&lt;p&gt;Any retype command should inspect the multiattach keys and if there is any
change being requested in said keys the retype should fail immediately at the
API service.&lt;/p&gt;
&lt;p&gt;NOTE that the default will be multiattach:False&lt;/p&gt;
&lt;p&gt;There is an additional required task, the &lt;cite&gt;–allow-multiattach&lt;/cite&gt;
parameter included with volume create needs to be deprecated and it needs to be
very explicit that that flag is NOT relevant to the implementation of
multi-attach that is being proposed in this spec and implemented in Cinder API
microversion xyz.&lt;/p&gt;
&lt;p&gt;Special considerations for force-detach; recent changes have been added that
treat things like detach of attachments with no connector as &lt;cite&gt;force detach&lt;/cite&gt;
operations.  This should be fine in a multi-attach scenario because the force
detach is ONLY issued against that instantiation of an attachment.  In other
words the only thing force detach does is ignore state checks and disconnects
the specified session, leaving others intact.  The process on the Cinder side
should follow the standard multi-attach detach process with the exception of
ignoring the status of the volume.&lt;/p&gt;
&lt;p&gt;FWIW that call rarely works as users expect anyway, so maybe this will be
a good time to revisit it.  Perhaps deprecate it, and include a force parameter
to the attachment-delete API call itself?&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Be cloudy and write clustered apps&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use things like independent data instances&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Get over it, you probably don’t really need this&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;N/A
All of the needed changes to the data model should already be in place.
Inparticular the existing &lt;cite&gt;multiattach&lt;/cite&gt; column on the volume object, which
will signal the consumer that they’re working with a multiattach capable
volume.  So, if a volume of type multiattach:True is requested/created,
it’s multiattach column is set to True, else False.&lt;/p&gt;
&lt;p&gt;To elaborate on the create flow:
Admin creates a volume type &lt;cite&gt;multiattach&lt;/cite&gt; with extra-specs:
{
‘multiattach’: ‘&amp;lt;is&amp;gt; True’
}&lt;/p&gt;
&lt;p&gt;If a user desires a multiattach volume, he/she issues a create call specifying
the multiattach type:
&lt;cite&gt;cinder create –volume-type multiattach –name my-mavol 20&lt;/cite&gt;&lt;/p&gt;
&lt;p&gt;If there are NO backends reporting &lt;cite&gt;multiattach: True&lt;/cite&gt; then scheduling
will fail.  Unfortunatly this process includes the task-flow retries and the
object will be created, the caller will get a 202 response, but after taskflow
and the scheduler finish retries and fail to find a backend the volume status
will be set to error.  It may be possible to speed this up if we need to and
put capability checks into the API layer so that we could respond immediately
with an Invalid Request. We do provide an API call now that pulls capabilities
from the system, so we could make that check upon receipt of the create request
and make sure it’s possible to fulfill the request.  It would probably be wise
to cache this info based on the periodic capability reporting instead of
fetching it each time.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;This has a number of impacts on the API, the most obvious of which is the fact
that you can attach a volume multiple times.  The other changes that may not be
so obvious are things like representing a volume’s attachment status, and
managing state changes when a secondary attachment is processed or removed.&lt;/p&gt;
&lt;p&gt;The current representation of volume-status is likely to be insufficent once
multiple attachments are enabled.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;User can potentially attach a volume to multiple servers, and corrupt their
data.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Drivers will need to add a capabilities field “multiattach: True/False”, and
do any special handling on their end for connecting/disconnecting volumes in
this category.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;None&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;None&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Update Cinder attach/detach to accomodate shared targets
(most of this is being done independently, see &lt;cite&gt;Dependencies&lt;/cite&gt;
section for more info)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement policy changes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement changes to API to allow/ignore existing attachments on
attachment-create calls.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update the attach/detach volume-status transitions to be multiattach aware
and make sure they reflect the correct values.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update the detail volume view and possibly the summary view to clearly inform
the user when a volume is attached to multiple servers.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Handling of disconnects for devices using shared targets
Initial work is under review here:  &lt;a class="reference external" href="https://review.openstack.org/#/c/520676/"&gt;https://review.openstack.org/#/c/520676/&lt;/a&gt;
Additionally, the API will need a micro version bump and additions to the
response views for volumes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Required patches for service-uuid have already merged
&lt;a class="reference external" href="https://review.openstack.org/#/c/519025/"&gt;https://review.openstack.org/#/c/519025/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/266605/"&gt;https://review.openstack.org/#/c/266605/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;New unit tests will be added to test the changed code and functional testing
will need to be added as well.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;This will require updates to both deployment guides as well as end-user guides.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id2" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://specs.openstack.org/openstack/cinder-specs/specs/ocata/add-new-attach-apis.html"&gt;https://specs.openstack.org/openstack/cinder-specs/specs/ocata/add-new-attach-apis.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;p&gt;Related Nova spec:
&lt;a class="reference external" href="https://specs.openstack.org/openstack/nova-specs/specs/queens/approved/cinder-volume-multi-attach.html"&gt;https://specs.openstack.org/openstack/nova-specs/specs/queens/approved/cinder-volume-multi-attach.html&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Wed, 16 Jan 2019 00:00:00 </pubDate></item><item><title>Promote Replication Target (Cheesecake)</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/rocky/cheesecake-promote-backend.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/replication-backend-promotion"&gt;https://blueprints.launchpad.net/cinder/+spec/replication-backend-promotion&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;After failing backend A over to backend B, there is not a mechanism in
Cinder to promote backend B to the master backend in order to then replicate
to a backend C. We also lack some management commands to help rebuild after a
disaster if states get out of sync.&lt;/p&gt;
&lt;section id="current-workflow"&gt;
&lt;h3&gt;Current Workflow&lt;/h3&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;p&gt;Setup Replication&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Failure Occurs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fail over&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Promote Secondary Backend&lt;/p&gt;
&lt;ol class="loweralpha"&gt;
&lt;li&gt;&lt;p&gt;Freeze backend to prevent manage operations&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Stop cinder volume service&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update cinder.conf to have backend A replaced with B and B with C&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Hack db to set backend to no longer be in ‘failed-over’ state&lt;/em&gt;.
This is the step this spec is concerned with. Example:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="n"&gt;services&lt;/span&gt; &lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="n"&gt;disabled&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;disabled_reason&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;replication_status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'enabled'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;active_backend_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;NULL&lt;/span&gt;
  &lt;span class="n"&gt;where&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Start cinder volume service&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unfreeze backend&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;There was a fire in my data center and my primary backend (A) was destroyed.
Luckily, I was replicating that backend to backend (B). After failing over
to backend B and repairing the data center, we installed backend C to be a
new replication target for B.&lt;/p&gt;
&lt;p&gt;There is also a case where, for whatever reason, the replication state gets out
of sync with reality. In a situation where the status and active backend id
need to be adjusted manually by the cloud admin while recovering from a
disaster.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;To handle the case where the Cinder DB just needs to be synchronized with the
real world we will add the following cinder manage commands to reset the active
backend for a host. Similar to reset-state for volumes this will just do DB
operations. The assumption being that the cinder.conf has already been updated,
and the volume service is stopped, in a disabled state, and probably frozen.
The manage command will verify that the service is stopped, disabled, and
frozen.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;cinder&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;manage&lt;/span&gt; &lt;span class="n"&gt;reset&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;active&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;backend&lt;/span&gt; &lt;span class="n"&gt;replication_status&lt;/span&gt;&lt;span class="o"&gt;=&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; \
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;active_backend_id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;backend&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Equivalent to:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="n"&gt;services&lt;/span&gt; &lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="n"&gt;replication_status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'&amp;lt;status&amp;gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;active_backend_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'&amp;lt;id&amp;gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="n"&gt;where&lt;/span&gt; &lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'&amp;lt;backend-name&amp;gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Where the defaults for &lt;cite&gt;status&lt;/cite&gt; will be disabled and the &lt;cite&gt;active_backend_id&lt;/cite&gt;
will be None. The target for this could also be a cluster in A-A deployments.&lt;/p&gt;
&lt;p&gt;Note: It will be up to the Admin to re-enabled the service.&lt;/p&gt;
&lt;p&gt;That gives us the ability to avoid having an admin go manually run DB commands,
but does &lt;em&gt;NOT&lt;/em&gt; allow for doing this in an “online” recovery. The volume service
must be offline for this to work safely.&lt;/p&gt;
&lt;p&gt;Making this change will require drivers to make adjustments to their
replication states upon initialization. As-is we don’t really have much
definition around what is allowed to change in cinder.conf and how much the
driver should support for changes to replication targets and things like that.
There is sort of an implied contract that when &lt;cite&gt;__init__&lt;/cite&gt; or &lt;cite&gt;do_setup&lt;/cite&gt; is
called the driver &lt;em&gt;should&lt;/em&gt; make their current replication state match what they
are given in the config. This is a little bit problematic today though as there
isn’t a mechanism for them to update DB entries like
&lt;cite&gt;replication_extended_status&lt;/cite&gt; or &lt;cite&gt;replication_driver_data&lt;/cite&gt;. To solve that gap,
and allow for this new officially supported method of modifying replication
status when offline, we will introduce a new driver api method&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;update_host_replication&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;replication_status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;active_backend_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;groups&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This method will be called immediately following &lt;cite&gt;do_setup&lt;/cite&gt; and will return a
model update for the service as well as a list of updates for the volumes and
groups if the driver supports replication groups.  The &lt;cite&gt;group&lt;/cite&gt; parameter will
default to None if not defined.&lt;/p&gt;
&lt;p&gt;The drivers will need to be able to take appropriate steps to get the system
into the desired state based on the current DB state (which was theoretically
modifed before startup by the new cinder-manage command) and the current
cinder.conf.&lt;/p&gt;
&lt;p&gt;If not implemented things will continue to work as they do today, and require
that the admin potentially take more drastic measures to recover after
performing a failover. The goal here is to not break any existing
functionality, but to add enough infrastructure for drivers to behave better.&lt;/p&gt;
&lt;p&gt;When we do this we might require some way of fencing to prevent multiple A-A
driver instances from doing the setup at the same time as it will more than
likely be problematic for some backends, and could risk data loss if more than
one is modifying replication states at the same time. As a simple solution we
could use a new replication_status like &lt;cite&gt;updating&lt;/cite&gt; for the service, and only
allow them to call setup_replication if the status is not set to that. This
status can also be beneficial for an admin to know what is happening if the
process of updating via the driver takes noticeable amounts of time.&lt;/p&gt;
&lt;p&gt;Doing it this way should also allow for later on making “online” updates where
we can utilize that same driver hook to modify replication states. This spec
and initial implementation does not aim to cover that scenario.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;We could add admin API’s to Cinder. Those API’s could do the DB updates and
ping the drivers. The downside is that it requires the API and volume service
to be online, which may be problematic in the scenario that you are picking up
pieces after a disaster.&lt;/p&gt;
&lt;p&gt;Later on we can look into doing “online” promotions where the volume service
does not need to be offline. Similar code in the drivers would be required, but
the complexity gets increased rapidly by trying to support this.&lt;/p&gt;
&lt;p&gt;There was also discussion about using new admin API’s which would modify a db
state that tracks replication info. The downside to this is that we will move
into a scenario where the running config and state doesn’t match the configured
state.&lt;/p&gt;
&lt;p&gt;Following on that path of tracking replication state in the db, we could go to
the extreme and move all of the replication configuration to be done via API’s.
We can then track state, and provide drivers with diffs as the state changes.
In the longer term that addresses the runtime vs config state disparity, but it
will be a significant change in workflow and deployments. Not to mention would
require somewhat major changes to drivers implementing replication.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;A new status for the service/cluster will be added.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Volume service startup will probably take a performance hit, depending on the
backend and how many replicated volumes need to be modified and updated.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Driver maintainers will need to potentially implement this new functionality,
and be aware of the implications of how/when replication configuration and
status can be adjusted.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;jbernard&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Implement cinder-manage reset-active-backend command&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement volume manager changes to allow for &lt;cite&gt;update_host_replication&lt;/cite&gt; to be
used at startup by drivers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open a bug against each backend that supports replication and needs an
update as a result of this change.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Documentation in the Admin guide for how to perform a backend promotion, and
updating the devref for driver developers to explain the expectations of
drivers implementing replication.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Wed, 09 Jan 2019 00:00:00 </pubDate></item><item><title>Affinity and anti-affinity scheduler filter</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/juno/affinity-antiaffinity-filter.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/affinity-antiaffinity-filter"&gt;https://blueprints.launchpad.net/cinder/+spec/affinity-antiaffinity-filter&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;To add scheduler filter to Cinder that allows scheduler to make placement
decision based on affinity relationship between existing volumes and new
volume (the one being scheduled).  The affinity relationship here means
the location of volumes (‘host’ of volume).&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Cinder has done a good job hiding the details of storage backends from end
users by using volume types.  However there are use cases where users who
build their application on top of volumes would like to be able to ‘choose’
where a volume be created on.  How can Cinder provide such capability without
hurting the simplicity we have been keeping?  Affinity/anti-affinity is one
of the flexibility we can provide without exposing details to backends.&lt;/p&gt;
&lt;p&gt;The term affinity/anti-affinity here is to describe the relationship
between two sets of volumes in terms of location.  To limit the scope, we
describe one volume is affinity with the other one only when they reside in
the same volume back-end (this notion can be extended to volume pools if
volume pool support lands in Cinder); on the contrary, ‘anti-affinity’
relation between two sets of volumes simply implies they are on different
Cinder back-ends (pools).&lt;/p&gt;
&lt;p&gt;This affinity/anti-affinity filter filters Cinder backend based on hint
specified by end user.  The hint expresses the affinity or anti-affinity
relation between new volumes and existing volume(s).  This allows end
users to provide hints like ‘please put this volume to a place that is
different from where Volume-XYZ resides in’.  Below are two use cases where
this new filter can be useful.&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;DB team builds MySQL master onto one volume, they’d prefer to put new
volumes for slave DBs to different backends from where the master DB
resides in, for the sake of high availability.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Log processing project would like to have fast storage as possible, so
they create soft RAID across multiple volumes. They want to put these
volumes as close to each other as possible, ideally on the same storage
backend, for the sake of performance.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Add two new filters to Cinder - AffinityFilter and AntiAffinityFilter.  These
two filters will look at the scheduler hint provided by end users (via
scheduler hint extension) and filter backends by checking the ‘host’ of
old and new volumes see if a backend meets the requirement (being on the same
backend as existing volume or not being on the same backend(s) as existing
volume(s)).&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;There had been one proposal to allow admin user to directly specify the
backend for new volumes.  It doesn’t really provide similar functionality as
affinity filter ‘cos it was admin only and it itself has a few drawbacks
(security concern, for example).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;Although this change involves using or parsing user-provided - scheduler hints,
which is already part of Cinder.  This doesn’t put Cinder in any more danger
as it is now.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;New filters would query DB once per request, it only adds slightly latency
to the system and the latency has nothing to do with the size of the system.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;zhiteng-huang (winston-d on IRC)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Filter implementation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Internal DB API modifition&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Test against AffinityFilter:&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create one volume A;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create another volume B with uuid of A and ‘same_backend’ as hint;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Checks if B is created on same backend as A;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;Test against AntiAffinityFilter:&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create one volume A;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create another volume C with uuid of A and ‘different_backend’ as hint;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Checks if C is created on different backend as A;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Need to document the usage of new filters.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;Nova has been offering simliar feature called SameHostFilter and
DifferentHostFilter since &lt;em&gt;Diablo&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/nova/blob/master/nova/scheduler/filters/affinity_filter.py"&gt;https://github.com/openstack/nova/blob/master/nova/scheduler/filters/affinity_filter.py&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Mon, 07 Jan 2019 00:00:00 </pubDate></item><item><title>Backup State Reset API</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/juno/support-reset-state-for-backup.html</link><description>

&lt;p&gt;Include the URL of your launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/support-reset-state-for-backup"&gt;https://blueprints.launchpad.net/cinder/+spec/support-reset-state-for-backup&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Provide an API to reset the state of a backup being stucked in creating or
restoring.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Since there are volume reset-state function and snapshot reset-state function,
backup also needs reset-state as well.
When creating or restoring backup, it may leave backup stucked in creating or
restoring status due to database down or rabbitmq down, etc..
Currently we could only solve these problems by restarting cinder-backup. This
bp is to another mean for administrators to solve these problems by calling
backup reset state API.&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Resetting status from creating/restoring to available&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;restoring –&amp;gt; available
Directly change the backup status to ‘error’, because the backup data is
already existed in storage backend.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;creating –&amp;gt; available
Use backup-create routine as an example to illustrate what benefit we can
get from backup-reset function. Backup-create routine first backup volume
and metadatas, and then update the status of volume and backup. If database
just went down after update the volume’s status to ‘available’, leaving the
backup’s status to be ‘creating’ without having methods to deal with
through API.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If we have reset-state API and resetting status from creating to available, we
first verify whether the backup is ok on storage backend.
If so, we change backup status from creating to available.
If not, we throw an exception and change backup status from creating to error.&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;2. Resetting status from creating/restoring to error
Directly change the backup status to ‘error’ without restart cinder-backup.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;A new API function and corresponding cinder command will be added to reset
the status of backups.&lt;/p&gt;
&lt;p&gt;The initial proposal is to provide a method for administrator to handle the
backup item stucked in status like creating or restoring.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Login in the cinder database, use the following update sql to change the
backup item.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="n"&gt;backups&lt;/span&gt; &lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'some status'&lt;/span&gt; &lt;span class="n"&gt;where&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'xxx-xxx-xxx-xxx'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Add a new REST API to reset backup states:&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;POST /v2/{tenant_id}/backups/{id}/action&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;JSON request schema definition:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="s1"&gt;'backup-reset_status'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'status'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'available'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Normal http response code:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;202&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Expected error http response code:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;400&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;A new command, backup-reset-state, will be added to python-cinderclient. This
command mirrors the underlying API function.&lt;/p&gt;
&lt;p&gt;Resetting the status of a backup can be performed by:
$ cinder backup-reset-state –state &amp;lt;state&amp;gt; &amp;lt;backup&amp;gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;ling-yun&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Implement REST API&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement cinder client functions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement cinder command&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;The cinder client documentation will need to be updated to reflect the new
command.&lt;/p&gt;
&lt;p&gt;The cinder API documentation will need to be updated to reflect the REST API
changes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Mon, 07 Jan 2019 00:00:00 </pubDate></item><item><title>New Core APIs for Discovering System Capabilities</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/newton/discovering-system-capabilities.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/discovering-system-capabilities"&gt;https://blueprints.launchpad.net/cinder/+spec/discovering-system-capabilities&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;There needs to be a way for Horizon to discover the capabilities of the remote
block storage deployment so that it can enable/disable the UI widgets
that exercise those capabilities. Consider the volume backup functionality
which may or may not be supported by a cinder deployment. If Horizon could
programmatically detect the presence of this capability, it can enable the
volume backup actions in the UI. This will obviate the need for the operator
to manually set appropriate fields in Horizon’s config to signal the
availability of this feature, which is the case today. We propose adding
a set of APIs that would return the “capabilities” available to the current
user. These can be used by Horizon and other clients to configure themselves
without the need for config files that are manually kept in sync.&lt;/p&gt;
&lt;p&gt;This blueprint grew out of the design discussion in &lt;a class="footnote-reference brackets" href="#id12" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; and &lt;a class="footnote-reference brackets" href="#id13" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; for the bug
#1334856 &lt;a class="footnote-reference brackets" href="#id14" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; filed by jgriffith.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Horizon allows users to create volume backups via the UI, if the underlying
cinder deployment supports the same. Not all cinder deployments support this
functionality, so Horizon needs a way to know when it is supported so that
it can show the UI elements for backup.&lt;/p&gt;
&lt;p&gt;Today, Horizon uses &lt;a class="footnote-reference brackets" href="#id16" id="id4" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;5&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; a config setting “enable_backup” for controlling the
enable status of volume backup operations in the UI. This needs to be manually
set/unset by the operator based on the status of the cinder-backup service.
This is not only cumbersome but also prone to operator error.&lt;/p&gt;
&lt;p&gt;The volume backup API is implemented on the server side by the cinder-backup
service. This service is absent when the cinder deployment does not support
volume backups. This is the case, e.g., for devstack with default config.&lt;/p&gt;
&lt;p&gt;The “os-services” API extension shows the state of all backend services.
This suggests a way by which Horizon could get to know the existence of the
cinder-backup service. However this has two problems. The first is that the
os-services API is admin-only whereas the backup operation is available to
even non-admin users. The second and more important problem is that not all
features have corresponding services or extension APIs that could be used to
compute the support for that feature in a similar way.&lt;/p&gt;
&lt;p&gt;This problem raises its head in non UI domains also. Consider the OpenStack
Heat project. Heat templates allows the option of backing up a volume upon the
deletion of the corresponding volume resource in the template. However,
as there is no way to know whether backup capability is supported by a
Cinder deployment, this can result in late failures during a volume delete.
This ultimately prevents interoperability of orchestration templates across
clouds.&lt;/p&gt;
&lt;p&gt;It is easy to see that the above problem is not limited to just the backup
feature but is much more general. Horizon needs a way to programmatically
know which capabilities are supported by the remote block storage service so
that it can enable only those UI widgets that deal with these capabilities
and disable others.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;The solution proposed in this spec allows building a dynamic, self-configuring
Horizon UI. This unburdens the operator from manually configuring Horizon and
constantly keeping it in sync with the capabilities of the Cinder deployment.&lt;/p&gt;
&lt;p&gt;This solution can be immediately applied to solve the volume backup enable
status problem in Horizon. No longer will the operator need to set the
“enable_backup” in Horizon config; Horizon will programmatically get the
status using the proposed API.&lt;/p&gt;
&lt;p&gt;Other capability which can similarly gain is the replication capability, which
is only supported by certain volume types (actually “volume backends”, but
normally volume backends are more or less tied to volume types). Note that
feature will be listed by a different capability API than the one that lists
the backup feature. See details below.&lt;/p&gt;
&lt;p&gt;The proposed set of APIs can also be used in custom UIs or user scripts for
the same reasons that we envision Horizon using it for.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;A new, public Block Storage microversion API that returns the set of all
capabilities for a particular user and resource. Note that the service (or
the deployment) itself is considered as a resource (the root resource).&lt;/p&gt;
&lt;p&gt;The capabilities of a system can be defined at multiple levels. The
top-level capabilities such as backup capability are defined at the service
level (or the root resource level). So, the question “Does this cinder service
instance have backup capability?” makes sense by itself. Lower level
capabilities are defined on specific (REST) resources. For example,
replication feature is defined on a volume type. So, it doesn’t make sense to
ask “Does this cinder service instance have the replication capability?”;
instead, we need to ask “Does the volume type xyz have the replication
capability?”.&lt;/p&gt;
&lt;p&gt;While we can define a capabilities API for every resource, in practice it will
be required only a small number of resources. For the Cinder API, it is only
required today for the service and volume type resources.&lt;/p&gt;
&lt;p&gt;It is not possible to avoid multiple levels of capability APIs. The
lower level capability APIs require input (the resource type) which is not
available at the top level.&lt;/p&gt;
&lt;p&gt;The different levels of capability APIs also align with the natural
organization of any UI (e.g. Horizon). On the home page, the UI only shows
the widgets corresponding to top level capabilities. It is possible to
navigate to deeper levels by selecting widgets on the home page. For
example, selecting a particular volume type can lead a page showing widgets
that correspond to the capabilities of that particular volume type. By making
the calls to appropriate level capabilities API, Horizon can programmatically
configure itself at every level.&lt;/p&gt;
&lt;p&gt;Note that a cinder instance may implement a particular feature but may not
allow a particular user to access the same. So, the capabilities API
should not only consider whether the service implements the particular feature
but also if the current user is privileged to access the same. The “privilege”
information is already available in the policy.json &lt;a class="footnote-reference brackets" href="#id15" id="id5" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; file that maps different
operations to the users that can access them. So, any capapbility API
implementation must make use of this file.&lt;/p&gt;
&lt;p&gt;The detection of whether a particular deployment/resource implements a
particular capability varies by the capability itself. For the backup
capability, it could be the presence of the cinder-backup service. For
replication feature, it could be statically set when the volume type is
created or it could be fetched from the driver somehow.&lt;/p&gt;
&lt;p&gt;It is not possible to implement the capabilities API based solely on the info
in the policy.json &lt;a class="footnote-reference brackets" href="#id15" id="id6" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; file as the policy file does not allow defining rules
per resource. For example, we can allow replication operation for all users
but we cannot constrain it to a specific volume type (which is deal breaker
since not all volume types support replication).&lt;/p&gt;
&lt;p&gt;It is easy to see that all capabilities APIs should be public, i.e. accessible
by any user.&lt;/p&gt;
&lt;p&gt;The key contribution of this BP is identifying and proposing an API pattern,
namely “one capability API per resource” (of course if some resource doesn’t
need it, we don’t need to define a capability API for it). This idea is simple
but powerful and also reusable across all OpenStack projects.&lt;/p&gt;
&lt;p&gt;While this BP proposes an API pattern, we will only implement the top level
capabilities API. This will return only “volume-backup” for now but can be
augmented as new capabilities are added to Cinder at the service level. For
now, the detection of the backup capability would be similar to the
os-services extension. It will check if the cinder-backup service is enabled
or not by checking the services table from cinder database and if so return
“volume-backup” in the response.&lt;/p&gt;
&lt;p&gt;A brief note on the presence of capabilities like APIs in Cinder today: There
is a “volume capabilities” extension API &lt;a class="footnote-reference brackets" href="#id17" id="id7" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;6&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, but it is defined at the
service level (&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/v2/{tenant_id}/capabilities/{hostname}&lt;/span&gt;&lt;/code&gt;) rather than at
the volume type level. The “show volume type details” API &lt;a class="footnote-reference brackets" href="#id19" id="id8" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;8&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; stuffs the
capabilities in a catch-all “extra_specs” property. If this BP is approved,
we will need to rationalize these existing APIs with the new capabilities
APIs that will be defined. This is not in scope for this sepc.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Make the existing os-services extension public: This will expose the private
cloud internals to the tenant. This is a security hole and hence makes this
alternative infeasible. Also, there may not be a 1:1 correspondence between
capabilities and services.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Split the existing os-services extension API into public and private halves,
with the public part exposing limited information.&lt;/p&gt;
&lt;p&gt;We could modify the services:index action to take a details=true/false
parameter: http://{cinder-endpoint}/v2/{tenant-id}/os-services?details=false&lt;/p&gt;
&lt;p&gt;And define different policies for detail=true (admin_api) and detail=false
(”” i.e. unrestricted).&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;“volume_extension:services:index_with_details”: “rule:admin_api”&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;“volume_extension:services:index_without_details”: “”&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It is not clear if this can be implemented in a backward compatible way and
also whether there is precedence for splitting the policy of a single API
call based on parameters. Also, as mentioned above, there may not be a 1:1
correspondence between capabilities and services.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Re-use the existing “list extensions” public API &lt;a class="footnote-reference brackets" href="#id18" id="id9" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;7&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. This was proposed by
dulek in &lt;a class="footnote-reference brackets" href="#id13" id="id10" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. First, there may not be a 1:1 correspondence between
capabilities and extensions (although it is true for the volume backup
case). Even if it were always true, the operator would need to prune
cinder.conf (manually!) so that it lists only those extensions that are
actually supported. As explained in &lt;a class="footnote-reference brackets" href="#id13" id="id11" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, there is no easy way to do that.
Also, as noted by duncant, this breaks the existing semantics - many
deployments have the API extensions enabled (as it comes by default) without
the service being actually running. So the check return value would mean
different things on different systems.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None. As explained, we use the existing services table for the volume backup
capability detection. Future capability additions may use different resources
and algorithms.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;We give instances of the “capabilities API pattern” for three resources,
including the service itself.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;GET&lt;/span&gt; &lt;span class="pre"&gt;/v3.x/{tenant&lt;/span&gt; &lt;span class="pre"&gt;id}/capabilities&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Returns the set of capabilities of the underlying block storage deployment
at the service level.&lt;/p&gt;
&lt;p&gt;Normal http response code(s): 200&lt;/p&gt;
&lt;p&gt;Response is a list of capabilities. Each capability is a simple noun or
hyphenated compound noun. E.g:&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-rest notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;{
  "capabilities": [
    {
      "name": "volume-backup",
      "description": "Allows creating backups of volumes."
    },
    {
      "name": "other-capability",
      "description": "Other capability description."
    },
  ]
}
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;GET&lt;/span&gt; &lt;span class="pre"&gt;/v3.x/{tenant_id}/types/{volume_type_id}/capabilities&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Returns the set of capabilities of a particular volume type.&lt;/p&gt;
&lt;p&gt;Normal http response code(s): 200&lt;/p&gt;
&lt;p&gt;Response is a list of capabilities. E.g:&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-rest notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;{
  "capabilities": [
    {
      "name": "replication",
      "description": "Allows replication of volumes."
    },
    {
      "name": "other-capability",
      "description": "Other capability description."
    },
  ]
}
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;General example:&lt;/p&gt;
&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;GET&lt;/span&gt; &lt;span class="pre"&gt;/v3.x/{tenant_id}/&amp;lt;some-resource-collection&amp;gt;/{some-resource-instance}/capabilities&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Returns the set of capabilities of some-resource-instance.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None. Exposing an abstract set of system capabilities should be safe. These
capabilities can be gleaned from the available actions in the UI in any case
(e.g. backup UI widget is visible implies volume backup capability exists).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;This change is transparent to the user although the user can use this API in
a similar way as Horizon for custom UIs or management scripts.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;These are new APIs and should not affect any existing APIs
or code paths.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;Operator no longer has to manually set “enable_backup” in Horizon config
settings file. Back-compat story for this Horizon config change is out of
scope for this spec.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;The developer will need to be aware of the capabilities API pattern and
evaluate if any new optional functionality he/she plans to add to a Cinder
service or a lower level resource (e.g. volume type) may benefit from
being exposed via this API. The developer may first need to define a
capability API for that resource.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;dramakri&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Implement the proposed public microversion capabilities API at the
service level&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement at least the backup capability detection&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add test cases&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update API docs&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit and functional test cases need to be added to validate this new API.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;New API and client call in Cinder needs to be documented.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Changes to Horizon config setting needs to be documented.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id12" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://lists.openstack.org/pipermail/openstack-dev/2015-October/077209.html"&gt;http://lists.openstack.org/pipermail/openstack-dev/2015-October/077209.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id13" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id2"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id10"&gt;2&lt;/a&gt;,&lt;a role="doc-backlink" href="#id11"&gt;3&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://lists.openstack.org/pipermail/openstack-dev/2016-April/092365.html"&gt;http://lists.openstack.org/pipermail/openstack-dev/2016-April/092365.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id14" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id3"&gt;3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/cinder/+bug/1334856"&gt;https://bugs.launchpad.net/cinder/+bug/1334856&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id15" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id5"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id6"&gt;2&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/cinder/blob/master/etc/cinder/policy.json"&gt;https://github.com/openstack/cinder/blob/master/etc/cinder/policy.json&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id16" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id4"&gt;5&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/developer/horizon/topics/settings.html"&gt;http://docs.openstack.org/developer/horizon/topics/settings.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id17" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id7"&gt;6&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://developer.openstack.org/api-ref-blockstorage-v2.html#capabilities-v2"&gt;http://developer.openstack.org/api-ref-blockstorage-v2.html#capabilities-v2&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id18" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id9"&gt;7&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://developer.openstack.org/api-ref-blockstorage-v2.html#volumes-v2-extensions"&gt;http://developer.openstack.org/api-ref-blockstorage-v2.html#volumes-v2-extensions&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id19" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id8"&gt;8&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://developer.openstack.org/api-ref-blockstorage-v2.html#showVolumeType"&gt;http://developer.openstack.org/api-ref-blockstorage-v2.html#showVolumeType&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Sun, 06 Jan 2019 00:00:00 </pubDate></item><item><title>Add user_id attribute to backup response</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/stein/add-user-id-attribute-to-backup-response.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/add-user-id-attribute-to-backup-response"&gt;https://blueprints.launchpad.net/cinder/+spec/add-user-id-attribute-to-backup-response&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This blueprint proposes to add &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;user_id&lt;/span&gt;&lt;/code&gt; attribute to
the response body of list backup with detail and show backup detail APIs.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently, there is a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;user_id&lt;/span&gt;&lt;/code&gt; field in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;backups&lt;/span&gt;&lt;/code&gt; table. These
fields are very useful for admin to manage the backup file, but this
is not returned in response body. So it is difficult to manage the resources
under the project. If there are multiple users under one project, it is
impossible to distinguish which user the backup file belongs to.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;In large scale environment, lots of backups resources were created in system,
that we can only see the project to which the backup file belongs, but we
cannot know to which user the backup belongs.&lt;/p&gt;
&lt;p&gt;Administrators would like the ability to identify the users that have created
backups.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;This spec proposes to add &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;user_id&lt;/span&gt;&lt;/code&gt; attribute to the
response body of list backup with detail and show backup detail APIs.&lt;/p&gt;
&lt;p&gt;Add a new microverion API to add &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;user_id&lt;/span&gt;&lt;/code&gt; attribute
to the response body of list backup with detail and show backup detail APIs:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;List backups with detail GET /v3/{project_id}/backups/detail&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Show backup detail GET /v3/{project_id}/backups/{backup_id}&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;The admin/user could get &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;user_id&lt;/span&gt;&lt;/code&gt; from the context as a log print, but
it’s difficult to find it out easily, especially when the user wants to find
a very old backup file.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;Add a new microversion in Cinder API.&lt;/p&gt;
&lt;p&gt;List backups with detail:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v3&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;backups&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;detail&lt;/span&gt;
&lt;span class="n"&gt;Response&lt;/span&gt; &lt;span class="n"&gt;BODY&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"backups"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
        &lt;span class="o"&gt;...&lt;/span&gt;
        &lt;span class="s2"&gt;"user_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"515ba0dd59f84f25a6a084a45d8d93b2"&lt;/span&gt;
    &lt;span class="p"&gt;}]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Show backup detail:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v3&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;backups&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;backup_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;Response&lt;/span&gt; &lt;span class="n"&gt;BODY&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"backups"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
        &lt;span class="o"&gt;...&lt;/span&gt;
        &lt;span class="s2"&gt;"user_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"515ba0dd59f84f25a6a084a45d8d93b2"&lt;/span&gt;
    &lt;span class="p"&gt;}]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Calling this method shows a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;user_id&lt;/span&gt;&lt;/code&gt; for volume backup.
It is intended for admins to use, which is used to display the user to which
the backup file belongs, and controlled by &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;BACKUP_ATTRIBUTES_POLICY&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Brin Zhang &amp;lt;&lt;a class="reference external" href="mailto:zhangbailin%40inspur.com"&gt;zhangbailin&lt;span&gt;@&lt;/span&gt;inspur&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add a new microversion.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;user_id&lt;/span&gt;&lt;/code&gt; to the response body of list backup
with detail and show backup detail APIs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the related unit tests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update related list backup with detail and show detail api doc.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit-tests, tempest and other related test should be implemented&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Wed, 19 Dec 2018 00:00:00 </pubDate></item><item><title>Driver reinitialization after failure</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/stein/driver-reinitialization-after-fail.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/driver-initialization-after-fail"&gt;https://blueprints.launchpad.net/cinder/+spec/driver-initialization-after-fail&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This spec proposes support for reintialization of volume drivers after it fails
during startup.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;During Cinder initialization, for many reasons, the storage backend might not
be ready and responding. In this case, the driver will not be loaded even if
the array becomes available right after.&lt;/p&gt;
&lt;p&gt;As there is no retry in Cinder volume service, even later the backend storage
is ready, Cinder volume service can’t recover by itself. It needs users
to restart the volume service manually.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;When a Cinder volume service starts, sometimes its corresponding storage
services are not ready. But later the storage services become ready. As a
result the volume service can’t work properly and can’t recover by itself.
But the administrators probably prefer Cinder to automatically recover from
the temporary failures without manual intervention of restarting the service.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;The proposal is to&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Allow reinitialization of a volume driver when it failed to initialize.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Provide a configuration to set the maximum retry numbers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The interval of retry will exponentially backoff. Every interval is the
exponentiation of retry count. The first interval is 1s, second interval
is 2s, third interval is 4s, and so on.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Retry will be handled in init_host.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For this, the following additional config option would be needed:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;‘reinit_driver_count’ (default: 3)&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Set the maximum times to reintialize the driver if volume initialization fails.
Default number is 3.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;We also can differentiate whether it should retry with an exception. Like
import error, config error, it may not retry. But the benefit is not
very impressive, and implementing the differentiation needs work in every
driver. As drivers don’t differentiate such errors from backend storage
errors.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="cinder-client-impact"&gt;
&lt;h3&gt;Cinder-client impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;Users don’t need to restart volume service when the initialization of
drivers fail on recoverable errors.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Lisa Li (&lt;a class="reference external" href="mailto:xiaoyan.li%40intel.com"&gt;xiaoyan&lt;span&gt;.&lt;/span&gt;li&lt;span&gt;@&lt;/span&gt;intel&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add the option ‘reinit_driver_count’.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Retry to initialize volume drivers when it fails.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add related unit test cases.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add unit tests to cover this change.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add administrator documentation to advertise the option of ‘reinit_driver_count’
for driver reinitialization and explain how this should be used.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;None&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Thu, 13 Dec 2018 00:00:00 </pubDate></item><item><title>Improve volume transfer records</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/stein/improve-volume-transfer-records.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/improve-volume-transfer-records"&gt;https://blueprints.launchpad.net/cinder/+spec/improve-volume-transfer-records&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This blueprint proposes to improve volume transfer records by adding
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;source_project_id&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;destination_project_id&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;accepted&lt;/span&gt;&lt;/code&gt; fields to
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;transfer&lt;/span&gt;&lt;/code&gt; table and related api responses, makes it easier for users to
trace the volume transfer history.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently, the volume transfer record does not include the destination
project_id after transferring and the source project_id before transferring.
These fields are very useful for admins and operators to trace the transfer
history.&lt;/p&gt;
&lt;p&gt;And also once the transfer is deleted, the user can’t determine if this
transfer had been accepted or not before it was deleted.&lt;/p&gt;
&lt;p&gt;It is bad for admins and users to trace volume historical track between
project and audit the volume records.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;In order to trace the volume transfer history, the admin wants to know who
was the volume owner before transferring.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The admin wants to know whether a deleted transfer had been accepted or not.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;This spec proposes to do&lt;/p&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;p&gt;Add three new fields to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;transfer&lt;/span&gt;&lt;/code&gt; table:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;source_project_id&lt;/span&gt;&lt;/code&gt;, this field records the source project_id
before volume transferring.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;destination_project_id&lt;/span&gt;&lt;/code&gt;, this field records the destination project_id
after volume transferring.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;accepted&lt;/span&gt;&lt;/code&gt;, this field records if this transfer was accepted or not.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a new microverion API to add above fields to the response of follow
API:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create a volume transfer POST /v3/{project_id}/volume-transfers&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Show volume transfer detail GET /v3/{project_id}/volume-transfers&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;List volume transfer and detail GET
/v3/{project_id}/volume-transfers/detail&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And the response of “List volume transfer (non-detail)” API will not
include these fields.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;The admins could find part of volume transferring info from log, but it’s
difficult to find it out easily, especially when the user wants to audit a
very old volume transfer.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;A new microversion will be created to add these new added fields to transfer
related API responses.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;Notifications will be changed to add these new added fields.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Yikun Jiang &amp;lt;&lt;a class="reference external" href="mailto:yikunkero%40gmail.com"&gt;yikunkero&lt;span&gt;@&lt;/span&gt;gmail&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;source_project_id&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;destination_project_id&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;accepted&lt;/span&gt;&lt;/code&gt;
fields to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;transfer&lt;/span&gt;&lt;/code&gt; table&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;source_project_id&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;destination_project_id&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;accepted&lt;/span&gt;&lt;/code&gt;
fields to related API.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement changes for python-cinderclient to support list transfer with
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;--detail&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update related transfer api doc.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit-tests, tempest and other related test should be implemented&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Mon, 10 Dec 2018 00:00:00 </pubDate></item><item><title>Object deletion from DB without driver interaction</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/stein/delete-from-db.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/cinder-delete-from-db"&gt;https://blueprints.launchpad.net/cinder/+spec/cinder-delete-from-db&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;It’s impossible to delete a volume, a backup or a snapshot when the service is
not available. There’s no way to bypass driver interaction.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;Sometimes, OpenStack admins are pulling the plugs off some storage backends to
use a new one. They realize later that they need to cleanup the various
objects.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;With cinder-manage, we will have a –db-only switch under the volume delete
command. The snapshots are deleted in cascade. We will also implement backup
subcommand that acts like the volume subcommand.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;The only known workaround is to manually update multiple tables and set the
status to ‘deleted’ to various objects.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="active-active-ha-impact"&gt;
&lt;h3&gt;Active/Active HA impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;These commands will be available to operators:&lt;/p&gt;
&lt;div class="highlight-console notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="go"&gt;cinder-manage volume delete [--db-only] &amp;lt;volume-id&amp;gt;&lt;/span&gt;
&lt;span class="go"&gt;cinder-manage backup delete [--db-only] &amp;lt;backup-id&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Primary assignee: David Vallee Delisle &amp;lt;&lt;a class="reference external" href="mailto:dvd%40redhat.com"&gt;dvd&lt;span&gt;@&lt;/span&gt;redhat&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;The following changes will be done under cinder-manage command:
* Add a –db-only switch to the volume delete command.
* Add a backup delete subcommand with –db-only support.
* The snapshots are deleted in cascade when a volume is deleted.&lt;/p&gt;
&lt;p&gt;The following changes will be done in the rpcapis:
* Add a db_only argument in the delete function&lt;/p&gt;
&lt;p&gt;The following changes will be done in the manages:
* Add a db_only argument in the delete function&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Create tests to validate the delete volume and the delete backup are really
deleting.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Man page for cinder-manage and any associated documentation will be updated.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Tue, 16 Oct 2018 00:00:00 </pubDate></item><item><title>Transfer snapshots with volumes</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/rocky/transfer-snapshots-with-volumes.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/transfer-snps-with-vols"&gt;https://blueprints.launchpad.net/cinder/+spec/transfer-snps-with-vols&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This spec aims to extend transfer function that can transfer snapshots
with volumes at same time.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently, Cinder can transfer volumes to another project’s owner, but
if this volume has snapshots before transferring, after this operation,
new owner can’t delete this volume successfully since it has snapshots.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;When transferring volume with snapshots, a user will now have a choice whether
or not to transfer those snapshots along with a volume. By default, snapshots
are transferred, but selecting this option will allow snapshots not to be
transferred to another project.
Note those snapshots can be deleted by the remote user if necessary.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;In normal deleting, Cinder will disallow the request since the volume has
snapshots,  but unfortunately, Cinder has cascade deleting operation now,
the request will be passed down to driver, some driver will raise
exception since snapshot is still existing. So it also should be changed in
cascade deletion process.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add an optional argument “–no-snapshots” in transfer API and CLI. If user
didn’t specify it, cinder will transfer snapshots that a volume has by
default.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a new field in transfer DB model to record this option.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update snapshot’s information in DB like user id, project id, etc.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Check if the volume still has some snapshots in other project when cascade
deleting.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Another option is cinder transfer the snapshots if user specifies an option
argument ‘–with-snapshots’.&lt;/p&gt;
&lt;p&gt;This option can be minimal with the change, in order to make the client code
more simple.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;Add a new field “with_snapshots(boolean)” in transfer model.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;New microversion in Cinder API.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a new V3 API and an optional argument “no_snapshots”:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v3&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;volume&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;transfers&lt;/span&gt;
&lt;span class="n"&gt;RESP&lt;/span&gt; &lt;span class="n"&gt;BODY&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"transfer"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                         &lt;span class="o"&gt;...&lt;/span&gt;
                         &lt;span class="n"&gt;no_snapshots&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                        &lt;span class="p"&gt;}&lt;/span&gt;
           &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;If users didn’t transfer snapshots with volume, there could be kind of
security impact that remote users may be able to act upon the untransferred
snapshots. For example, by leveraging COW, that remote user can change the
snapshot size in backend.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;Add ‘with_snapshots’ information to transfer notificaiton.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;There could be a db performance issue if a lot of snapshots associated with a
given volume since cinder need to change those snapshots’ project id, user id,
etc.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Drivers that implement some form of volume ownership tracking on
the backend will need to be fixed to track this change too.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;wanghao&amp;lt;&lt;a class="reference external" href="mailto:sxmatch1986%40gmail.com"&gt;sxmatch1986&lt;span&gt;@&lt;/span&gt;gmail&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;None&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Implement feature in Cinder tree.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update cinderclient to support this functionality.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add change to API doc.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Both unit and Tempest tests are needed to be created to cover the code change.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;The cinder API documention will need to be updated to reflect the REST
API changes.&lt;/p&gt;
&lt;p&gt;Devref entry on the volume transfer driver entry point should be created.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Tue, 19 Jun 2018 00:00:00 </pubDate></item><item><title>Update backup’s size when backup is created</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/stein/update-backup-size-when-backup-is-created.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/report-size-when-backup-created"&gt;https://blueprints.launchpad.net/cinder/+spec/report-size-when-backup-created&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This blueprint proposes to update backup with the size reported by
backup backend when backup is created.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Most clouds provide end user a convenient way to protect their data by
creating a backup for their volume. Users can create any backup copy at
anytime, and the cloud providers charge them by the backup size in total.
As the basic volume service, Cinder supports creating, restoring and
deleting backups plus the backup quotas, but our backup size isn’t correct
at present, the backup’s size always equals to the original volume’s size
even if the incremental backup doesn’t have any content in it.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;Backup’s size attribute will reflect the actual size on the backend, the quota
and charge would be more accurate.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;This spec proposes that the backup driver should report the actual size that
object holds at the backend when backup is created. So, when user requests to
create a backup for a volume with 10G, Cinder will still generate the record
with 10G as well as consume 10G for quota reservation, but when the actual
size is reported, we will update both the object and the quotas.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: The actual size here stands for the final size at the backend, that
means if we create backup for a 1G volume which only has 200mb data and
after compression only 100mb is used at disk, the actual size is 100mb,
not 200mb or 1G.&lt;/p&gt;
&lt;p&gt;As Cinder has the unified unit G for every resource, that size should be
rounded up to G too, for example, if we create an incremental backup whose
actual size is only 12mb at backend, driver should still report 1 G to
Cinder service:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;backup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;backup&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;volume_file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;backup_metadata&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="sd"&gt;"""Start a backup of a specified volume.&lt;/span&gt;

&lt;span class="sd"&gt;    Driver should return the size that the backup object holds&lt;/span&gt;
&lt;span class="sd"&gt;    in the backend, with the unit of G. For instance:&lt;/span&gt;

&lt;span class="sd"&gt;    .. code-block:: python&lt;/span&gt;

&lt;span class="sd"&gt;        {&lt;/span&gt;
&lt;span class="sd"&gt;            'size': 2&lt;/span&gt;
&lt;span class="sd"&gt;        }&lt;/span&gt;
&lt;span class="sd"&gt;    """&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Cinder’s backup service would use this &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;size&lt;/span&gt;&lt;/code&gt; to update backup model
as well as commit portion of the reservation (Instead of commit the
reservation record, Cinder will update the reservation and then commit
the updated record after backup is actually created in the background
to cover this case ).&lt;/p&gt;
&lt;p&gt;In order to report the actual size that backup holds, drivers need
to record or calculate the object size. Take our &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;chunkeddriver&lt;/span&gt;&lt;/code&gt; for
instance, the total size is accumulated by the objects’ size:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;object1_size&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;object2_size&lt;/span&gt;&lt;span class="o"&gt;....&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;If compression feature is enabled, the object’s size should be:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;compressed_object1_size&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;compressed_object2_size&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Now Cinder has the attribute &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;size&lt;/span&gt;&lt;/code&gt; for backup object which
only reflects the volume’s size when created. In order to support
updating the actual size of the backup, we will add one more attribute
here.&lt;/p&gt;
&lt;p&gt;1. &lt;strong&gt;volume_size&lt;/strong&gt;: This is used to record the original volume’s size
and can be used to create new volume when restoring, we can not directly
link to the original volume size here because we could resize the volume
after the volume is backed up.&lt;/p&gt;
&lt;p&gt;2. &lt;strong&gt;size&lt;/strong&gt;: This will be used to store the reported value from driver
rather the original volume size. And when backup is first created,
this value would be equal to the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volume_size&lt;/span&gt;&lt;/code&gt; and will be updated
when backup is created at backend.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Keep using volume’s size to generate the backup’s size as well as quota
usage record in database.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="cinder-client-impact"&gt;
&lt;h3&gt;Cinder-client impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;There would be a slight performance impact
when committing quota reservations.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Developer should report backup’s size in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;backup&lt;/span&gt;&lt;/code&gt; method
when adding new backup driver.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;tommylikehu(&lt;a class="reference external" href="mailto:tommylikehu%40gmail.com"&gt;tommylikehu&lt;span&gt;@&lt;/span&gt;gmail&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Update cinder to support update the backup size.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update existing driver to report backup’s actual size.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add related unit testcases.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add unit tests to cover this change.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Update the base backup driver’s interface.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update developer’s documentation to advertise this change.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 14 Jun 2018 00:00:00 </pubDate></item><item><title>Cinder Certificate Validation</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/stein/support-validate-image-certificate.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/certificate-validate"&gt;https://blueprints.launchpad.net/cinder/+spec/certificate-validate&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;OpenStack now supports signature verification for signed images. However, it
does not support strong certificate validation for certificates used to
generate image signatures. Specifically, cinder has no mechanism to identify
trusted certificates. While cinder verifies the signature of a signed image
using cursive, there is no way to determine if the certificate used to
generate and verify that signature is a certificate that is trusted by the
user. This change will introduce an addition to the cinder API allowing the
user to specify a list of trusted certificates when creating volume from
images. These trusted certificates will be used to conduct certificate
validation in concert with signature verification in cursive, providing the
user confidence in the identity and integrity of the image being created.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Cinder is capable of verifying the signature of a signed image by using
cursive, the OpenStack signature verification library [1]. Signature
verification ensures that unmodified image data is retrieved from glance.
However, the validation of the certificate used to generate the signature
of the signed image is currently limited to a timestamp validity check,
ensuring only that the certificate is valid for use at the time of signature
verification. There is no mechanism to ensure that the certificate used is
one approved by the end user. An attacker with access to glance could replace
a user’s signed image with a modified, malicious image signed with the
attacker’s certificate, stored in the OpenStack deployment’s certificate
manager. If asked to create volume from the modified image, cinder would
retrieve the image and its corresponding certificate, verify the image
signature, and build a volume using the malicious image data. Providing
support for certificate validation in cursive helps cinder detect this
attack scenario and take steps to alert the user of the potential compromise.&lt;/p&gt;
&lt;p&gt;Note that this threat model considers glance to be untrusted and does not
include threats to the integrity, availability, or confidentiality of cinder.
It assumes that: (1) an attacker has access to the certificate manager and is
able to store certificates for use with image signing, and (2) this attacker
is unable to access arbitrary certificate public/private key pairs belonging
to other users. An attacker with such access would be able to impersonate the
user, replacing signed images and perfectly updating the corresponding image
signatures and metadata as needed to conceal the attack.&lt;/p&gt;
&lt;section id="use-cases"&gt;
&lt;h3&gt;Use Cases&lt;/h3&gt;
&lt;p&gt;Cinder users want to ensure that they are creating from images they trust by
controlling the set of certificates used to sign their images.&lt;/p&gt;
&lt;p&gt;With this change, a cinder user can specify the identities of trusted
certificates when creating volumes from a signed image if
signature verification and certificate validation are enabled. One of these
trusted certificates is expected to be the signing certificate of the
certificate used to generate the image signature.&lt;/p&gt;
&lt;p&gt;With certificate validation enabled, image signature verification will only
succeed if the image signing certificate was generated by a trusted
certificate. This allows users to place themselves in-the-loop of the
signature verification process, requiring valid certificate information for
boot to succeed. Note that if the deployment is configured to trust certain
certificates that the user isn’t aware of, the deployer could still manipulate
images in a way that the user wouldn’t detect with this feature.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Supporting certificate validation requires several changes. The initial change
adds a pair of new configuration options. The first configuration option,
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;enable_certificate_validation&lt;/span&gt;&lt;/code&gt;, will enable the use of the cursive
certificate validation routine when conducting image signature verification
(see the fifth change below). This option will only be used if
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;verify_glance_signatures&lt;/span&gt;&lt;/code&gt; is set to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;enabled&lt;/span&gt;&lt;/code&gt; and will default to
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;False&lt;/span&gt;&lt;/code&gt;.  Certificate validation will be performed if this option is
set to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;True&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The second configuration option, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;default_trusted_certificate_ids&lt;/span&gt;&lt;/code&gt;, will
contain a list of certificate IDs that are designated as trusted by the
cinder deployment. This list of trusted certificate IDs will only be used if
certificate validation is enabled and if no trusted certificate IDs were
provided by the user (see the second and third changes below). The list should
be defined by an administrator as it will be the default set of trusted
certificate IDs for the cinder deployment. The default value of this option
will be an empty list, requiring a user-provided set of trusted certificate
IDs if left empty. If the user does provide a list of trusted certificate IDs,
the list of default trusted certificate IDs will be ignored.&lt;/p&gt;
&lt;p&gt;The second change adds a parameter, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;trusted_image_certificates&lt;/span&gt;&lt;/code&gt;, to the
volume create command of the cinder API. The value of the parameter is an array
containing the string IDs of the trusted certificates used to validate the
signed image’s signing certificate. These IDs are assigned by the certificate
manager upon upload of the trusted certificates. Multiple IDs are allowed here
to provide flexibility for the user. It may not be feasible for the user to
know which specific certificate corresponds to their image. Allowing the user
to define a set of trusted certificates removes the need for an
image/certificate mapping, simplifying the user experience. When provided,
cinder will pass these values to the certificate validation routine in cursive,
overriding the default list of trusted certificate IDs (see the second
configuration option above). Cursive will use them to fetch the trusted
certificates using castellan. If provided, the value of the parameter will be
saved in image metadata.&lt;/p&gt;
&lt;p&gt;The third change integrates the certificate verification routine into the
signature verification workflow. When the certificate verification routine
fetches the image’s signing certificate, it builds the verification context
using the trusted certificates provided by the user. It then passes the
signing certificate through the context for certificate validation. If
validation succeeds, signature verification can proceed as normal.
If validation fails, signature verification fails as well, the volume is
placed in an ERROR state.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: The corresponding feature [2] has been merged into Cursive already.&lt;/p&gt;
&lt;p&gt;It is possible a silent fail scenario could occur if (1) cinder is not
configured to conduct certificate validation, and (2) the user provides
trusted certificate IDs expecting certificate validation to occur. In this
case, cinder would not conduct certificate validation and would boot the
instance, causing the user to believe certificate validation succeeded even
though it never happened. To prevent this from happening, the create workflow
will be updated to conduct signature and certificate verification if trusted
certificate IDs are associated with the create request. This matches
the user’s expectations and prevents a silent fail scenario from ever
occurring. Note here that this override only occurs if the user specifies
certificate IDs. The default list of certificate IDs is only used if
the feature is enabled and therefore will never trigger the override.&lt;/p&gt;
&lt;p&gt;The fourth change updates the cinderclient to support the
trusted_image_certificates parameter for the volume create commands.
This includes support for a new environment variable,
OS_TRUSTED_CERTIFICATE_IDS, that can be used to define a comma-delimited list
of trusted certificate IDs. If the trusted_image_certificates parameter is not
used, the client will pull the value of the environment variable and use it
instead. This value will be converted into a list before being passed on.&lt;/p&gt;
&lt;p&gt;If the user does not provide a value for the trusted_image_certificates
parameter, either explicitly or through the OS_TRUSTED_CERTIFICATE_IDS
environment variable, cinder will pull the list of trusted certificate IDs from
the default_trusted_certificate_ids configuration option. If this option is
left as an empty list, there is no way for nova to obtain a trusted
certificate for certificate validation. In this case there would be no way to
determine if the image’s signing certificate is trusted so signature
verification would fail, in turn failing volume creation.&lt;/p&gt;
&lt;p&gt;To be clear, we will verify the image’s signature only when image is
downloaded from glance and content is copied to volume on host. So when image
volume is created via &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;clone_image&lt;/span&gt;&lt;/code&gt; or &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;clone_image_volume&lt;/span&gt;&lt;/code&gt; we will skip
this verification process, in order not to confuse end users, we will also add
a flag in volume image metadata to indicate whether we validated the
certificates during volume creation, and the service will generate an user
message if the certificate validation fails in the backend.&lt;/p&gt;
&lt;p&gt;Note that these trusted certificates are stored in a certificate manager
independent of the volume service. For this work, a certificate manager is
any service backend supported by castellan that provides management
operations for certificates objects. Certificate management is often a
subset of the functionality provided by generic key managers, which are
capable of managing different types of cryptographic secrets (e.g.,
encryption keys, passwords). As of the Pike release, barbican (the OpenStack
key management service) is the only OpenStack service that satisfies the
requirements for a certificate manager. In the future, any OpenStack or
third-party service that is supported by castellan and provides certificate
management could be used instead of barbican.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;An alternative approach to certificate validation here would be to support
certificate trust stores, collections of trusted certificates associated with
individual users or projects. When creating a new server, the user would
specify their trust store as a source of trusted certificates, replacing the
list of certificates provided in the trusted_image_certificates parameter.
There are many ways to support trust stores, including: a filesystem
directory trust store containing trusted certificate files stored locally on
the compute host, a metadata/managed resource approach supported under
services like nova or keystone, and a container-based secret storage approach
supported by services like barbican. While useful in defining collections of
trusted certificates, a trust store approach would need to scale for large
cloud deployments which may be difficult from a management and maintenance
perspective. Trust stores also introduce a new construct that must be
trusted by the user, especially if the user is not directly responsible for
maintaining their trust store. These restrictions may not be feasible for
some cloud deployments.&lt;/p&gt;
&lt;p&gt;An alternative to the user providing trusted certificates, or storing trusted
certificates in a trust store(or just a database table), would be to
dynamically fetch certificates using information stored in the Private
Internet Extension of the signed certificate being validated. This approach
allows deployers and users to use signing certificates without needing to
pre-fetch all of the root and intermediate certificates required to complete
the certificate validation process. However, this approach requires the
compute service have persistent network access to all possible certificate
repositories where root and intermediate certificates may be stored. In many
cases, this will include network access to the public Internet which may not
be feasible for a generic deployment.&lt;/p&gt;
&lt;p&gt;An enhanced certificate validation routine would include certificate
revocation, supporting commonly used approaches like certificate revocation
lists (CRLs) and/or the Online Certificate Status Protocol (OCSP). Supporting
certificate revocation would allow the compute service to dynamically
determine when certificates become invalid in real time due to compromise,
further improving the security of booting signed images. However, supporting
certificate revocation involves dynamically fetching and trusting network
resources, often under the control and authority of third-parties. This may
not be feasible for some deployments. It is possible that certificate
revocation could be integrated outside of the compute service, for example
within the certificate manager or through another third-party service. This
would grant nova the benefits of timely revocation without complicating the
signature verification and certificate validation features in nova itself.&lt;/p&gt;
&lt;p&gt;It should be noted here that support for certificate revocation is intended
to be added in future work for this feature.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;p&gt;Add a new microversion to support specifying &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;trusted_image_certificates&lt;/span&gt;&lt;/code&gt;
when creating volume:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;V3&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tenant_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;volumes&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight-javascript notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"volume"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="s2"&gt;"size"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"image_volume"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="s2"&gt;"imageRef"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"CAB56EC2-4BDC-45D4-9898-3F88A7003261"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="s2"&gt;"trusted_image_certificates"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="s2"&gt;"00000000-0000-0000-0000-000000000000"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="s2"&gt;"11111111-1111-1111-1111-111111111111"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="s2"&gt;"22222222-2222-2222-2222-222222222222"&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Note that while in these examples the values in trusted_image_certificates
are UUIDs they are not guaranteed to be so. Certificate managers use
different ID allocation schemes; while some use strict UUIDs, others use
simple incrementing integers or raw hex strings. For this feature, the type
of trusted_image_certificates will be an array containing zero or more JSON
string values.&lt;/p&gt;
&lt;p&gt;The following is a JSON schema description of the trusted_image_certificates
parameter:&lt;/p&gt;
&lt;div class="highlight-javascript notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"array"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="s2"&gt;"minItems"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="s2"&gt;"maxItems"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="s2"&gt;"uniqueItems"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="s2"&gt;"items"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"string"&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Note the upper and lower bounds for the number of certificate IDs included
in the trusted_image_certificates parameter. If an API call is made for a
signed image and exceeds the maximum number of allowed certificate IDs, then
the API call will fail.&lt;/p&gt;
&lt;p&gt;API version bump will be required for these changes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;With the added verification step provided by this feature when enabled, the
security of the signed image verification feature is improved.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;With support being added for the OS_TRUSTED_CERTIFICATE_IDS environment
variable, users are encouraged to set the variable with the list of trusted
certificate IDs through their openrc file, alongside their authentication
credentials. The value of the OS_TRUSTED_CERTIFICATE_IDS environment variable
is a comma-delimited string of trusted certificate IDs, which will be
converted into a list of certificate IDs for the trusted_image_certificates
parameter.&lt;/p&gt;
&lt;p&gt;An example openrc file is shown below, using the same trusted certificate IDs
as those used in the API example (see REST API Impact above):&lt;/p&gt;
&lt;div class="highlight-bash notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="nb"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;OS_USERNAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;username
&lt;span class="nb"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;OS_PASSWORD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;password
&lt;span class="nb"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;OS_TENANT_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;projectName
&lt;span class="nb"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;OS_AUTH_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;https://identityHost:portNumber/v2.0
&lt;span class="nb"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;OS_TRUSTED_CERTIFICATE_IDS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;00000000&lt;/span&gt;-0000-0000-0000-000000000000,
&lt;span class="m"&gt;11111111&lt;/span&gt;-1111-1111-1111-111111111111,22222222-2222-2222-2222-222222222222
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Cinder will load the user’s trusted certificates via cursive every time
signature verification is performed. Depending upon the size and number of
certificates, and the frequency of signature verification, this could
introduce a performance burden on the volume service, such as consuming images
from the Cinder image cache. To alleviate this, see “Alternatives” above
regarding a persistent certificate trust store and dynamically loading
certificates from remote storage.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;The inclusion of two new configuration options, enable_certificate_validation
and default_trusted_certificate_ids, will smooth the transition for
deployments looking to enable this feature.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Yikun Jiang(&lt;a class="reference external" href="mailto:yikunkero%40gmail.com"&gt;yikunkero&lt;span&gt;@&lt;/span&gt;gmail&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;)&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;tommylikehu(&lt;a class="reference external" href="mailto:tommylikehu%40gmail.com"&gt;tommylikehu&lt;span&gt;@&lt;/span&gt;gmail&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add two new configuration options, enable_certificate_validation and
default_trusted_certificate_ids. The first will enable the use of
certificate validation if signature verification is enabled. The second will
provide a default list of trusted certificate IDs that can be used if no
trusted certificate IDs are provided with the volume request.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update the existing signature verification workflow in cinder to incorporate
certificate validation, using the verify_certificate routine in cursive to
validate the signing certificate.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a new cinder API parameter, trusted_image_certificates, to the volume
create command. The value of this parameter will need to be
passed through to the signature verification step when downloading the image
from glance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update cinderclient to support the trusted_image_certificates parameter.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update cinderclient to pull the value of the OS_TRUSTED_CERTIFICATE_IDS
environment variable when the trusted_image_certificates parameter is not
provided by the user.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit tests will be included to test the functionality implemented in cinder,
cinderclient. Tempest tests will also be implemented to test the end-to-end
feature across glance and cinder.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Documentation on the trusted_image_certificates API parameter and the two
new configuration options will need to be added, as will instructions
defining the OS_TRUSTED_CERTIFICATE_IDS environment variable and its usage.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;[1] “Cursive.” Online: &lt;a class="reference external" href="https://launchpad.net/cursive"&gt;https://launchpad.net/cursive&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[2] “Add certificate validation.” &lt;a class="reference external" href="https://review.openstack.org/#/c/357202/"&gt;https://review.openstack.org/#/c/357202/&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Tue, 05 Jun 2018 00:00:00 </pubDate></item><item><title>API Validation</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/queens/v3-api-validation.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/json-schema-validation"&gt;https://blueprints.launchpad.net/cinder/+spec/json-schema-validation&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Currently, Cinder has different implementations for validating
request bodies. The purpose of this blueprint is to track the progress of
validating the request bodies sent to the Cinder server, accepting requests
that fit the resource schema and rejecting requests that do not fit the
schema. Depending on the content of the request body, the request should
be accepted or rejected consistently.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently Cinder doesn’t have a consistent request validation layer. Some
resources validate input at the resource controller and some fail out in the
backend. Ideally, Cinder would have some validation in place to catch
disallowed parameters and return a validation error to the user.&lt;/p&gt;
&lt;p&gt;The end user will benefit from having consistent and helpful feedback,
regardless of which resource they are interacting with.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;As a user or developer, I want to observe consistent API validation and values
passed to the Cinder API server.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;One possible way to validate the Cinder API is to use jsonschema similar to
Nova, Keystone and Glance (&lt;a class="reference external" href="https://pypi.org/project/jsonschema"&gt;https://pypi.org/project/jsonschema&lt;/a&gt;).
A jsonschema validator object can be used to check each resource against an
appropriate schema for that resource. If the validation passes, the request
can follow the existing flow of control through the resource manager to the
backend. If the request body parameters fails the validation specified by the
resource schema, a validation error wrapped in HTTPBadRequest will be returned
from the server.&lt;/p&gt;
&lt;p&gt;Example:
“Invalid input for field ‘name’. The value is ‘some invalid name value’.&lt;/p&gt;
&lt;p&gt;Each API definition should be added with the following ways:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create definition files under ./cinder/api/schemas/.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Each definition should be described with JSON Schema.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Each parameter of definitions(type, minLength, etc.) can be defined from
current validation code, DB schema, unit tests, Tempest code, or so on.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Some notes on doing this implementation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Common parameter types can be leveraged across all Cinder resources. An
example of this would be as follows:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;cinder.api.validation&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;parameter_types&lt;/span&gt;
&lt;span class="c1"&gt;# volume create schema&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;snip&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
     &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'object'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'properties'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s1"&gt;'volume'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'object'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'properties'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="s1"&gt;'size'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;parameter_types&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;positive_integer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s1"&gt;'availability_zone'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;parameter_types&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;availability_zone&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s1"&gt;'source_volid'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="s1"&gt;'format'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'uuid'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="p"&gt;},&lt;/span&gt;
                    &lt;span class="s1"&gt;'description'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;parameter_types&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s1"&gt;'multiattach'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;parameter_types&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s1"&gt;'snapshot_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="s1"&gt;'format'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'uuid'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="p"&gt;},&lt;/span&gt;
                    &lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;parameter_types&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s1"&gt;'imageRef'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="s1"&gt;'format'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'uuid'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="p"&gt;},&lt;/span&gt;
                    &lt;span class="s1"&gt;'volume_type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="s1"&gt;'format'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'uuid'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="p"&gt;},&lt;/span&gt;
                    &lt;span class="s1"&gt;'metadata'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'object'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                     &lt;span class="p"&gt;},&lt;/span&gt;
                    &lt;span class="s1"&gt;'consistencygroup_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="s1"&gt;'format'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'uuid'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="s1"&gt;'required'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'size'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="s1"&gt;'additionalProperties'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="s1"&gt;'required'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'server'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s1"&gt;'additionalProperties'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;create_v312&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;copy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;deepcopy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;create_v312&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'properties'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;'volume'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;
    &lt;span class="s1"&gt;'properties'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;'group_id'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'format'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'uuid'&lt;/span&gt;&lt;span class="p"&gt;,},&lt;/span&gt;

&lt;span class="n"&gt;parameter_types&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'string'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'minLength'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'maxLength'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;positive_integer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'integer'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'string'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="s1"&gt;'pattern'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'^[0-9]*$'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'minimum'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'minLength'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;description&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;
&lt;span class="n"&gt;availability_zone&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;

&lt;span class="c1"&gt;# This registers a FormatChecker on the jsonschema module.&lt;/span&gt;
&lt;span class="c1"&gt;# It might appear that nothing is using the decorated method but it gets&lt;/span&gt;
&lt;span class="c1"&gt;# used in JSON schema validations to check uuid formatted strings.&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;oslo_utils&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;uuidutils&lt;/span&gt;

&lt;span class="nd"&gt;@jsonschema&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FormatChecker&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cls_checks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'uuid'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;_validate_uuid_format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;uuidutils&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_uuid_like&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;boolean&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'boolean'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'string'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="s1"&gt;'enum'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'True'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'TRUE'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'true'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'1'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'ON'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'On'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'on'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s1"&gt;'YES'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Yes'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'yes'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'False'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'FALSE'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'false'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'0'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'OFF'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Off'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'off'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s1"&gt;'NO'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'No'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'no'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The validation can take place at the controller layer using below decorator:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;cinder.api.schemas&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;volume&lt;/span&gt;

&lt;span class="nd"&gt;@wsgi&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;http_client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ACCEPTED&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@validation&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;volume&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"3.0"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@validation&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;volume&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_v312&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"3.12"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="sd"&gt;"""creates a volume.&lt;/span&gt;

&lt;span class="sd"&gt;     version 3.12 added groupd_id to the volume request body.&lt;/span&gt;
&lt;span class="sd"&gt;     If user has requested volume create with version v2 then the&lt;/span&gt;
&lt;span class="sd"&gt;     'validation.schema' decorator will ignore its schema validation and&lt;/span&gt;
&lt;span class="sd"&gt;     will pass the request as it is in the create method."""&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Initial work will include capturing the Block Storage API Spec for existing
resources in a schema. This should be a one time operation for each
major version of the API. This will be applied to the Block Storage V3 API.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When adding a new extension to Cinder, the new extension must be proposed
with its appropriate schema.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Before the API validation framework, we needed to add the validation code into
each API method in ad-hoc. These changes would make the API method code dirty
and we needed to create multiple patches due to incomplete validation.&lt;/p&gt;
&lt;p&gt;If using JSON Schema definitions instead, acceptable request formats are clear
and we don’t need to do ad-hoc works in the future.&lt;/p&gt;
&lt;p&gt;Pecan Framework:
&lt;a class="reference external" href="http://pecan.readthedocs.org/en/latest/"&gt;Pecan&lt;/a&gt;
Some projects(Ironic, Ceilometer, etc.) are implemented with Pecan/WSME
frameworks and we can get API documents automatically from the frameworks.
In WSME implementation, the developers should define API parameters for
each API. Pecan would make the implementations of API routes(URL, METHOD) easy.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;API Response code changes:&lt;/p&gt;
&lt;p&gt;There are some occurrences where API response code will change while adding
schema layer for them. For example, On current master ‘services’ table has
‘host’ and ‘binary’ of maximum 255 characters in database table. While updating
service user can pass ‘host’ and ‘binary’ of more than 255 characters which
obviously fails with 404 ServiceNotFound wasting a database call. For this we
can restrict the ‘host’ and ‘binary’ of maximum 255 characters only in schema
definition of ‘services’. If user passes more than 255 characters, he/she will
get 400 BadRequest in response.&lt;/p&gt;
&lt;p&gt;API Response error messages:&lt;/p&gt;
&lt;p&gt;There will be change in the error message returned to user. For example,
On current master if user passes more than 255 characters for volume name
then below error message is returned to user from cinder-api:&lt;/p&gt;
&lt;p&gt;Invalid input received: name has &amp;lt;actual no of characters user passed&amp;gt;
characters, more than 255.&lt;/p&gt;
&lt;p&gt;With schema validation below error message will be returned to user for this
case:&lt;/p&gt;
&lt;p&gt;Invalid input for field/attribute name. Value: &amp;lt;value passed by user&amp;gt;.
‘&amp;lt;value passed by user&amp;gt;’ is too long.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;The output from the request validation layer should not compromise data or
expose private data to an external user. Request validation should not
return information upon successful validation. In the event a request
body is not valid, the validation layer should return the invalid values
and/or the values required by the request, of which the end user should know.
The parameters of the resources being validated are public information,
described in the Block Storage API spec, with the exception of private data.
In the event the user’s private data fails validation, a check can be built
into the error handling of the validator to not return the actual value of the
private data.&lt;/p&gt;
&lt;p&gt;jsonschema documentation notes security considerations for both schemas and
instances:
&lt;a class="reference external" href="http://json-schema.org/latest/json-schema-core.html#anchor21"&gt;http://json-schema.org/latest/json-schema-core.html#anchor21&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Better up front input validation will reduce the ability for malicious user
input to exploit security bugs.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Cinder will need some performance cost for this comprehensive request
parameters validation, because the checks will be increased for API parameters
which are not validated now.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;This will require developers contributing new extensions to Cinder to have
a proper schema representing the extension’s API.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Primary assignee:
Dinesh_Bhor (Dinesh Bhor &amp;lt;&lt;a class="reference external" href="mailto:dinesh.bhor%40nttdata.com"&gt;dinesh&lt;span&gt;.&lt;/span&gt;bhor&lt;span&gt;@&lt;/span&gt;nttdata&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;)&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Initial validator implementation, which will contain common validator code
designed to be shared across all resource controllers validating request
bodies.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Introduce validation schemas for existing core API resources.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Introduce validation schemas for existing API extensions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enforce validation on proposed core API additions and extensions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Remove duplicated ad-hoc validation code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add unit and end-to-end tests of related API’s.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add/Update cinder documentation.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;The extension’s which are there under cinder/api/contrib/ are getting called by
v2 as well as v3. So if we add schema validation for v3 then we will have to
remove the existing validation of parameters which is there inside of
controller methods which will again break the v2 apis.&lt;/p&gt;
&lt;p&gt;Solution:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Do the schema validation for v3 apis using the @validation.schema decorator
similar to Nova and also keep the validation code which is there inside of
method to keep v2 working.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Once the decision is made to remove the support to v2 we should remove the
validation code from inside of method.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Tempest tests can be added as each resource is validated against its schema.
These tests should walk through invalid request types.&lt;/p&gt;
&lt;p&gt;We can follow some of the validation work already done in the Nova V3 API:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/tempest/tree/etc/schemas/compute/flavors/flavors_list.json?id=24eb89cd3efd9e9873c78aacde804870962ddcbb"&gt;Validation Testing&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/tempest/tree/tempest/api/compute/flavors/test_flavors_negative.py?id=b2978da5ab52e461b06a650e038df52e6ceb5cd6"&gt;Negative Validation Testing&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Negative validation tests should use tempest.test.NegativeAutoTest&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;The cinder API documentation will need to be updated to reflect the
REST API changes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The cinder developer documentation will need to be updated to explain
how the schema validation will work and how to add json schema for
new API’s.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;Useful Links:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;[Understanding JSON Schema] (&lt;a class="reference external" href="http://spacetelescope.github.io/understanding-json-schema/reference/object.html"&gt;http://spacetelescope.github.io/understanding-json-schema/reference/object.html&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[Nova Validation Examples] (&lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/nova/tree/nova/api/validation"&gt;http://git.openstack.org/cgit/openstack/nova/tree/nova/api/validation&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[JSON Schema on PyPI] (&lt;a class="reference external" href="https://pypi.org/project/jsonschema"&gt;https://pypi.org/project/jsonschema&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[JSON Schema core definitions and terminology] (&lt;a class="reference external" href="http://tools.ietf.org/html/draft-zyp-json-schema-04"&gt;http://tools.ietf.org/html/draft-zyp-json-schema-04&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[JSON Schema Documentation] (&lt;a class="reference external" href="http://json-schema.org/documentation.html"&gt;http://json-schema.org/documentation.html&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Tue, 01 May 2018 00:00:00 </pubDate></item><item><title>Cinder Volume Active/Active support - Replication</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/ocata/ha-aa-replication.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/cinder-volume-active-active-support"&gt;https://blueprints.launchpad.net/cinder/+spec/cinder-volume-active-active-support&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As it stands to reason replication v2.1 only works in deployment configurations
that were available and supported in Cinder at the time of its design and
implementation.&lt;/p&gt;
&lt;p&gt;Now that we are also supporting Active-Active configurations this translates to
replication not properly working on this new supported configuration.&lt;/p&gt;
&lt;p&gt;This spec extends replication v2.1 functionality to support Active-Active
configurations while preserving backward compatibility for non clustered
configurations.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;On replication v2.1 failover is requested on a per backend basis, so when a
failover request is received by the API it is then redirected to a specific
volume service via an asynchronous RPC call using that service’s topic message
queue.  Same thing happens for freeze and thaw operations.&lt;/p&gt;
&lt;p&gt;It works when we have a one-to-one relation between volume services and storage
backends, but it doesn’t when we have many-to-one relationship because the
failover RPC call will be received by only one of the services that form the
cluster for the storage backend and the others will be oblivious to this change
and will continue using the same replication site they had been using before.
This will result in some operations succeeding, those going to the service that
performed the failover, and some operations failing, since they are going to
the site that’s not available.&lt;/p&gt;
&lt;p&gt;While that’s the primary issue, it’s not the only one, since we also have to
track the replication status at the cluster level.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;Users want to have highly available cinder services with disaster recovery
using replication.&lt;/p&gt;
&lt;p&gt;It is not enough that individual features will be available on their own as
they’ll want to have them both at the same time; so being able to use either
Active-Active configurations without replication, or replication if not
deployed as Active-Active, is insufficient.&lt;/p&gt;
&lt;p&gt;They could probably make it work if they stopped all but one volume services in
the cluster, issued the failover request, and once it has been completed they
brought the other services back up, but this would not be a clean approach to
the problem.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;The proposed change in its core is to divide the failover operation in the
driver into two individual operations, one that will do the side of things
related with the storage backend, for example force promoting volumes to
primary on the secondary site, and another that will make the driver perform
all the operations against the secondary storage device.&lt;/p&gt;
&lt;p&gt;As mentioned before only one volume service will receive the request to do the
failover, so by splitting the operation the manager will be able to request the
local driver to do the first part of the failover and once that is done it will
send all volume nodes in the cluster handling that backend the signal that
the failover has been completed and that they should start pointing to the
failed over secondary site, thus solving the problem of some services not
knowing that a new site should be used.&lt;/p&gt;
&lt;p&gt;This will also require two homonymous RPC calls to the drivers new methods in
the volume manager: &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;failover&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;failover_completed&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;We will also add the replication information to the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;clusters&lt;/span&gt;&lt;/code&gt; table to track
replication at the cluster level for clustered services.&lt;/p&gt;
&lt;p&gt;Given current use of the freeze and thaw operation there doesn’t seem to be a
reason to do the same split, so these operations would be left as they are and
will only be performed by one volume service when requested.&lt;/p&gt;
&lt;p&gt;This change will require vendors to update their drivers to support replication
on Active-Active configurations, so to avoid surprises we will be preventing
the volume service from starting in Active-Active configurations with
replication enabled on drivers that don’t support the Active-Active
mechanism.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;The splitting mechanism for the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;failover_host&lt;/span&gt;&lt;/code&gt; method is pretty straight
forward, the only alternative to the proposed changed would be to split the
thaw and freeze operations as well.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;Three new fields related to the replication will be added to the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;clusters&lt;/span&gt;&lt;/code&gt;
table.  These will be the same fields we currently have in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;services&lt;/span&gt;&lt;/code&gt;
table and will hold the same meaning:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;replication_status&lt;/span&gt;&lt;/code&gt;: String storing the replication status for the whole
cluster.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;active_backend_id&lt;/span&gt;&lt;/code&gt;: String storing which one of the replication sites is
currently active.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;frozen&lt;/span&gt;&lt;/code&gt;: Boolean reflecting whether the cluster is frozen or not.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These fields will be kept in sync between the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;clusters&lt;/span&gt;&lt;/code&gt; table and the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;services&lt;/span&gt;&lt;/code&gt; table for consistency.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;A new action called &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;failover&lt;/span&gt;&lt;/code&gt; equivalent to existing &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;failover_host&lt;/span&gt;&lt;/code&gt;
will be added, and it will support a new &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cluster&lt;/span&gt;&lt;/code&gt; parameter in addition to
the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;host&lt;/span&gt;&lt;/code&gt; field already available in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;failover_host&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cluster listing will accept &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;replication_status&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;frozen&lt;/span&gt;&lt;/code&gt; and
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;active_backend_id&lt;/span&gt;&lt;/code&gt; as filters,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cluster listing will return additional &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;replication_status&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;frozen&lt;/span&gt;&lt;/code&gt; and
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;active_backend_id&lt;/span&gt;&lt;/code&gt; fields.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;The client will return the new fields when listing clusters using the new
microversion and new filters will also be available.&lt;/p&gt;
&lt;p&gt;Failover for this microversion will accept the cluster parameter.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;The new code should have no performance impact on existing deployments since it
will only affect new Active-Active deployments.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Drivers that wish to support replication on Active-Active deployments will have
to implement &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;failover&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;failover_completed&lt;/span&gt;&lt;/code&gt; methods as well as the
current &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;failover_host&lt;/span&gt;&lt;/code&gt; method since it is being used for backward
compatibility with the base replication v2.1.&lt;/p&gt;
&lt;p&gt;The easiest way to support this with minimum code would be to implement
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;failover&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;failover_completed&lt;/span&gt;&lt;/code&gt; and then create &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;failover_host&lt;/span&gt;&lt;/code&gt; based
on those:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;failover_host&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;secondary_id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;failover&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;secondary_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;failover_completed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;secondary_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Gorka Eguileor (geguileo)&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;None&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Change service start to use &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;active_backend_id&lt;/span&gt;&lt;/code&gt; from the cluster or the
service.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add new &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;failover&lt;/span&gt;&lt;/code&gt; REST API&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update list REST API method to accept new filtering fields and update the
view to return new information.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update the DB model and create migration&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Cluster&lt;/span&gt;&lt;/code&gt; Versioned Object&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make modifications to the manager to support the new RPC calls.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;This work has no additional dependency besides the basic Active-Active
mechanism being in place, which it already is.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Only unit tests will be implemented, since there is no reference driver that
implements replication and can be used at the gate.&lt;/p&gt;
&lt;p&gt;We also lack a mechanism to actually verify that the replication is actually
working.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;From a documentation perspective there won’t be much to document besides the
changes related to the API changes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://specs.openstack.org/openstack/cinder-specs/specs/mitaka/cheesecake.html"&gt;Replication v2.1&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Fri, 09 Feb 2018 00:00:00 </pubDate></item><item><title>Cinder Pagination Sorting Enhancements</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/kilo/volume-sorting.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/cinder-pagination"&gt;https://blueprints.launchpad.net/cinder/+spec/cinder-pagination&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Currently, the sorting support for Cinder allows the caller to specify a
single sort key and sort direction. This blueprint enhances the sorting
support for the /volumes and /volumes/detail APIs so that multiple sort keys
and sort directions can be supplied on the request.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;There is no support for retrieving volume data based on multiple sort keys; a
single sort key and direction is currently supported and it is defaulted to
descending sort order by the “created_at” key. In order to retrieve data in
any sort order and direction, the REST APIs need to accept multiple sort keys
and directions.&lt;/p&gt;
&lt;p&gt;Use Case: A UI that displays a table with only the page of data that it
has retrieved from the server. The items in this table need to be sorted
by status first and by display name second. In order to retrieve data in
this order, the APIs must accept multiple sort keys/directions.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;The /volumes and /volumes/detail APIs will align with the API working group
guidelines (see References section) for sorting and support the following
parameter on the request:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;sort: Comma-separated list of sort keys, each key is optionally appended
with &amp;lt;:dir&amp;gt;, where ‘dir’ is the direction for the corresponding sort key
(supported values are ‘asc’ for ascending and ‘desc’ for descending)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For example:
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/volumes?sort=status:asc,display_name:asc,created_at:desc&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Note: The “created_at” and “id” sort keys are always appended at the end of
the key list if they are not already specified on the request.&lt;/p&gt;
&lt;p&gt;The database layer already supports multiple sort keys and directions. This
blueprint will update the API layer to retrieve the sort information from
the API request and pass that information down to the database layer.&lt;/p&gt;
&lt;p&gt;All sorting is handled in the cinder.common.sqlalchemyutils.paginate_query
function.  This function accepts an ORM model class as an argument and the
only valid sort keys are attributes on the given model class.  Therefore,
the valid sort keys are limited to the model attributes on the
models.Volume class.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Multiple sort keys and directions could be passed using repeated ‘sort_key’
and ‘sort_dir’ query parameters. For example:&lt;/p&gt;
&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/volumes?sort_key=status&amp;amp;sort_dir=asc&amp;amp;sort_key=display_name&amp;amp;sort_dir=asc&amp;amp;&lt;/span&gt;
&lt;span class="pre"&gt;sort_key=created_at&amp;amp;sort_dir=desc&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;However, this is not aligned with the API sorting guidelines.&lt;/p&gt;
&lt;p&gt;Also, this additional sorting could be conditionally enabled based on the
existence of a new extension; however, since sorting by a single key is
already supported, then a new extension may not be needed to enhance this
support to multiple keys/directions. However, an extension could be created
if necessary.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;The following existing v2 GET APIs will support the new sorting parameters:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;/v2/{tenant_id}/volumes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;/v2/{tenant_id}/volumes/detail&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Note that the design described in this blueprint could be applied to other GET
REST APIs but this blueprint is scoped to only those listed above. Once this
design is finalized, then the same approach could be applied to other APIs.&lt;/p&gt;
&lt;p&gt;The existing API documentation needs to be updated to include the following
new Request Parameters:&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Parameter&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Style&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;sort&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;query&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Comma-separated list of sort keys and optional
sort directions in the form of key&amp;lt;:dir&amp;gt;,
where ‘dir’ is either ‘asc’ for ascending
order or ‘desc’ for descending order. Defaults
to the ‘created_at’ and ‘id’ keys in
descending order.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Currently, the volumes query supports the ‘sort_key’ and ‘sort_dir’ parameters;
these will be deprecated. The API will raise a “badRequest” error response
(code 400) if both the new ‘sort’ parameter and a deprecated ‘sort_key’ or
‘sort_dir’ parameter is specified.&lt;/p&gt;
&lt;p&gt;Neither the API response format nor the return codes will be modified, only
the order of the volumes that are returned.&lt;/p&gt;
&lt;p&gt;In the event that an invalid sort key is specified then a “badRequest” error
response (code 400) will be returned with a message like “Invalid input
received: Invalid sort key”.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;The cinderclient should be updated to accept sort keys and sort directions,
using the ‘sort’ parameter being proposed in the cross-project spec:
&lt;a class="reference external" href="https://review.openstack.org/#/c/145544/"&gt;https://review.openstack.org/#/c/145544/&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;All sorting will be done in the database. The choice of sort keys is limited
to attributes on the models.Volume ORM class – not every attribute key
returned from a detailed query is a valid sort key.&lt;/p&gt;
&lt;p&gt;Performance data was gathered by running on a simple devstack VM with 2GB
memory. 5000 volumes were inserted into the DB. The data shows that the
sort time on the main data table is dwarfed (see first table below) when
running a detailed query – most of the time is spent querying the other
tables for each item; therefore, the impact of the sort key on a detailed
query is minimal.&lt;/p&gt;
&lt;p&gt;For example, the data below compares the processing time of a GET request for
a non-detailed query to a detailed query with various limits using the default
sort keys. The purpose of this table is to show the processing time for a
detailed query is dominated by getting the additional details for each item.&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Limit&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Non-Detailed (sec)&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Detailed (sec)&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Non-Detailed / Detailed %&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;50&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0.0560&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0.8621&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;6.5%&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;100&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0.0813&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;1.6839&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;4.8%&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;150&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0.0848&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;2.4705&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;3.4%&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;200&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0.0874&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;3.2502&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;2.7%&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;250&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0.0985&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;4.1237&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;2.4%&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;300&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0.1229&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;4.8731&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;2.5%&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;350&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0.1262&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;5.6366&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;2.2%&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;400&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0.1282&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;6.5573&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;2.0%&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;450&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0.1458&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;7.2921&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;2.0%&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;500&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0.1770&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;8.1126&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;2.2%&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;1000&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0.2589&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;16.0844&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;1.6%&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Non-detailed query data was also gathered. The table below compares the
processing time using default sort keys to the processing using display_name
as the sort key. Items were added with a 40 character display_name that was
generated in an out-of-alphabetical sort order.&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Limit&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Default keys (sec)&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;display_name key (sec)&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Slowdown %&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;50&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0.0560&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0.0600&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;7.1%&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;100&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0.0813&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0.0832&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;2.3%&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;150&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0.0848&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0.0879&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;3.7%&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;200&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0.0874&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0.0906&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;3.7%&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;250&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0.0985&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0.1031&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;4.7%&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;300&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0.1229&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0.1198&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;-2.5%&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;350&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0.1262&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0.1319&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;4.5%&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;400&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0.1282&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0.1368&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;6.7%&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;450&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0.1458&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0.1458&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0.0%&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;500&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0.1770&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0.1619&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;-8.5%&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;1000&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0.2589&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0.2659&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;2.7%&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;In conclusion, the sort processing on the main data table has minimal impact
on the overall processing time. For a detailed query, the sort time is dwarfed
by other processing – even if the sort time when up 3x it would only
represent 4.8% of the total processing time for a detailed query with a limit
of 1000 (and only increase the processing time by .11 sec with a limit of 50).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;The choice of sort keys has a minimal impact on data retrieval performance
(see performance data above). Therefore, the user should be allowed to
retrieve data in whatever order they need to for creating their views (see
use case in the Problem Description).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;kaufer (&lt;a class="reference external" href="mailto:kaufer%40us.ibm.com"&gt;kaufer&lt;span&gt;@&lt;/span&gt;us&lt;span&gt;.&lt;/span&gt;ibm&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;)&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;None&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;Ideally the logic for processing the sort parameters would be common to all
components and would be done in oslo; a similar blueprint is also being
proposed in nova:
&lt;a class="reference external" href="https://blueprints.launchpad.net/nova/+spec/nova-pagination"&gt;https://blueprints.launchpad.net/nova/+spec/nova-pagination&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Therefore, I see the following work items:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Duplicate the common code being proposed in nova to process the sort
parameters, see &lt;a class="reference external" href="https://review.openstack.org/#/c/95260/"&gt;https://review.openstack.org/#/c/95260/&lt;/a&gt;. Once both projects
are using the same code then it should be moved into oslo.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update the API to retrieve the sort information and pass down to the
DB layer (requires changes to volume/api.py, db/api.py, and
db/sqlalchemy/api.py)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update the cinderclient to accept and process multiple sort keys and sort
directions&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Related (but independent) change being proposed in nova:
&lt;a class="reference external" href="https://blueprints.launchpad.net/nova/+spec/nova-pagination"&gt;https://blueprints.launchpad.net/nova/+spec/nova-pagination&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CLI Sorting Argument Guidelines cross project spec:
&lt;a class="reference external" href="https://review.openstack.org/#/c/145544/"&gt;https://review.openstack.org/#/c/145544/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Both unit and Tempest tests need to be created to ensure that the data is
retrieved in the specified sort order. Tests should also verify that the
default sort keys (“created_at” and “id”) are always appended to the user
supplied keys (if the user did not already specify them).&lt;/p&gt;
&lt;p&gt;Testing should be done against multiple backend database types.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;The /volumes and /volumes/detail API documentation will need to be updated
to:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Reflect the new sorting parameters and explain that these parameters will
affect the order in which the data is returned.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Explain how the default sort keys will always be added at the end of the
sort key list&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The documentation could also note that query performance will be affected by
the choice of the sort key, noting which keys are indexed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;API Working group sorting guidelines:
&lt;a class="reference external" href="https://github.com/openstack/api-wg/blob/master/guidelines/"&gt;https://github.com/openstack/api-wg/blob/master/guidelines/&lt;/a&gt;
pagination_filter_sort.rst&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Tue, 06 Feb 2018 00:00:00 </pubDate></item><item><title>Volume Migration Improvement</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/liberty/volume-migration-improvement.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/migration-improvement"&gt;https://blueprints.launchpad.net/cinder/+spec/migration-improvement&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This specification proposes to improve the current volume migration in terms
of implementing a better way to manage the volume migration status,
adding the migration progress indication, enriching the notification system via
reporting to Ceilometer, guaranteeing the migration quality via tempest tests
and CI support, etc. It targets to resolve the current issues for the available
volumes only, since we need to wait until the multiple attached volume
functionality lands in Nova to resolve the issues related to the attached
volumes. There is going to be another specification designed to cover the
issues regarding the attached volumes.&lt;/p&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;Having the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;well&lt;/span&gt; &lt;span class="pre"&gt;defined&lt;/span&gt;&lt;/code&gt; capabilities will allow the deployer to see what
common capabilities are shared beyond their deployed backends in Cinder.&lt;/p&gt;
&lt;p&gt;There are three cases for volume migration. The scope of this spec is for the
available volumes only and targets to resolve the issues within the following
migration Case 1 and 2:&lt;/p&gt;
&lt;p&gt;Within the scope of this spec
1) Available volume migration using the “dd” command.
For example, migration from LVM to LVM, between LVM and vendor driver, and
between different vendor drivers.&lt;/p&gt;
&lt;p&gt;2) Available volume migration between two pools from the same vendor driver
using driver-specific way. Storwize is taken as the reference example for this
spec.&lt;/p&gt;
&lt;p&gt;Out of the scope of the spec
3) In-use(attached) volume migration using Cinder generic migration.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently, there are quite some straightforward issues about the volume
migration.
1. Whether the migration succeeds or fails is not saved anywhere, which is very
confusing for the administrator. The volume status is still available or
in-use, even if the administrator mentions –force as a flag for cinder migrate
command.
2. From the API perspective, the administrator is unable to check the status of
the migration. The only way to check if the migration fails or succeeds is
to check the database.
3. During the migration, there are two volumes appearing in the database record
via the check by “cinder list” command. One is the source volume and one is the
destination volume. The latter is actually useless to show and leads to
confusion for the administrator.
4. When executing the command “cinder migrate”, most of the time there is
nothing returned to the administrator from the terminal, which is unfriendly
and needs to be improved.
5. It is probable that the migration process takes a long time to finish.
Currently the administrator gets nothing from the log about the progress of the
migration.
6. Nothing reports to the Ceilometer.
7. There are no tempest test cases and no CI support to make sure the migration
truly works for any kind of drivers.&lt;/p&gt;
&lt;p&gt;We propose to add the management of the migration status to resolve
issues 1 to 4, add the migration progress indication to cover Issue 5, add
the notification to solve Issue 6 and add tempest tests and CI support to
tackle Issue 7.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;At the beginning, we declare that all the changes and test cases are dedicated
to available volumes. For the attached volumes, we will wait until the multiple
attached volume functionality get merged in Nova.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Management of the volume migration status:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If the migration fails, the migration status is set to “error”. If the
migration succeeds, the migration status is set to “success”. If no migration
is ever done for the volume, the migration status is set to None. The migration
status is used to record the result of the previous migration. The migration
status can be seen by the administrator only.&lt;/p&gt;
&lt;p&gt;The administrator has several ways to check the migration status:
1) The administrator can do a regular “volume list” with a filter
“migration_status=&amp;lt;expected volume migration status&amp;gt;” to find all the volumes
with the specified migration status. If no filter is specified, all the volumes
will list the migration status.
2) The administrator can issue a “get” command for a certain volume and the
migration status can be found in the field ‘os-vol-mig-status-attr:migstat’.&lt;/p&gt;
&lt;p&gt;If the administrator issues the migrate command with the –force flag, the
volume status will be changed to ‘maintenance’. Attach or detach will not be
allowed during migration. If the administrator issues the migrate command
without the –force flag, the volume status will remain unchanged. Attach or
detach action issued during migration will abort the migration. The status
‘maintenance’ can be extended to use in any other situation, in which the
volume service is not available due to any kinds of reasons.&lt;/p&gt;
&lt;p&gt;We plan to provide more information when the administrator is running
“cinder migrate” command. If the migration is able to start, we return a
message “Your migration request has been received. Please check migration
status and the server log to see more information.” If the migration is
rejected by the API, we shall return messages like “Your migration request
failed to process due to some reasons”.&lt;/p&gt;
&lt;p&gt;We plan to remove the redundant information for the dummy destination volume.
If Cinder Internal Tenant(&lt;a class="reference external" href="https://review.openstack.org/#/c/186232/"&gt;https://review.openstack.org/#/c/186232/&lt;/a&gt;) is
successfully implemented, we will apply that patch to hide the destination
volume.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Migration progress indication:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We would like to introduce a poll mechanism to check the migration progress in
a certain interval as the implementation for the migration progress indication.
The poll mechanism can be realized in a loop, and the migration progress will
be checked in a certain interval, which is configurable in cinder.conf. This
mechanism can be running in parallel to the volume migration.&lt;/p&gt;
&lt;p&gt;If the volume copy starts, another thread for the migration progress check will
start as well. If the volume copy ends, the thread for the migration progress
check ends.&lt;/p&gt;
&lt;p&gt;A driver capability named migration_progress_report can be added to each
driver.
It is either True or False. This is for the case that volumes are migrated
from one pool to another within the same storage back-end. If it is True, the
loop for the poll mechanism will start. Otherwise, no poll mechanism will
start.&lt;/p&gt;
&lt;p&gt;A configuration option named migration_progress_report_interval can be added
into cinder.conf, specifying how frequent the migration progress needs to be
checked. For example, if migration_progress_report_interval is set to
30 seconds, the code will check the migration progress and report it every
30 seconds.&lt;/p&gt;
&lt;p&gt;If the volume is migrated using dd command, e.g. volume migration from LVM to
LVM, from LVM to vendor driver, from one back-end to another via blockcopy,
etc, the migration progress can be checked via the position indication of
/proc/&amp;lt;PID&amp;gt;/fdinfo/1.&lt;/p&gt;
&lt;p&gt;For the volume is migrated using file I/O, the current file pointer is able to
report the position of the transferred data. The migration progress can be
checkedvia this position relative to EOF.&lt;/p&gt;
&lt;p&gt;If the volume is migrated within different pools of one back-end, we would like
to implement this feature by checking the stats of the storage back-end.
Storwize V7000 is taken as the reference implementation about reporting the
migration progress. It is possible that some drivers support the progress
report and some do not. A new key “migration_progress_report” will be added
into the driver to report the capability. If the back-end driver supports to
report the migration progress, this key is set to True. Otherwise, this key is
set to False and the progress report becomes unsupported in this case.&lt;/p&gt;
&lt;p&gt;The migration progress can be checked by the administrator only. Since the
progress is not stored, each time the progress is queried from the API, the
request will be scheduled to the cinder-volume service, which can get the
updated migration progress for a specified volume and reports back.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;We can definitely use a hidden flag to indicate if a database row is displayed
or hidden. However, cinder needs a consistent way to resolve other issues like
image cache, backup, etc, we reach an agreement that cinder internal tenant is
the approach to go.&lt;/p&gt;
&lt;p&gt;The purpose that we plan to have a better management of the volume migration
status, add migration progress indication, report the stats to Ceilometer and
provide tempest tests and CI, is simply to guarantee the migration works in a
more robust and stable way.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;The REST API should be able to provide the migration status and the migration
progress information for the volumes. For the migration status, it can be
retrieved from the database. For the migration progress, the API request
will be scheduled to the cinder volume service, where the volume is located,
and cinder volume service reports the updated progress back.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;The volume migration should send notification to Ceilometer about the start,
and the progress and the finish.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;If the back-end driver supports the migration progress indication, a new
configuration option migration_progress_report_interval can be added. The
administrator can decide how frequent the cinder volume service to report the
migration progress. For example, if migration_progress_report_interval is set
to 30 seconds, the cinder volume service will provide the progress information
every 30 seconds.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;The driver maintainer or developer should be aware that they need to add a new
capability to indicate whether their driver support the progress report.
If yes, they need to implement the related method, to be provided in the
implementation of this specification.&lt;/p&gt;
&lt;p&gt;If their drivers have implemented volume migration, integration tests and
driver CI are important to ensure the quality. This is something they need to
pay attention and implement for their drivers as well.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Vincent Hou (&lt;a class="reference external" href="mailto:sbhou%40cn.ibm.com"&gt;sbhou&lt;span&gt;@&lt;/span&gt;cn&lt;span&gt;.&lt;/span&gt;ibm&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;)&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Jay Bryant
Jon Bernard&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Management of the volume migration status:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;1) Change the migration_status to “error” if the migration fails; Change the
migration_status to “success” if the migration succeeds.
2) Change the volume status to “maintenance” if the administrator executes
the migration command with –force flag. No attach or detach is allowed during
this migration. If the administrator executes the migration command without
–force flag, the volume status will stay unchanged. Attach or detach during
migration will terminate the migration to ensure the availability of
the volume.
3) Enrich cinderclient with friendly messages returned for cinder migrate and
retype command.
4) Hide the redundant dummy destination volume during migration.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Migration progress indication:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Add a loop to wrap the implementation of the poll mechanism.&lt;/p&gt;
&lt;p&gt;The driver, which supports the migration progress report, will set
migration_progress_report to True. Otherwise, set it to False.&lt;/p&gt;
&lt;p&gt;The option migration_progress_report_interval will be used to specify the time
interval, in which the migration progress is checked.&lt;/p&gt;
&lt;p&gt;1) If the volume is migrated between LVM back-ends, or one back-end to another,
the position indication of /proc/&amp;lt;PID&amp;gt;/fdinfo/1 can be checked to get the
progress of the blockcopy.&lt;/p&gt;
&lt;p&gt;2) If the volume is migrated within different pools of one back-end, we would
like to check the progress report of the back-end storage in a certain time
interval.&lt;/p&gt;
&lt;p&gt;The migration percentage will be logged and reported to Ceilometer.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Notification:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Add the code to send the start, progress and end to Ceilometer during
migration.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Tempest tests and CI support:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This work item is planned to finish in two steps. The first step is called
manual mode, in which the tempest tests are ready and people need to configure
the OpenStack environment manually to meet the requirements of the tests.&lt;/p&gt;
&lt;p&gt;The second step is called automatic mode, in which the tempest tests can run
automatically in the gate. With the current state of OpenStack infrastructure,
it is only possible for us to do the manual mode. The automatic mode needs to
collaboration with OpenStack-infra team and there is going to be a blueprint
for it.&lt;/p&gt;
&lt;p&gt;The following cases will be added:
1) From LVM(thin) to LVM(thin)
2) From LVM(thin) to Storwize
3) From Storwize to LVM(thin)
4) From Storwize Pool 1 to Storwize Pool 2&lt;/p&gt;
&lt;p&gt;Besides, RBD driver is also going to provide the similar test cases from (2)
to (4) as above.&lt;/p&gt;
&lt;p&gt;We are sure that other drivers can get involved into the tests. This
specification targets to add the test cases for LVM, Storwize and RBD drivers
as the initiative. We hope other drivers can take the implementation of LVM,
Storwize and RBD as a reference in future.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Documentation:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Update the manual for the administrators, and the development reference for
the driver developers and maintainers.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;Cinder Internal Tenant: &lt;a class="reference external" href="https://review.openstack.org/#/c/186232/"&gt;https://review.openstack.org/#/c/186232/&lt;/a&gt;
Add support for file I/O volume migration:
&lt;a class="reference external" href="https://review.openstack.org/#/c/187270/"&gt;https://review.openstack.org/#/c/187270/&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Depending on ability to parse the required information for the LVM driver, the
following scenarios for available volumes will taken into account:
1) Migration using Cinder generic migration with LVM(thin) to LVM(thin).
2) Migration using Cinder generic migration with LVM(thin) to vendor driver.
3) Migration using Cinder generic migration with vendor driver to LVM(thin).
4) Migration between two pools from the same vendor driver using
driver-specific way.&lt;/p&gt;
&lt;p&gt;There are some other scenarios, but for this release we plan to consider the
above.
For scenarios 1 to 3, we plan to put tests cases into Tempest.
For Scenario 4, we plan to put the test into CI.
The reference case for Scenario 2 is migration from LVM to Storwize V7000.
The reference case for Scenario 3 is migration from Storwize V7000 to LVM.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Documentation should be updated to tell the administrator how to use the
migrate and retype command. Describe what commands work for what kind of use
cases, how to check the migration status, how to configure and check
the migration indication, etc.&lt;/p&gt;
&lt;p&gt;Reference will be updated to tell the driver maintainers or developers how to
change their drivers to adapt this migration improvement via the link
&lt;a class="reference external" href="http://docs.openstack.org/developer/cinder/devref/index.html"&gt;http://docs.openstack.org/developer/cinder/devref/index.html&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/migration-improvement"&gt;https://blueprints.launchpad.net/cinder/+spec/migration-improvement&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://etherpad.openstack.org/p/volume-migration-improvement"&gt;https://etherpad.openstack.org/p/volume-migration-improvement&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Tue, 06 Feb 2018 00:00:00 </pubDate></item><item><title>Assisted Snapshot Improvements</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/mitaka/assisted_snapshot_improvements.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/assisted-snapshot-improvements"&gt;https://blueprints.launchpad.net/cinder/+spec/assisted-snapshot-improvements&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This spec aims to improve the infrastructure used to coordinate
between Cinder and Nova for volume snapshots.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;The update_snapshot_status API is used to update fields in the Cinder
database which the driver performing a snapshot delete uses to determine
when Nova’s part is finished and the Cinder driver can take over again.&lt;/p&gt;
&lt;p&gt;This currently overloads the ‘progress’ field of the snapshot to
carry information from the API layer to the driver.  This is hacky and
should be reworked as more drivers are interested in supporting
assisted snapshots.&lt;/p&gt;
&lt;p&gt;This work will also assist in supporting proper transitions between
different phases of the snapshot create/delete process.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;NA.
There is no user/deployer impact as this is a internal only change.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;section id="api-volume-service-interaction"&gt;
&lt;h3&gt;API&amp;lt;-&amp;gt;Volume service interaction&lt;/h3&gt;
&lt;p&gt;Establish a snapshot_admin_metadata table which is similar to the
volume_admin_metadata table:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;primary&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;volume_id&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="n"&gt;ref&lt;/span&gt; &lt;span class="n"&gt;volumes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;volume&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;relationship&lt;/span&gt; &lt;span class="n"&gt;joining&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;volumes&lt;/span&gt; &lt;span class="n"&gt;table&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Setting a snapshot_status metadata value will allow the API layer
to transfer this information to the volume service.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="volume-manager-driver-interaction"&gt;
&lt;h3&gt;Volume manager&amp;lt;-&amp;gt;driver interaction&lt;/h3&gt;
&lt;p&gt;Split the assisted snapshot processing code out of the driver
(currently RemoteFS-based) and into the volume manager.
This will allow drivers that support assisted snapshots to have a
call for each stage, rather than only a single delete_snapshot call.&lt;/p&gt;
&lt;p&gt;The driver will have a property indicating it supports assisted
snapshots, which triggers use of the following methods in the manager
instead of the manager calling the driver’s create_snapshot:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;create_snapshot_assisted_begin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;snapshot_ref&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;create_snapshot_assisted_complete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;snapshot_ref&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;delete_snapshot_assisted_begin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;snapshot_ref&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;delete_snapshot_assisted_complete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;snapshot_ref&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Each of these calls can return a dict of fields to be updated for the
snapshot and/or snapshot_admin_metadata by the volume manager.&lt;/p&gt;
&lt;p&gt;This will move some database accesses currently done in the driver
to the volume manager, as well as better allowing support for defined
state transitions between the Nova and Cinder phases.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Leave things as they are today, which may lead to a less robust/maintainable
infrastructure for assisted snapshots.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;Create new snapshot_admin_metadata table as described above.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;update_snapshot_status() API will look for a new ‘compute_snapshot_status’
field which will be used to populate the snapshot_admin_metadata entry.&lt;/p&gt;
&lt;p&gt;If this field is not present, it will use the ‘progress’ field as before
for compatibility.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None, interactions in and out of Cinder expose the same information
and level of access as today.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;Cinder will remain backward compatible with Liberty Nova for the APIs
being modified here.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;New interfaces for drivers for creating and deleting snapshots assisted
by the compute service.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;deepakcs&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;None&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add processing to update_snapshot_status API for new fields&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add new fields to the update_snapshot_status call made by Nova&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add processing in snapshot-tracking code for the new compute_progress field&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create new driver interfaces in the volume manager&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Migrate RemoteFS snapshot infrastructure to the new interfaces for the
RemoteFSSnapDriver class.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Have Nova send new fields for update_snapshot_status API calls
&lt;a class="reference external" href="https://review.openstack.org/#/c/134517/"&gt;https://review.openstack.org/#/c/134517/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;This will be covered by CI for GlusterFS, the NFS driver (once snapshots
are added to it in Mitaka), and CI for other RemoteFS drivers.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Nova change: &lt;a class="reference external" href="https://review.openstack.org/#/c/134517/"&gt;https://review.openstack.org/#/c/134517/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Tue, 06 Feb 2018 00:00:00 </pubDate></item><item><title>RBD Volume Encryption</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/queens/rbd-encryption.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/nova/+spec/libvirt-qemu-native-luks"&gt;https://blueprints.launchpad.net/nova/+spec/libvirt-qemu-native-luks&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This feature adds support to the Cinder RBD volume driver
to support Cinder’s volume encryption.&lt;/p&gt;
&lt;p&gt;This requires a few changes in Cinder and Nova due to the fact that
RBD volumes are attached by qemu directly and not as block devices
on the host.&lt;/p&gt;
&lt;p&gt;This fills a feature gap for the RBD driver in Cinder.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;The RBD driver does not support volume encryption.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;Volume encryption is a common requirement for deployments,
particularly where a deployer needs to meet particular security
standards.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Enable volume encryption for RBD via qemu’s LUKS block layer.&lt;/p&gt;
&lt;p&gt;This means that Nova has to support libvirt operations to manage
this qemu feature.  This is done here:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/523958/"&gt;https://review.openstack.org/#/c/523958/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We also need Cinder to format volumes upon creation with a LUKS
header.  This is currently done by os-brick for iSCSI drivers,
but can’t be done in the same way for RBD since there is no
block device on the compute host, and dm-crypt is not used.&lt;/p&gt;
&lt;p&gt;(Note: this will also be true when using qemu’s iSCSI initiator
with Nova)&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;This is a security-focused feature, but it uses the already existing
infrastructure of Cinder volume encryption.&lt;/p&gt;
&lt;p&gt;The way encryption works when using RBD is slightly different from
other Cinder drivers.  Decryption/encryption is handled inside of
qemu rather than at the device-mapper layer on the host via dm-crypt.&lt;/p&gt;
&lt;p&gt;This means fewer operations having to be run as root, and less exposure
of decrypted data to the rest of the system via block devices.&lt;/p&gt;
&lt;p&gt;But, the feature in general has the same security implications as
cinder volume encryption does for other drivers.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Using encryption could result in slightly higher CPU usage on compute
nodes.  Should be comparable to using encryption with any other Cinder
driver.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;eharney&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;lyarwood&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/534811/"&gt;https://review.openstack.org/534811/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/523958/"&gt;https://review.openstack.org/523958/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Nova changes here:
- &lt;a class="reference external" href="https://blueprints.launchpad.net/nova/+spec/libvirt-qemu-native-luks"&gt;https://blueprints.launchpad.net/nova/+spec/libvirt-qemu-native-luks&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;QEMU 2.6&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;libvirt 2.2.0&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;This feature will be covered by the standard tempest tests used for all
volume drivers.&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Gate configuration issues are being sorted out here:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/536350/"&gt;https://review.openstack.org/#/c/536350/&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Document that volume encryption now works for the RBD volume driver&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Current limitation: attached volume migration is not supported&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/q/topic:bp/libvirt-qemu-native-luks"&gt;https://review.openstack.org/#/q/topic:bp/libvirt-qemu-native-luks&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/nova/+spec/libvirt-qemu-native-luks"&gt;https://blueprints.launchpad.net/nova/+spec/libvirt-qemu-native-luks&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://lists.openstack.org/pipermail/openstack-dev/2018-January/126440.html"&gt;http://lists.openstack.org/pipermail/openstack-dev/2018-January/126440.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Wed, 31 Jan 2018 00:00:00 </pubDate></item><item><title>Provisioning Improvements</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/queens/provisioning-improvements.html</link><description>

&lt;p&gt;Include the URL of your launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/provisioning-improvements"&gt;https://blueprints.launchpad.net/cinder/+spec/provisioning-improvements&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Cinder provisioning is still a source of pain for everyone: end users, admins,
and developers.  Multiple factors have contributed to our current situation,
like the information being dispersed in different specs, developer’s reference,
and even the code, but we also have cases of misinterpreted documentation,
documentation not keeping up with the project’s evolution, and even misleading
or incorrect documentation.&lt;/p&gt;
&lt;p&gt;This spec will build on those that preceded it on the same topic &lt;a class="footnote-reference brackets" href="#id6" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; &lt;a class="footnote-reference brackets" href="#id7" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; and
others related to the subject &lt;a class="footnote-reference brackets" href="#id8" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; to bring a consolidated and updated view on
the matter as well as add a some minor improvements and fix some issues in
hopes that we can provide a better experience for all involved.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Our current situation is quite chaotic, we have volume creations that fail
based on an incorrect capacity calculation that would have succeeded if we had
just received an update on the stats of the backend, we have drivers that are
reporting incorrect data on the stats, and we have volumes that cannot be
created when they should be allowed to.&lt;/p&gt;
&lt;p&gt;Before going any further we first need to define the terms we’ll be using to
ensure they hold the same meaning for all of us, as this is the source of some
of our current issues.&lt;/p&gt;
&lt;p&gt;Disagreement on the mapping of these terms and their description is
understandable, but for the sake of understanding each other we’ll hold below
descriptions as true since they were defined as such in our specs and most of
our code.&lt;/p&gt;
&lt;p&gt;Improvements on the word used for the terms and field names can be discussed at
another time and updated in the specs, documentation, and code accordingly.&lt;/p&gt;
&lt;p&gt;For the sake of completeness and to remove any misunderstandings that could
lead to different implementations on the drivers, which we currently have, the
descriptions will also include some clarifications and examples that may
reference current Cinder code.&lt;/p&gt;
&lt;section id="terminology"&gt;
&lt;h3&gt;Terminology&lt;/h3&gt;
&lt;dl&gt;
&lt;dt&gt;GB:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Even though this is formally known as the symbol representation of a gigabyte
-decimal unit of measurement- we will be using it throughout the spec and our
code as the symbol for the gibibyte -binary unit of measurement as defined by
the International Electrotechnical Commission (IEC), with symbol GiB-, so
when we talk about 1GB we are talking about 1024MB, and the same applies to
TB and MB.&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Total capacity:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;It is the total physical capacity that would be available in the storage
array’s pool being used by Cinder if no volumes were present.&lt;/p&gt;
&lt;p&gt;This is currently being reported by the drivers as &lt;cite&gt;total_capacity_gb&lt;/cite&gt; and,
as the name indicates, should be reported in GB and with a precision no
greater than 2 decimals.&lt;/p&gt;
&lt;p&gt;If the storage array has 5TB of space but the pool used in Cinder is limited
to 1TB then the driver should be reporting a &lt;cite&gt;total_capacity_gb&lt;/cite&gt; of 1024GB.&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Volume size:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;It is the maximum physical size that a volume can take in the storage array.&lt;/p&gt;
&lt;p&gt;This is referenced throughout the code as &lt;cite&gt;volume_size&lt;/cite&gt;.&lt;/p&gt;
&lt;p&gt;For a thick volume the &lt;cite&gt;volume_size&lt;/cite&gt; will be the same as the free capacity we
lost when it was provisioned, whereas for a thin volume it will be greater
than the space used for the volume in the storage array until the volume gets
completely full.&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Free capacity:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;It is the current physical capacity available in the storage array’s pool
being used by Cinder.  The number and volume sizes of the thin and thick
volumes that have been provisioned by Cinder or directly in the storage array
are irrelevant here.&lt;/p&gt;
&lt;p&gt;This is currently being reported by the drivers as &lt;cite&gt;free_capacity_gb&lt;/cite&gt; and, as
the name indicates, should be reported in GB and with a precision no greater
than 2 decimals.&lt;/p&gt;
&lt;p&gt;If the storage array has 5TB of space with a total of 3TB available for all
its pools but Cinder is using a pool that has a limit of 1TB of which it has
already used 400GB and someone has manually created volumes outside of Cinder
that are currently using 124GB of space, then the driver should be reporting
a &lt;cite&gt;free_capacity_gb&lt;/cite&gt; of 500GB (1TB = 1024GB = 400GB + 124GB + 500GB).&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Provisioned capacity:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;The amount of capacity that would be used in the storage array’s pool being
used by Cinder if all the volumes present in there were completely full.&lt;/p&gt;
&lt;p&gt;This is currently being reported by the drivers as &lt;cite&gt;provisioned_capacity_gb&lt;/cite&gt;
and, as the name indicates, should be reported in GB and with a precision no
greater than 2 decimals.  This is a required field and &lt;em&gt;must always be
present&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;This includes not only volumes created by Cinder but also all other existing
volumes in that backend, but &lt;em&gt;does not include snapshots&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Let’s expand the earlier example from “free capacity” where 524GB of the
available 1TB had already been used, and say that the 124GB that were
externally created were all used by 1GB thick volumes, and that Cinder was
using the 400GB with 400 thick volumes of 1GB and 20 empty thin volumes of
20GB each.  In this situation our reported &lt;cite&gt;provisioned_capacity_gb&lt;/cite&gt; value
should be 924GB ((124 * 1GB) + (400 * 1GB) + (20 * 20GB)).&lt;/p&gt;
&lt;p&gt;If a driver does not report the &lt;cite&gt;provisioned_capacity_gb&lt;/cite&gt; data we’ll use the
automatically calculated &lt;cite&gt;allocated_capacity_gb&lt;/cite&gt; as described below.&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Allocated capacity:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Contrary to what the name may suggest this is not referring to the
“allocated” space on the storage array, but to the provisioned volumes
created by this specific Cinder Volume backend process on the storage array’s
pool being used by Cinder and that still present.&lt;/p&gt;
&lt;p&gt;Important to notice that this refers to a specific service backend, so if you
are running a multi-backend Cinder service or multiple Cinder Volume services
where you have more than one backend configured to use the same storage
array’s pool, then each one of these backends will only be reporting the
sum of the &lt;cite&gt;volume_size&lt;/cite&gt; of the volumes they created and not the sum of all
the &lt;cite&gt;volume_size&lt;/cite&gt; of the volumes that have been created by a Cinder service.&lt;/p&gt;
&lt;p&gt;This is currently being reported by the Volume service as
&lt;cite&gt;allocated_capacity_gb&lt;/cite&gt; and, as the name indicates, should be reported in GB.&lt;/p&gt;
&lt;p&gt;For two volumes had been created, one thick and one thin, each one of 1GB,
then you’ll be reporting 2GB as &lt;cite&gt;allocated_capacity_gb&lt;/cite&gt;, but if you were to
unmanage one of those volumes then you would only be reporting 1GB, even if
the volume is still there and will still be counted in the
&lt;cite&gt;provisioned_capacity_gb&lt;/cite&gt;.&lt;/p&gt;
&lt;p&gt;This field is calculated directly by the Cinder core code and drivers should
not calculate or report this information on their &lt;cite&gt;get_volume_stats&lt;/cite&gt; method.&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Over subscription ratio:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;It is the maximum ratio between the “provisioned capacity” and the “total
capacity” represented as a real number.  A ratio of 1.0 means that the
“provisioned capacity” cannot exceed the “total capacity” whereas a value of
5.0 means that the Cinder backend is allowed to create as much as 5 times the
“total capacity” of the storage array’s pool in volumes.&lt;/p&gt;
&lt;p&gt;This will only have effect when a thin provisioned volume is being created,
and will be ignored for thick provisioned.&lt;/p&gt;
&lt;p&gt;This is currently being reported by the drivers as
&lt;cite&gt;max_over_subscription_ratio&lt;/cite&gt; with a greater or equal value to 1.0,
preferably with no more than a 2 decimal precision.&lt;/p&gt;
&lt;p&gt;This value is optional, and when missing from the driver’s status report the
value defined in the &lt;cite&gt;[DEFAULT]&lt;/cite&gt; section on the Cinder scheduler receiving
the request will be used.  So vendors should make sure that they are
correctly returning this value in their drivers if they support thin
provisioning and admins should make sure they have a consistent default value
of the &lt;cite&gt;max_over_subscription_ratio&lt;/cite&gt; across all scheduler nodes.&lt;/p&gt;
&lt;p&gt;Note that this ratio is per backend or per pool depending on driver
implementation.&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Reserved percentage:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Represents the percentage of the storage array’s “total capacity” that is
reserved and should not be used for calculations.  It is represented by an
integer value going from 0 up to 100.&lt;/p&gt;
&lt;p&gt;This is currently being reported by the drivers as
&lt;cite&gt;reserved_percentage&lt;/cite&gt; with a greater or equal value to 1.0, preferably
with no more than a 2 decimal precision.&lt;/p&gt;
&lt;p&gt;Default value is 0 if the field is missing in the status report from the
backend or if the user has not defined it in the backend’s Cinder
configuration.  This is per backend or per pool depending on driver
implementation.&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Provisioning support:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Cinder backends may support up to two different types of provisioning, &lt;em&gt;thin&lt;/em&gt;
and &lt;em&gt;thick&lt;/em&gt; and drivers are expected to indicate as capable of one of them at
least in their capabilities report.&lt;/p&gt;
&lt;p&gt;The way to report support for these is setting to true the boolean fields
&lt;cite&gt;thin_provisioning_support&lt;/cite&gt; and/or &lt;cite&gt;thick_provisioning_support&lt;/cite&gt;.  And non
reported provisioning types will default to false.&lt;/p&gt;
&lt;p&gt;A Cinder backend may support both provisioning types at the same time.&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Volume provisioning type:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;For Cinder backends that only support one of the provisioning types all
volumes created on them will be of that type, and we can use the volume
type’s extra specs to make the scheduler filter out backends not supporting a
specific provisioning type:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;‘thin_provisioning_support’: ‘&amp;lt;is&amp;gt; True’ or ‘&amp;lt;is&amp;gt; False’&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;‘thick_provisioning_support’: ‘&amp;lt;is&amp;gt; True’ or ‘&amp;lt;is&amp;gt; False’&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But if our deployment is using a backend that is supporting both provisioning
types simultaneously we need to be explicit about the type of provisioning we
want for a volume using the volume type’s extra spec &lt;cite&gt;provisioning:type&lt;/cite&gt; and
setting it to &lt;cite&gt;thin&lt;/cite&gt; or &lt;cite&gt;thick&lt;/cite&gt;.&lt;/p&gt;
&lt;p&gt;If no &lt;cite&gt;provisioning:type&lt;/cite&gt; is defined for a volume it will default to thin if
the backend is capable of it, and the driver is expected to honor this
assumption.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="incorrect-reports"&gt;
&lt;h3&gt;Incorrect reports&lt;/h3&gt;
&lt;p&gt;Given above terms which were originally defined in their corresponding specs,
even if there may be additional comments in this one, we can determine that
there are a good number of Cinder drivers that do not follow these definitions
and are reporting what would be incorrect values.&lt;/p&gt;
&lt;p&gt;Reporting incorrect values means that on a heterogeneous cloud you’ll have
inconsistent scheduling and an admin will not be able to make sense of the
stats from the volumes.&lt;/p&gt;
&lt;p&gt;To illustrate this here are some of the interpretations we can see across
different drivers for the &lt;cite&gt;provisioned_capacity_gb&lt;/cite&gt;:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Sum of all the volumes’ max sizes, which is correct.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sum of all the volumes’ physical disk usage, which is wrong.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sum of the Cinder volumes’ physical disk usage, which is wrong.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And something similar happens with the &lt;cite&gt;allocated_capacity_gb&lt;/cite&gt; where drivers go
and report the value directly instead of letting the Cinder core code take care
of it.  Drivers have been known to report here the following information:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Sum of the Cinder volumes’ physical disk usage, which is correct.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sum of the physical disk usage, which is wrong.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sum of all the volumes’ max sizes, which is wrong.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="provisioning-calculations"&gt;
&lt;h3&gt;Provisioning calculations&lt;/h3&gt;
&lt;p&gt;Some of the creation failures are based on the &lt;cite&gt;provisioned_capacity_gb&lt;/cite&gt; value
being wrong, but there are other cases where Cinder’s calculations for over
provisioning do not match industry’s standard definition, which for some admins
create confusion and undesired behavior.&lt;/p&gt;
&lt;p&gt;Standard provisioning calculation to check if a volume of &lt;cite&gt;volume_size&lt;/cite&gt; fits
is:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;provisioned_capacity_gb&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;volume_size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;
 &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;total_capacity_gb&lt;/span&gt;
  &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reserved_percentage&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mf"&gt;100.0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="n"&gt;max_over_subscription_ratio&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Whereas the Cinder calculations, which were agreed on as the best calculations
for being considered safer are:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;volume_size&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;
 &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;free_capacity_gb&lt;/span&gt;
  &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;total_capacity_gb&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="n"&gt;reserved_percentage&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mf"&gt;100.0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
 &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="n"&gt;max_over_subscription_ratio&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="calculating-max-over-subscription-ratio"&gt;
&lt;h3&gt;Calculating max over subscription ratio&lt;/h3&gt;
&lt;p&gt;Most deployments have very dynamic workloads each with different physical
storage requirements, which means that one month we may require many volumes
of which we barely use any space and next month we may require fewer volumes
but use most of the provisioned capacity.&lt;/p&gt;
&lt;p&gt;This makes it almost impossible to accurately model our storage requirements
at deployment time, which is precisely when we have to set the
&lt;cite&gt;max_over_subscription_ratio&lt;/cite&gt; for our Cinder backends.&lt;/p&gt;
&lt;p&gt;As requirements change one option would be to change the configuration and
restart our Cinder Volume services, but since Cinder is also in the data path
the restart may take a long time to do and will have a considerable impact on
our cloud users.&lt;/p&gt;
&lt;p&gt;Not being able to determine beforehand the best &lt;cite&gt;max_over_subscription_ratio&lt;/cite&gt;
and not being able to easily restart the Cinder service is a common pain that
most operators have with backends supporting thin provisioning.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;The basic case for fixing the status report is where we would like to have
consistent reporting from our backends for the admins to see in the logs and
for the scheduler to use.&lt;/p&gt;
&lt;p&gt;Any operator using thin provisioning storage that wants to optimize their
storage usage and dynamically adjust to the dynamic requirements of its cloud.&lt;/p&gt;
&lt;p&gt;As for the alternative calculations it would greatly benefit any backend that
is close to their full capacity or one that is creating huge volumes that
usually never get filled in.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;section id="id4"&gt;
&lt;h3&gt;Incorrect reports&lt;/h3&gt;
&lt;p&gt;Since we have consolidated all the documentation in one place, this spec, where
we clearly state expected driver behavior all driver maintainers will be urged
to make their drivers compliant with it.  This will mean adapt their drivers
to follow this document’s definition for &lt;cite&gt;provisioned_capacity_gb&lt;/cite&gt; and stop
reporting the &lt;cite&gt;allocated_capacity_gb&lt;/cite&gt; field.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="automatic-over-subscription-ratio-calculation"&gt;
&lt;h3&gt;Automatic over subscription ratio calculation&lt;/h3&gt;
&lt;p&gt;To allow automatic over subscription ratio calculation we will make existing
configuration option &lt;cite&gt;max_over_subscription_ratio&lt;/cite&gt; into a polymorphic option
that accepts not only integers and floats, but also a new string value &lt;cite&gt;auto&lt;/cite&gt;
that will instruct Cinder to use our default value of 20 as the starting
reference when the backend is empty and then, when there is data calculate the
current value on each driver stats report with the following formula:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;ratio = 1 + (`provisioned_capacity_gb` /
             (`total_capacity_gb` - `free_capacity_gb` + 1))
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;If the driver is not reporting &lt;cite&gt;provisioned_capacity_gb&lt;/cite&gt; then we’ll proceed to
use the &lt;cite&gt;allocated_capacity_gb&lt;/cite&gt; instead:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;ratio = 1 + (`allocated_capacity_gb` /
             (`total_capacity_gb` - `free_capacity_gb` + 1))
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;We are not considering the reserved capacity in this formula because the
scheduler’s capacity filter already takes it into consideration when
calculating the virtual free capacity.&lt;/p&gt;
&lt;p&gt;There are a couple of drivers that are already doing this, Pure and Kaminario’s
K2, but with different configuration options,
&lt;cite&gt;pure_automatic_max_oversubscription_ratio&lt;/cite&gt; and
&lt;cite&gt;auto_calc_max_oversubscription_ratio&lt;/cite&gt; respectively, so those configuration
options will take precedence, if configured, over this new feature, but we’ll
encourage vendors to deprecate those options.&lt;/p&gt;
&lt;p&gt;Drivers that are making use of the &lt;cite&gt;max_over_subscription_ratio&lt;/cite&gt; in a non
compatible way will raise an error and fail to start, logging an appropriate
message if configured with this new feature.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="id5"&gt;
&lt;h3&gt;Provisioning calculations&lt;/h3&gt;
&lt;p&gt;Instead of keep fighting with admins and developers on which one of the
approaches is best -standard calculation or Cinder’s- we will be adding a new
configuration option called &lt;cite&gt;over_provisioning_calculation&lt;/cite&gt; which will take
values &lt;cite&gt;standard&lt;/cite&gt; and &lt;cite&gt;cinder&lt;/cite&gt; and default to &lt;cite&gt;cinder&lt;/cite&gt; for backward
compatibility and that will be used by the &lt;cite&gt;CapacityFilter&lt;/cite&gt; to determine which
one of the mechanism to use.&lt;/p&gt;
&lt;p&gt;This configuration option will also affect &lt;cite&gt;CapacityWeigher&lt;/cite&gt; as it will need to
do the free space calculation according to the standard definition as well.&lt;/p&gt;
&lt;p&gt;As one can assume thick provisioning will have no modifications on its
behavior.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Don’t support standard over-provisioning calculations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Instead of modifying &lt;cite&gt;CapacityFilter&lt;/cite&gt; and &lt;cite&gt;CapacityWeigher&lt;/cite&gt; create 2 new
classes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Instead of adding the &lt;cite&gt;over_provisioning_calculation&lt;/cite&gt; configuration option
make the filter use the options JSON file provided by
&lt;cite&gt;scheduler_json_config_location&lt;/cite&gt; .  This data seems to be currently missing
on some of the operations like migrate, extend, so that would need to
changed.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;The only affected API will be the &lt;cite&gt;get_pools&lt;/cite&gt; API that will be able to return
the 2 new fields, &lt;cite&gt;total_used_capacity_gb&lt;/cite&gt; and &lt;cite&gt;cinder_used_capacity_gb&lt;/cite&gt;, when
they are being reported by the driver’s &lt;cite&gt;get_volume_stats&lt;/cite&gt; method.  Fields will
not be present if the drivers are not reporting them.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;The user may see new fields when calling cinderclient’s &lt;cite&gt;get_pools&lt;/cite&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Depending on the driver and the storage array, performance could increase or
decrease, since getting provisioned sizes instead of physical sizes could be
faster or slower.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;With the change of values returned by Cinder backends for
&lt;cite&gt;allocated_capacity_gb&lt;/cite&gt; and &lt;cite&gt;provisioned_capacity_gb&lt;/cite&gt; we may experience
failures on creating volumes until we correct the values of
&lt;cite&gt;reserved_percentage&lt;/cite&gt; and &lt;cite&gt;max_over_subscription_ratio&lt;/cite&gt; in our cloud to the
right values, since we may have been using incorrect ones.&lt;/p&gt;
&lt;p&gt;A configuration option will be modified:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;cite&gt;max_over_subscription_ratio&lt;/cite&gt;: Changes its type from Float to String and
adds a new possible value, &lt;cite&gt;auto&lt;/cite&gt;, that will enable this new feature.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A new configuration options will be added:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;cite&gt;over_provisioning_calculation&lt;/cite&gt;: Will allow to select what kind of
calculations the &lt;cite&gt;CapacityFilter&lt;/cite&gt; does to determine if there is space for a
volume in a backend.  Acceptable values are &lt;cite&gt;standard&lt;/cite&gt; and &lt;cite&gt;cinder&lt;/cite&gt;.  Default
values will be &lt;cite&gt;cinder&lt;/cite&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Driver maintainer will need to verify, and fix if necessary, their stat reports
for &lt;cite&gt;allocated_capacity_gb&lt;/cite&gt; and &lt;cite&gt;provisioned_capacity_gb&lt;/cite&gt; and if they are using
&lt;cite&gt;max_over_subscription_ratio&lt;/cite&gt; in a non compatible way they should fix their
driver so that it supports the feature.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;None&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;None&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;File bugs for drivers that are not in compliance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fix drivers stat reporting.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add support for the 3 new fields, &lt;cite&gt;provisioned_capacity_precission&lt;/cite&gt;,
&lt;cite&gt;total_used_capacity_gb&lt;/cite&gt; and &lt;cite&gt;cinder_used_capacity_gb&lt;/cite&gt; in the scheduler, the
&lt;cite&gt;get_pools&lt;/cite&gt; API, and the client.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify &lt;cite&gt;CapacityFilter&lt;/cite&gt; to support the standard over-provisioning
calculation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify &lt;cite&gt;CapacityWeigher&lt;/cite&gt; to support standard over-provisioning calculations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add to the volume manager the estimation mechanism for drivers that don’t
report &lt;cite&gt;provisioned_capacity_gb&lt;/cite&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update all the developers reference docs to ensure that there is no more
confusion on what the report stats need to return, and make sure that the
wiki page on how to contribute a driver links to that documentation
explaining the importance of following it when writing the driver.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;New unit tests will be added to test the changed code.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Since our current documentation is lacking in this aspect this will add and
update it to reflect what’s expected of the driver in the stats reports.&lt;/p&gt;
&lt;p&gt;End user documentation should also be updated.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id6" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://specs.openstack.org/openstack/cinder-specs/specs/kilo/over-subscription-in-thin-provisioning.html"&gt;https://specs.openstack.org/openstack/cinder-specs/specs/kilo/over-subscription-in-thin-provisioning.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id7" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://specs.openstack.org/openstack/cinder-specs/specs/newton/differentiate-thick-thin-in-scheduler.html"&gt;https://specs.openstack.org/openstack/cinder-specs/specs/newton/differentiate-thick-thin-in-scheduler.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id8" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id3"&gt;3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://specs.openstack.org/openstack/cinder-specs/specs/liberty/standard-capabilities.html"&gt;https://specs.openstack.org/openstack/cinder-specs/specs/liberty/standard-capabilities.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Fri, 26 Jan 2018 00:00:00 </pubDate></item><item><title>Cinder API Microversions</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/mitaka/api-microversions.html</link><description>

&lt;p&gt;We need a way to be able to introduce changes to the REST API to both
fix bugs and add new features. Some of these changes are backwards
incompatible and we currently have no way of doing this. This becomes
especially important to introduce backwards incompatible changes to the
Nova - Cinder API.
Credit and thanks to the authors of the Nova spec upon which this is based,
especially Christopeher Yeoh and Sean Dague, and to the Manila team,
especially Clinton Knight.&lt;/p&gt;
&lt;p&gt;Blueprint:
&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/cinder-api-microversions"&gt;https://blueprints.launchpad.net/cinder/+spec/cinder-api-microversions&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Many changes to the Cinder REST API require changes to the consumers of the
API. For example, If we need to add a required parameter to a method that is
called by Nova, we’d need both the Nova calling code and the cinderclient that
Nova uses to change. But newer Cinder versions with the change must work with
older Nova versions, and there is no mechanism for this at the moment. Adding
microversions will solve this problem.
With microversions, the highest supported version will be negotiated by a field
in the HTTP header that is sent to the Cinder API. In the case where the field
‘versions’ is not sent (i.e. clients and scripts that pre-date this change),
then the lowest supported version would be used. This means that our current
Cinder API v2 would be the default, and consumers of the API that wished to
use a newer version could do so.&lt;/p&gt;
&lt;p&gt;Not in Scope: Experimental APIs. This will be done separately.
Note that Experimental APIs are only different in how we choose to
use the API microversions. For Nova, a microversion does not have to
be backwards compatible, and a microversion might remove an API. In this
definition of microversions, the Experimental APIs that are used by
Manila are no different from microversions that are used by Nova.
This spec assumes that Cinder will take the route used by Manila, and
use the Experimental API HTTP header to indicate an API that might
cause a backwards incompatible change and/or be removed.
These policies do not have to be determined now, and can be decided
at the time that patches with new microversions are merged.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Allows developers to modify the Cinder API in backwards compatible
way and signal to users of the API dynamically that the change is
available without having to create a new API extension.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Allows developers to modify the Cinder API in a non backwards
compatible way whilst still supporting the old behaviour. Users of
the REST API are able to decide if they want the Cinder API to behave
in the new or old manner on a per request basis. Deployers are able
to make new backwards incompatible features available without
removing support for prior behaviour as long as there is support
to do this by developers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Users of the REST API are able to, on a per request basis, decide
which version of the API they want to use (assuming the deployer
supports the version they want). This means that a deployer who does
not upgrade will not break compatibility, and clients that do not upgrade
will also remain compatible.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Cinder will use a framework we will call ‘API Microversions’ for allowing
changes to the API while preserving backward compatibility. The basic idea is
that a user has to explicitly ask for their request to be treated with a
particular version of the API. So breaking changes can be added to the API
without breaking users who don’t specifically ask for it. This is done with
an HTTP header X-OpenStack-Cinder-API-Version which is a monotonically
increasing semantic version number starting from 2.1.&lt;/p&gt;
&lt;p&gt;If a user makes a request without specifying a version, they will get the
DEFAULT_API_VERSION as defined in cinder/api/openstack/wsgi.py. This value is
currently 2.0 and is expected to remain so for quite a long time.&lt;/p&gt;
&lt;p&gt;For the purposes of this discussion, “the API” is all core and
optional extensions in the Cinder tree.
Please note that extensions cannot be versioned. It has been discussed that
the Cinder team should therefore move the API extensions into core. This move
of extensions to core will take some time, and should not block making changes
to the API. Since changes to the API extensions cannot be versioned using the
API-microversions decorator, we will have to accept this until the work to move
extensions to core is completed.&lt;/p&gt;
&lt;p&gt;Versioning of the API should be a single monotonic counter. It will be
of the form X.Y where it follows the following convention:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;X will only be changed if a significant backwards incompatible
API change is made which affects the API as whole. That is, something
that is only very very rarely incremented.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Y when you make any change to the API. Note that this includes
semantic changes which may not affect the input or output formats or
even originate in the API code layer. We are not distinguishing
between backwards compatible and backwards incompatible changes in
the versioning system. It will, however, be made clear in the
documentation as to what is a backwards compatible change and what
is a backwards incompatible one.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Note that groups of similar changes across the API will not be made
under a single version bump. This will minimise the impact on users as
they can control changes that they want to be exposed to.&lt;/p&gt;
&lt;p&gt;A backwards compatible change is defined as one which would be allowed
under the &lt;a class="reference external" href="http://specs.openstack.org/openstack/api-wg/guidelines/evaluating_api_changes.html"&gt;OpenStack API Change Guidelines&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A version response would look as follows for GET &lt;a class="reference external" href="http:/"&gt;http:/&lt;/a&gt;/&amp;lt;cinder_URL&amp;gt;:8776&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="s2"&gt;"versions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
       &lt;span class="p"&gt;{&lt;/span&gt;
           &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"v2.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="s2"&gt;"links"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
               &lt;span class="p"&gt;{&lt;/span&gt;
                   &lt;span class="s2"&gt;"href"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"http://docs.openstack.org/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="s2"&gt;"rel"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"describedby"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"text/html"&lt;/span&gt;
               &lt;span class="p"&gt;},&lt;/span&gt;
               &lt;span class="p"&gt;{&lt;/span&gt;
                   &lt;span class="s2"&gt;"href"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"http://10.10.10.77:8776/v2/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="s2"&gt;"rel"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"self"&lt;/span&gt;
               &lt;span class="p"&gt;}&lt;/span&gt;
           &lt;span class="p"&gt;],&lt;/span&gt;
           &lt;span class="s2"&gt;"media-types"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
               &lt;span class="p"&gt;{&lt;/span&gt;
                   &lt;span class="s2"&gt;"base"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"application/json"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"application/vnd.openstack.volume+json;version=1"&lt;/span&gt;
               &lt;span class="p"&gt;},&lt;/span&gt;
               &lt;span class="p"&gt;{&lt;/span&gt;
                   &lt;span class="s2"&gt;"base"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"application/xml"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"application/vnd.openstack.volume+xml;version=1"&lt;/span&gt;
               &lt;span class="p"&gt;}&lt;/span&gt;
           &lt;span class="p"&gt;],&lt;/span&gt;
           &lt;span class="s2"&gt;"min_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"SUPPORTED"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="s2"&gt;"updated"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2014-06-28T12:20:21Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="s2"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
       &lt;span class="p"&gt;},&lt;/span&gt;
       &lt;span class="p"&gt;{&lt;/span&gt;
           &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"v2.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="s2"&gt;"links"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
               &lt;span class="p"&gt;{&lt;/span&gt;
                   &lt;span class="s2"&gt;"href"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"http://docs.openstack.org/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="s2"&gt;"rel"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"describedby"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"text/html"&lt;/span&gt;
               &lt;span class="p"&gt;},&lt;/span&gt;
               &lt;span class="p"&gt;{&lt;/span&gt;
                   &lt;span class="s2"&gt;"href"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"http://10.10.10.77:8776/v2/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="s2"&gt;"rel"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"self"&lt;/span&gt;
               &lt;span class="p"&gt;}&lt;/span&gt;
           &lt;span class="p"&gt;],&lt;/span&gt;
           &lt;span class="s2"&gt;"media-types"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
               &lt;span class="p"&gt;{&lt;/span&gt;
                   &lt;span class="s2"&gt;"base"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"application/json"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"application/vnd.openstack.volume+json;version=1"&lt;/span&gt;
               &lt;span class="p"&gt;},&lt;/span&gt;
               &lt;span class="p"&gt;{&lt;/span&gt;
                   &lt;span class="s2"&gt;"base"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"application/xml"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"application/vnd.openstack.volume+xml;version=1"&lt;/span&gt;
               &lt;span class="p"&gt;}&lt;/span&gt;
           &lt;span class="p"&gt;],&lt;/span&gt;
           &lt;span class="s2"&gt;"min_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"CURRENT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="s2"&gt;"updated"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2015-09-16T11:33:21Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="s2"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2.1"&lt;/span&gt;
       &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This specifies the min and max version that the server can
understand. min_version will start at 2.0 representing the v2.0 API.
Note that this assumes we will drop support for v1.0 in Mitaka.
It may eventually be increased if there are support burdens we don’t feel are
adequate to support.
This response indicates a version of 2.1 as the current
version. This number would change with each monotonic increment of the API
microversion.&lt;/p&gt;
&lt;section id="client-interaction"&gt;
&lt;h3&gt;Client Interaction&lt;/h3&gt;
&lt;p&gt;A client specifies the version of the API they want via the following
approach, a new header:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;OpenStack&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Cinder&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;API&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;2.114&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This conceptually acts like the accept header. This is a global API
version.&lt;/p&gt;
&lt;p&gt;Semantically this means:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;If X-OpenStack-Cinder-API-Version is not provided, act as if min_version was
sent.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If X-OpenStack-Cinder-API-Version is sent, respond with the API at that
version. If that’s outside of the range of versions supported,
return 406 Not Acceptable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If X-OpenStack-Cinder-API-Version: latest (special keyword) return
max_version of the API.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;NOTE about use of “latest” as a microversion:
A client should never use “latest” when calling the Cinder API, since it
is possible that the client does not have support for the latest server API
microversion. The use of “latest” is strictly for testing. An experimental
(non-gating) Tempeset test should use the microversion “latest” to detect
when the Tempest tests themselves must be updated. This experimental test will
fail using “latest” when the Tempest tests are out of date, and we will thus
have an automated way to detect when Tempest must be updated.&lt;/p&gt;
&lt;p&gt;This means out of the box, with an old client, an OpenStack
installation will return vanilla OpenStack responses at v2. The user
or SDK will have to ask for something different in order to get new
features.&lt;/p&gt;
&lt;p&gt;Two extra headers are always returned in the response:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;X-OpenStack-Cinder-API-Version: version_number&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Vary: X-OpenStack-Cinder-API-Version&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The first header specifies the version number of the API which was
executed.&lt;/p&gt;
&lt;p&gt;The second header is used as a hint to caching proxies that the
response is also dependent on the X-OpenStack-Cinder-API-Version and
not just the body and query parameters. See RFC 2616 section 14.44 for
details.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="implementation-design-details"&gt;
&lt;h3&gt;Implementation design details&lt;/h3&gt;
&lt;p&gt;On each request the X-OpenStack-Cinder-API-Version header string will be
converted to an APIVersionRequest object in the wsgi code. Routing
will occur in the usual manner with the version object attached to the
request object (which all API methods expect). The API methods can
then use this to determine their behaviour to the incoming request.&lt;/p&gt;
&lt;p&gt;Types of changes we will need to support:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;Status&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="n"&gt;changes&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;success&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt; &lt;span class="n"&gt;codes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;Allowable&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="n"&gt;parameters&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;affects&lt;/span&gt; &lt;span class="nb"&gt;input&lt;/span&gt; &lt;span class="n"&gt;validation&lt;/span&gt; &lt;span class="n"&gt;schemas&lt;/span&gt; &lt;span class="n"&gt;too&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;Allowable&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="n"&gt;parameters&lt;/span&gt;
&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;General&lt;/span&gt; &lt;span class="n"&gt;semantic&lt;/span&gt; &lt;span class="n"&gt;changes&lt;/span&gt;
&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;Data&lt;/span&gt; &lt;span class="n"&gt;returned&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;
&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;Removal&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;resources&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;API&lt;/span&gt;
&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;Removal&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;fields&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="nb"&gt;object&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;changing&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;layout&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Note: This list is not meant to be an exhaustive list&lt;/p&gt;
&lt;p&gt;Within a controller case, methods can be marked with a decorator
to indicate what API versions they implement. For example:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="nd"&gt;@api_version&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;min_version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'2.0'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'2.9'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;show&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
   &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="nd"&gt;@api_version&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;min_version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'2.17'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;show&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
   &lt;span class="k"&gt;pass&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;An incoming request for version 2.2 of the API would end up
executing the first method, whilst an incoming request for version
2.17 of the API would result in the second being executed.&lt;/p&gt;
&lt;p&gt;For cases where the method implementations are very similar with just
minor differences a lot of duplicated code can be avoided by versioning
internal methods intead. For example:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="nd"&gt;@api_version&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;min_version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'2.0'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;_version_specific_func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arg1&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
   &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="nd"&gt;@api_version&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;min_version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'2.5'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;_version_specific_func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arg1&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
   &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;show&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt; &lt;span class="n"&gt;common&lt;/span&gt; &lt;span class="n"&gt;stuff&lt;/span&gt; &lt;span class="o"&gt;....&lt;/span&gt;
   &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_version_specific_func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"foo"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;....&lt;/span&gt; &lt;span class="n"&gt;common&lt;/span&gt; &lt;span class="n"&gt;stuff&lt;/span&gt; &lt;span class="o"&gt;....&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Reducing the duplicated code minimizes maintenance
overhead. So the technique we use would depend on individual
circumstances of what code is common/different and where in the method
it is.&lt;/p&gt;
&lt;p&gt;A version object is passed down to the method attached to the request
object so it is also possible to do very specific checks in a
method. For example:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;show&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="o"&gt;....&lt;/span&gt; &lt;span class="n"&gt;stuff&lt;/span&gt; &lt;span class="o"&gt;....&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ver_obj&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;matches&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;start_version&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;end_version&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="o"&gt;....&lt;/span&gt; &lt;span class="n"&gt;Do&lt;/span&gt; &lt;span class="n"&gt;version&lt;/span&gt; &lt;span class="n"&gt;specific&lt;/span&gt; &lt;span class="n"&gt;stuff&lt;/span&gt; &lt;span class="o"&gt;....&lt;/span&gt;

  &lt;span class="o"&gt;....&lt;/span&gt;  &lt;span class="n"&gt;stuff&lt;/span&gt; &lt;span class="o"&gt;....&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Note that end_version is optional in which case it will match any
version greater than or equal to start_version.&lt;/p&gt;
&lt;p&gt;Some prototype code which explains how this work is available here:
&lt;a class="reference external" href="https://github.com/scottdangelo/TestCinderAPImicroversions"&gt;https://github.com/scottdangelo/TestCinderAPImicroversions&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The validation schema decorator would also need to be extended to support
versioning&lt;/p&gt;
&lt;p&gt;@validation.schema(schema_definition, min_version, max_version)&lt;/p&gt;
&lt;p&gt;Note that both min_version and max_version would be optional
parameters.&lt;/p&gt;
&lt;p&gt;A method, extension, or a field in a request or response can be
removed from the API by specifying a max_version:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="nd"&gt;@api_version&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;min_version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'2.0'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'2.9'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;show&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="o"&gt;....&lt;/span&gt;  &lt;span class="n"&gt;stuff&lt;/span&gt; &lt;span class="o"&gt;....&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;If a request for version 2.11 is made by a client, the client will
receive a 404 as if the method does not exist at all. If the minimum
version of the API as whole was brought up to 2.10 then the extension
itself could then be removed.&lt;/p&gt;
&lt;p&gt;The minimum version of the API as a whole would only be increased by a
consensus decision between Cinder developers who have the overhead of
maintaining backwards compatibility and deployers and users who want
backwards compatibility forever.&lt;/p&gt;
&lt;p&gt;Because we have a monotonically increasing version number across the
whole of the API rather than versioning individual plugins we will have
potential merge conflicts like we currently have with DB migration
changesets. Sorry, I don’t believe there is any way around this, but
welcome any suggestions!&lt;/p&gt;
&lt;/section&gt;
&lt;section id="client-expectations"&gt;
&lt;h3&gt;Client Expectations&lt;/h3&gt;
&lt;p&gt;As with systems which supports version negotiation, a robust client
consuming this API will need to also support some range of versions
otherwise that client will not be able to be used in software that
talks to multiple clouds.&lt;/p&gt;
&lt;p&gt;The concrete example is nodepool in OpenStack Infra. Assume there is a
world where it is regularly connecting to 4 public clouds. They are
at the following states:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;Cloud&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;min_ver&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;2.100&lt;/span&gt;
  &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;max_ver&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;2.300&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;Cloud&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;min_ver&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;2.200&lt;/span&gt;
  &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;max_ver&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;2.450&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;Cloud&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;min_ver&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;2.300&lt;/span&gt;
  &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;max_ver&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;2.600&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;Cloud&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;min_ver&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;2.400&lt;/span&gt;
  &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;max_ver&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;2.800&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;No single version of the API is available in all those clouds based on
the age of some of them. However within the client SDK certain
basic functions like boot will exist, though one might get different
additional data based on the version of the API. The client should smooth
over these differences when possible.&lt;/p&gt;
&lt;p&gt;Realistically this is a problem that exists today, except there is no
infrastructure to support creating a solution to solve it.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;One alternative is to make all the backwards incompatible changes at
once and do a major API release. For example, change the url prefix to
/v3 instead of /v2. And then support both implementations for a long
period of time. This approach has been difficult in the past and has
cause long periods of time before adoption by various users.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;As described above there would be additional version information added
to the GET /. These should be backwards compatible changes.&lt;/p&gt;
&lt;p&gt;Otherwise there are no changes unless a client header as described is
supplied as part of the request.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;SDK authors will need to start using the X-OpenStack-Cinder-API-Version header
to get access to new features. The fact that new features will only be
added in new versions will encourage them to do so.&lt;/p&gt;
&lt;p&gt;python-cinderclient is in an identical situation and will need to be
updated to support the new header in order to support new API
features.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;This will affect how Cinder developers modify the REST API code and add new
extensions.
This will affect the Volume Manager and the ability to remove locks and instead
return VolumeIsBusy for volumes in various -ing states.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Scott DAngelo&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Port Manila code for api-microversions
Status: Done (see &lt;a class="reference external" href="https://review.openstack.org/#/c/224910/"&gt;https://review.openstack.org/#/c/224910/&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add examples of increments and decorators (scottda)
Status: Done (see &lt;a class="reference external" href="https://github.com/scottdangelo/TestCinderAPImicroversions"&gt;https://github.com/scottdangelo/TestCinderAPImicroversions&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement changes for python-cinderclient (scottda)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;test with python-cinderclient changes (scottda)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cinder Doc changes (scottda)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;Any Cinder spec which makes backwards incompatible changes to the API is
dependent on this spec&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;It is not feasible for tempest to test all possible combinations
of the API supported by microversions. We will have to pick specific
versions which are representative of what is implemented. The existing
Cinder tempest tests will be used as the baseline for future API
version testing.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Documents concerning the API will need to reflect these changes.
These are begun in the WIP cinder code changes, and will live in
cinder/api/openstack/rest_api_version_history.rst&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/nova-specs/tree/specs/kilo/implemented/api-microversions.rst"&gt;http://git.openstack.org/cgit/openstack/nova-specs/tree/specs/kilo/implemented/api-microversions.rst&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Manila code for api-microversions: &lt;a class="reference external" href="https://review.openstack.org/#/c/207228/8"&gt;https://review.openstack.org/#/c/207228/8&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;WIP implementation code: &lt;a class="reference external" href="https://review.openstack.org/#/c/224910/"&gt;https://review.openstack.org/#/c/224910/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Test Cases and code: &lt;a class="reference external" href="https://github.com/scottdangelo/TestCinderAPImicroversions"&gt;https://github.com/scottdangelo/TestCinderAPImicroversions&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Wed, 24 Jan 2018 00:00:00 </pubDate></item><item><title>Cinder Volume Active/Active support - Job Distribution</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/ocata/ha-aa-job-distribution.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/cinder-volume-active-active-support"&gt;https://blueprints.launchpad.net/cinder/+spec/cinder-volume-active-active-support&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Right now cinder-volume service can run only in Active/Passive HA fashion.&lt;/p&gt;
&lt;p&gt;One of the reasons for this is that we have no concept of a cluster of nodes
that handle the same storage back-end.&lt;/p&gt;
&lt;p&gt;This spec introduces the concept of cluster to Cinder and aims to provide a way
for Cinder’s API and Scheduler nodes to distribute jobs to Volume nodes on a
High Availability deployment with Active/Active configuration.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Right now cinder-volume service only accepts Active/Passive High Availability
configurations, and current job distribution mechanism does not allow having
multiple services grouped in a cluster where jobs can be queued to be processed
by any of those nodes.&lt;/p&gt;
&lt;p&gt;Jobs are currently being distributed using a topic based message queue that is
identified by the &lt;cite&gt;volume_topic&lt;/cite&gt;, &lt;cite&gt;scheduler_topic&lt;/cite&gt;, or &lt;cite&gt;backup_topic&lt;/cite&gt; prefix
joined with the host name and possibly the backend name if it’s a multibackend
node like in &lt;cite&gt;cinder-volume.localhost@lvm&lt;/cite&gt;, and that’s the mechanism used to
send jobs to the Volume nodes regardless of the physical address of the node
that is going to be handling the job, allowing an easier transition on
failover.&lt;/p&gt;
&lt;p&gt;Chosen solution must be backward compatible as well as allow the new
Active/Active configuration to effectively send jobs.&lt;/p&gt;
&lt;p&gt;In the Active/Active configuration there can be multiple Volume services - this
is not mandatory at all times, as failures may leave us with only 1 active
service - with different &lt;cite&gt;host&lt;/cite&gt; configuration values that can interchangeably
accept jobs that are handling the same storage backend.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;Operators that have hard requirements, SLA or other reasons, to have their
cloud operational at all times or have higher throughput requirements will want
to have the possibility to configure their deployments with an Active/Active
configuration.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;section id="basic-mechanism"&gt;
&lt;h3&gt;Basic mechanism&lt;/h3&gt;
&lt;p&gt;To provide a mechanism that will allow us to distribute jobs to a group of
nodes we’ll add a new &lt;cite&gt;cluster&lt;/cite&gt; configuration option that will uniquely
identify a group of Volume nodes that share the same storage backends and
therefore can accept jobs for the same volumes interchangeably.&lt;/p&gt;
&lt;p&gt;This new configuration option, unlike the &lt;cite&gt;host&lt;/cite&gt; option, will be allowed to
have the same value on multiple volume nodes, with the only requisite that all
nodes that share the same value must also share the same storage backends and
they must also share the same configurations.&lt;/p&gt;
&lt;p&gt;By default &lt;cite&gt;cluster&lt;/cite&gt; configuration option will be undefined, but when a string
value is given a new topic queue will be created on the message broker to
distribute jobs meant for that cluster in the form of
&lt;cite&gt;cinder-volume.cluster@backend&lt;/cite&gt; similar to already existing host topic queue
&lt;cite&gt;cinder-volume.host@backend&lt;/cite&gt;.&lt;/p&gt;
&lt;p&gt;It is important to notice that &lt;cite&gt;cluster&lt;/cite&gt; configuration option is not a
replacement of the &lt;cite&gt;host&lt;/cite&gt; option as both will coexist within the service and
must exist for Active-Active configurations.&lt;/p&gt;
&lt;p&gt;To be able to determine the topic queue where an RPC caller has to send
operations we’ll add &lt;cite&gt;cluster_name&lt;/cite&gt; field to any resource DB table that
currently has the &lt;cite&gt;host&lt;/cite&gt; field we are using for non Active/Active
configurations.  This way we don’t need to check the DB, or keep a cache in
memory, to figure out in which cluster is this service included, if it is in a
cluster at all.&lt;/p&gt;
&lt;p&gt;Once the basic mechanism of receiving RPC calls on the cluster topic queue is
in place, operations will be incrementally moved to support Active-Active if
the resource is in a cluster, as indicated by the presence of a value in the
&lt;cite&gt;cluster_name&lt;/cite&gt; resource field.&lt;/p&gt;
&lt;p&gt;The reason behind this progressive approach instead of an all or nothing
approach is to reduce the possibility of adding new bugs and facilitating quick
fixes by just reverting a specific patch.&lt;/p&gt;
&lt;p&gt;This solution makes a clear distinction between independent services and those
that belong to a cluster, and the same can be said about resources belonging to
a cluster.&lt;/p&gt;
&lt;p&gt;To facilitate the inclusion of a service in a cluster, the volume manager will
detect when the &lt;cite&gt;cluster&lt;/cite&gt; value has changed from being undefined to having a
value and proceed to include all existing resources in the cluster by filling
the &lt;cite&gt;cluster_name&lt;/cite&gt; fields.&lt;/p&gt;
&lt;p&gt;Having both message queues, one for the cluster and one for the service, could
prove useful in the future if we want to add operations that can target
specific services within a cluster.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="heartbeats"&gt;
&lt;h3&gt;Heartbeats&lt;/h3&gt;
&lt;p&gt;With Active/Passive configurations a storage backend service is down whenever
we don’t have a valid heartbeat from the service and is up if we do.  These
heartbeats are reported in the DB in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;services&lt;/span&gt;&lt;/code&gt; table.&lt;/p&gt;
&lt;p&gt;On Active/Active configurations a service is down if there is no valid
heartbeat from any of the services that constitute the cluster, and it is up if
there is at least one valid heartbeat.&lt;/p&gt;
&lt;p&gt;Services will keep reporting their heartbeats in the same way that they are
doing it now, and it will be Scheduler’s job to separate between individual and
clustered services and aggregate the latter by cluster name.&lt;/p&gt;
&lt;p&gt;As explained in &lt;a class="reference internal" href="#rest-api-impact"&gt;REST API impact&lt;/a&gt; the API will be able to show cluster
information with the status -up or down- of each cluster, based on the services
that belong to it.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="disabling"&gt;
&lt;h3&gt;Disabling&lt;/h3&gt;
&lt;p&gt;This new mechanism will change the “disabling working unit” from service to
cluster for services that are in a cluster.  Which means that once all
operations that go through the scheduler have been moved to support
Active-Active configurations, we won’t be able to disable an individual service
belonging to a cluster and we’ll have to disable the cluster itself.  For non
clustered services, disabling will work as usual.&lt;/p&gt;
&lt;p&gt;Disabling a cluster will prevent schedulers from taking that cluster, and
therefore all its services, into consideration during filtering and weighting
and the service will still be reachable to all operations that don’t go through
the scheduler.&lt;/p&gt;
&lt;p&gt;It stands to reason that sometimes we’ll need to drain nodes to remove them
from a cluster, but this spec and its implementation will not be adding any new
mechanism for that.  So existing mechanism, using SIGTERM, should be used to
perform graceful shutdown of cinder volume services.&lt;/p&gt;
&lt;p&gt;Current graceful shutdown mechanism will make sure that no new operations are
received from the messaging queue while it waits for ongoing operations to
complete before stopping.&lt;/p&gt;
&lt;p&gt;It is important to remember that graceful shutdown has a timeout that will
forcefully stop operations if they take longer than the configured value.
Configuration option is called &lt;cite&gt;graceful_shutdown_timeout&lt;/cite&gt;, goes in [DEFAULT]
section and takes a default value of 60 seconds; so this should be configured
in our deployments if we think this is not long enough for our use cases.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="capabilities"&gt;
&lt;h3&gt;Capabilities&lt;/h3&gt;
&lt;p&gt;All Volume services periodically report their capabilities to the schedulers to
keep them updated with their stats, that way they can make informed decisions
on where to perform operations.&lt;/p&gt;
&lt;p&gt;In a similar way to the Service state reporting we need to prevent concurrent
access to the data structure when updating this information. Fortunately for us
we are storing this information in a Python dictionary on the schedulers, and
since we are using an eventlet executor for the RPC server we don’t have to
worry about using locks, the inherent behavior of the executor will prevent
concurrent access to the dictionary.  So no changes are needed there to have
exclusive access to the data structure.&lt;/p&gt;
&lt;p&gt;Although rare, we could have a consistency problem among volume services where
different schedulers would not have the same information for a given backend.&lt;/p&gt;
&lt;p&gt;When we had only 1 volume service reporting for each given backend this was not
a situation that could happen, since received capabilities report was always
the latest and all scheduler services were in sync.  But now that we have
multiple volume services reporting on the same backend we could receive two
reports from different volume services on the same backend and they could be
processed in different order on different schedulers, thus making us have
different data on each scheduler.&lt;/p&gt;
&lt;p&gt;The reason why we can’t assure that all schedulers will have the same
capabilities stored in their internal structures is because capabilities
reports can be processed in different order on different services.  Order is
preserved in &lt;em&gt;almost all&lt;/em&gt; stages, volume services report in a specific order
and message broker preserves this order and they are even delivered in the same
order, but when each service processes them we can have greenthreads execution
in different order on different scheduler services thus ending up with
different data on each service.&lt;/p&gt;
&lt;p&gt;This case could probably be ignored since it’s very rare and differences would
be small, but in the interest of consistent of the backend capabilities on
Scheduler services, we will timestamp the capabilities on the volume services
before they are sent to the scheduler, instead of doing it on the scheduler as
we are doing now. And then we’ll have schedulers drop any capabilities that are
older than the one in the data structure.&lt;/p&gt;
&lt;p&gt;By making this change we facilitate new features related to capability
reporting, like capability caching.  Since capability gathering is usually an
expensive operation and in Active-Active configurations we’ll have multiple
volume services requesting the same capabilities with the same frequency for
the same back-end, we could consider capability caching as solution to decrease
the cost of the gathering on the backend.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;One alternative to proposed job distribution would be to leave the topic queues
as they are and move the job distribution logic to the scheduler.&lt;/p&gt;
&lt;p&gt;The scheduler would receive a job and then send it to one of the volume
services that belong to the same cluster and is not down.&lt;/p&gt;
&lt;p&gt;This method has one problem, and that is that we could be sending a job to a
node that is down but whose heartbeat hasn’t expired yet, or one that has gone
down before getting the job from the queue.  In these cases we would end up
with a job that is not being processed by anyone and we would need to either
wait for the node to go back up or the scheduler would need to retrieve that
message from the queue and send it to another active node.&lt;/p&gt;
&lt;p&gt;An alternative to proposed heartbeats is that all services report using
&lt;cite&gt;cluster@backend&lt;/cite&gt; instead of &lt;cite&gt;host@backend&lt;/cite&gt; like they are doing now and as long
as we have a valid heartbeat we know that the service is up.&lt;/p&gt;
&lt;p&gt;There are 2 reasons why I believe that sending independent heartbeats is a
superior solution, even if we need to modify the DB tables:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Higher information granularity: We can report not only which services are
up/down but also which nodes are up/down.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It will help us on job cleanup of failed nodes that do not come back up.
Although cleanup is not part of this spec, it is good to keep it in mind and
facilitate it as much as possible.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Another alternative for the job distribution, which was the proposed solution
in previous versions of this specification, was to use &lt;cite&gt;host&lt;/cite&gt; configuration
option as the equivalent to &lt;cite&gt;cluster&lt;/cite&gt; grouping a new added &lt;cite&gt;node&lt;/cite&gt; configuration
option that would serve to identify individual nodes.&lt;/p&gt;
&lt;p&gt;Using such solution may lead to misunderstandings with the concept of hosts as
clusters, whereas using the cluster concept directly there is no such problem,
wouldn’t allow a progressive solution as it was a one shot change, and we
couldn’t send messages to individual volume services since we only had the host
message topic queue.&lt;/p&gt;
&lt;p&gt;There is a series of patches showing the implementation of the
&lt;a class="reference external" href="https://review.openstack.org/286599"&gt;node alternative mechanism&lt;/a&gt; that can serve as a more detailed explanation.&lt;/p&gt;
&lt;p&gt;Another possibility would be to allow disabling individual services within a
cluster instead of having to disable the whole cluster, and this is something
we can take up after everything else is done.  To do this we would use the
normal host message queue on the cinder-volume service to receive the
enable/disable of the cluster on the manager and that would trigger a
start/stop of the cluster topic queue.  But this is not trivial, as it requires
us to be able to stop and start the client for the cluster topic from the
cinder volume manager (it is managed at the service level) and be able to wait
for a full stop before we can accept a new enable request to start the message
client again.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Final result:&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;A new &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;clusters&lt;/span&gt;&lt;/code&gt; table will be added with the following fields:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;id&lt;/span&gt;&lt;/code&gt;: Unique identifier for the cluster&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;name&lt;/span&gt;&lt;/code&gt;: Name of the cluster, it is used to build the topic queue in the&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;same way the &lt;cite&gt;host&lt;/cite&gt; configuration option is used.  This comes from
the &lt;cite&gt;cluster&lt;/cite&gt; configuration option.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;binary&lt;/span&gt;&lt;/code&gt;: For now it will always be “cinder-volume” but when we add backups&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;it’ll also accept “cinder-backup”.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;disabled&lt;/span&gt;&lt;/code&gt;: To support disabling clusters.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;disabled_reason&lt;/span&gt;&lt;/code&gt;: Same as in service table.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;race_preventer&lt;/span&gt;&lt;/code&gt;: This field will be used to prevent potential races that&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;could happen if 2 new services are brought up at the same
time and both try to create the cluster entry at the same
time.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cluster_name&lt;/span&gt;&lt;/code&gt; field will be added to existing &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;services&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volumes&lt;/span&gt;&lt;/code&gt;,
and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;consistencygroups&lt;/span&gt;&lt;/code&gt; tables.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;Service listing will return &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cluster_name&lt;/span&gt;&lt;/code&gt; field when requested with the
appropriate microversion.&lt;/p&gt;
&lt;p&gt;A new &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;clusters&lt;/span&gt;&lt;/code&gt; endpoint will be added to list -detailed and summarized-,
show, and update operations with their respective policies.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Negligible if we implement the aggregation of the heartbeats on a SQL query
using exist instead of retrieving all heartbeats and doing the aggregation on
the scheduler.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Gorka Eguileor (geguileo)&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Michal Dulko (dulek)
Scott DAngelo (scottda)
Anyone is welcome to help&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add the new &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;clusters&lt;/span&gt;&lt;/code&gt; table and related operations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add Cluster Versioned Object.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify job distribution to use new &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cluster&lt;/span&gt;&lt;/code&gt; configuration option.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update service API and add new &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;clusters&lt;/span&gt;&lt;/code&gt; endpoint.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update cinder-client to support new endpoint and new field in services.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Move operations to Active-Active.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unittests for new API behavior.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;This spec has changes to the API as well as a new configuration option that
will need to be documented.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Wed, 24 Jan 2018 00:00:00 </pubDate></item><item><title>Report backend state in service list</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/queens/report-backend-state-in-service-list.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/report-backend-state-in-service-list"&gt;https://blueprints.launchpad.net/cinder/+spec/report-backend-state-in-service-list&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Storage driver reports state of backend storage device and let admin operator
know it via service list for maintenance purpose.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently, Cinder couldn’t report backend state to service, operators only
know that cinder-volume process is up, but isn’t aware of whether the backend
storage device is ok. Users still can create volume and go to fail over and
over again. To make maintenance easier, operator could query storage device
state via service list and fix the problem more quickly. If device state is
&lt;em&gt;down&lt;/em&gt;, that means volume creation will fail.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;In large scale cloud system, there could be many backends existing in the
system. If volume, snapshot or other resources creation goes to failure,
operators or cloud management system could query the service first and get
the backend device state in every service. If device state is &lt;em&gt;down&lt;/em&gt;, specify
that storage device has got some problems. Give operators/management system
more information to locate bug more quickly.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Each driver reports the backend state in “get_volume_stats” by adding
key/value: “backend_state: up/down”[1].&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When calling ‘service list’, get this information from scheduler for every
backend.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add ‘backend_state: up/down’ in response body of service list API if context
is admin.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Before all drivers support this feature, if the result of get_volume_stats
doesn’t include the backend state, Cinder will set backend_state to ‘up’ by
default.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Add cinder manage command to query backend device state from driver directly.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;Add backend_state: up/down into response body of service list and also need
a microversions for this feature:&lt;/p&gt;
&lt;div class="highlight-console notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="go"&gt;GET /v3/{project_id}/os-services&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;RESP BODY:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"services"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="s2"&gt;"host"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"host@backend1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="s2"&gt;"backend_status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"up"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="p"&gt;},&lt;/span&gt;
              &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"host"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"host@backend2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="s2"&gt;"backend_status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"down"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="p"&gt;}]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Driver maintainer needs to add backend state when reporting
volume stats.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;wanghao&amp;lt;&lt;a class="reference external" href="mailto:wanghao749%40huawei.com"&gt;wanghao749&lt;span&gt;@&lt;/span&gt;huawei&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Implement code in Cinder API and scheduler.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update cinderclient to support this function.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add change to API doc.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Both unit and Tempest tests need to be created to cover the code change that
mentioned in “Proposed change”.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;The cinder API documentation will need to be updated to reflect the REST
API changes.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;[1]https://docs.openstack.org/cinder/latest/contributor/drivers.html&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 18 Jan 2018 00:00:00 </pubDate></item><item><title>Improvement to query consistency group detail</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/newton/improvement-to-query-consistency-group-detail.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/improvement-to-query-consistency-group-detail"&gt;https://blueprints.launchpad.net/cinder/+spec/improvement-to-query-consistency-group-detail&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Return the volume id list if they exist in CG when querying CG detail.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently, querying consistency group detail will not return list of volumes
ids that exist in this CG, end users don’t know how many and which volumes are
in it. They must query the volume detail one by one to get the CG’s id and
form the list of volume ids. It’s very inconvenient to user experience.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;After adding volumes to a consistency group, end user wants to know how many
and which volumes are in a CG before they decide to make CG snapshot.
According to this feature, they can get this information easily by querying
consistency group detail, and make further adjustment, like adding more
volumes, or remove some volumes from this consistency group.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;1.Add volume id list into response body of querying a consistency group detail
if user wants those volume’s information.&lt;/p&gt;
&lt;p&gt;2.Add group_id query filter to /volumes to get a list of volumes
in a CG. For example “cinder list –group-id &amp;lt;uuid of CG&amp;gt;”.&lt;/p&gt;
&lt;p&gt;NOTE: Since we’re working on Generic Volume Group[1], to avoid unnecessary
code migration later, we will implement the ‘group_id’ query filter first,
and after Generic Volume Group is merged, we will implement the #1 way
dependent on the Generic Group spec.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;For performance impact, if we want to add index to consistencygroup_id column,
there is data model impact.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add volume id list into response body of querying a CG detail if specifying
the argument ‘list_volume=True’, this will be dependent on the Generic Group
spec now, so just leave a example here:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-console notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="go"&gt;GET /v3/{project_id}/consistencygroups/{consistency_group_id}?list_volume=True&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;RESP BODY:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"consistencygroup"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"XXX"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"XXX"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s2"&gt;"volume_list"&lt;/span&gt;&lt;span class="p"&gt;:[&lt;/span&gt;&lt;span class="s1"&gt;'volume_id1'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                     &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                     &lt;span class="s1"&gt;'volume_idn'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
                      &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add a filter “group_id=xxx” in URL of querying volume list/detail:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-console notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="go"&gt;GET /v3/{project_id}/volumes?group_id=XXX&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;There is no performance impact if user is NOT using ‘list_volume=True’.
We just need to consider to add a additional DB query to get all
volume ids which have same CG id. So the performance impact should
be small with ‘list_volume=True’. If considering large scale volumes,
we can add index to consistencygroup_id column of volume table
to reduce performance impact.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;wanghao&amp;lt;&lt;a class="reference external" href="mailto:wanghao749%40huawei.com"&gt;wanghao749&lt;span&gt;@&lt;/span&gt;huawei&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Implement code in db query and add list to response body.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update cinderclient to support this function.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add change to API doc.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Both unit and Tempest tests need to be created to cover the code change that
mentioned in “Proposed change”.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;The cinder API documentation will need to be updated to reflect the REST
API changes.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;[1]https://review.openstack.org/#/c/303893/&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 21 Dec 2017 00:00:00 </pubDate></item><item><title>Extending IBMNAS driver to support NAS based GPFS storage deployments</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/juno/support-GPFS-nas-ibmnas-driver.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/add-gpfs-nas-to-ibmnas"&gt;https://blueprints.launchpad.net/cinder/+spec/add-gpfs-nas-to-ibmnas&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Currently, the ibmnas driver works for an nfs export from Storwize V7000
Unified and SONAS products. It does not have the capability to work with
nfs exports provided from a gpfs server.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently, the ibmnas driver does not have the capability to work with nfs
exports provided from a gpfs server.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Lacking this capability will limit the end users from using remote gpfs
NAS servers as a backend in OpenStack environment.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add/Reuse functions in ibmnas.py to support all minimum features listed
(github.com/openstack/cinder/blob/master/doc/source/devref/drivers.rst)
for NAS based GPFS server backends.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;The existing gpfs driver can be extended to support NAS based gpfs storage
deployments. But this implementation requires many other new funtions to be
introduced, which are already existing and can be reused in ibmnas driver.
Apart from this in future, we have planned to support all NFS/GPFS related
IBM products via ibmnas driver. Hence extending ibmnas driver is more
advantageous than extending gpfs driver.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;No specific security issues needs to be considered. Insecure file permissions
(OSSN-0014) is fixed in the driver and is addressed by
&lt;a class="reference external" href="https://review.openstack.org/#/c/101919/"&gt;https://review.openstack.org/#/c/101919/&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;This requires an additional option to be configured while deploying
OpenStack with IBMNAS products (sonas, v7ku, gpfs-nas).&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;New configuration option needs to be filled in cinder.conf
ibmnas_platform_type = &amp;lt;sonas&amp;gt; | &amp;lt;v7ku&amp;gt; | &amp;lt;gpfs-nas&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This change needs to be explicitly enabled on IBMNAS driver CI certification&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;sasikanth &amp;lt;&lt;a class="reference external" href="mailto:sasikanth.eda%40in.ibm.com"&gt;sasikanth&lt;span&gt;.&lt;/span&gt;eda&lt;span&gt;@&lt;/span&gt;in&lt;span&gt;.&lt;/span&gt;ibm&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;nilesh-bhosale &amp;lt;&lt;a class="reference external" href="mailto:nilesh.bhosale%40in.ibm.com"&gt;nilesh&lt;span&gt;.&lt;/span&gt;bhosale&lt;span&gt;@&lt;/span&gt;in&lt;span&gt;.&lt;/span&gt;ibm&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add/Reuse functions in ibmnas.py to support NAS based GPFS storage
deployments.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit tests - Existing test_ibmnas.py will be improved to handle the new
code changes/functions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tempest tests - No additional testcases needs to be written, this feature
can be tested with the existing tempest.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cinder driver certification tests - Driver certification tests will be
executed and results will be submitted to the community (as the changes will
altogether enable a new storage platform).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CI tests - We are working towards 3rd party CI environment and will
continuously run tests across the respective hardware platform.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;ibmnas driver documentation needs to updated with this new configuration
option.&lt;/p&gt;
&lt;p&gt;ibmnas_platform_type = &amp;lt;sonas&amp;gt; | &amp;lt;v7ku&amp;gt; | &amp;lt;gpfs-nas&amp;gt;&lt;/p&gt;
&lt;p&gt;This option is used for selecting the appropriate backend storage.
Valid values are v7ku for using IBM Storwize V7000 Unified
sonas for using IBM Scale Out NAS and
gpfs-nas for using NAS based GPFS server deployment&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 16 Nov 2017 00:00:00 </pubDate></item><item><title>Volume Replication</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/juno/volume-replication.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/volume-replication"&gt;https://blueprints.launchpad.net/cinder/+spec/volume-replication&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Volume replication is a key storage feature and a requirement for
features such as high-availability and disaster recovery of applications
running on top of OpenStack clouds.
This blueprint is an attempt to add initial support for volume replication
in Cinder, and is considered a first take which will include support for:
* Replicate volumes (primary to secondary approach)
* Promote a secondary to primary (and stop replication)
* Re-enable replication
* Test that replication is running properly&lt;/p&gt;
&lt;p&gt;It is important to note that this is a first pass at volume replication.
The process of implementing replication for drivers has uncovered a
number of challenges that will be addressed in a future revision of
replication that will address the ability to have different replication
types and the ability to replicate across multiple backends.&lt;/p&gt;
&lt;p&gt;While this blueprint focuses on volume replication, a related blueprint
focuses on consistency groups, and replication will be extended to
support it.&lt;/p&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;The main use of volume replication is resiliency in presence of failures.
Examples of possible failures are:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Storage system failure&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Rack(s) level failure&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Datacenter level failure&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here we specifically exclude failures like media failures, disk failures, etc.
Such failures are typically addressed by local resiliency schemes.&lt;/p&gt;
&lt;p&gt;Replication can be implemented in the following ways:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Host-based - Requires Nova integration&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Storage-based&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Typical block based approach - replication is specified between two
existing volumes (or groups of volumes) on the controllers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Typically file system based approach - a file
(in Cinder context, the file representing a block device) placed in a
directory (or group or fileset, etc) that is automatically copied to a
specified remote location.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Assumptions:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Replication should be transparent to the end-user, failover, failback
and test will be executed by the cloud admin.
However, to test that the application is working, the end-user may be
involved, as they will be required to verify that his application is
working with the volume replica.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The storage admin will provide the setup and configuration to enable the
actual replication between the storage systems. This could be performed
at the storage back-end or storage driver level depending on the storage
back-end. Specifically, storage drivers are expected to report with whom
they can replicate and report this to the scheduler.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The cloud admin will enable the replication feature through the use of
volume types.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The end-user will not be directly exposed to the replication feature.
Selecting a volume-type will determine if the volume will be replicated,
based on the actual extra-spec definition of the volume type (defined by
the cloud admin).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Quota management: quota are consumed as 2x as two volumes are
created and the consumed space is doubled.
We can re-examine this mechanism after we get comments from deployers.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Introduction:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;The proposed design provides just a framework in Cinder for backend volume
drivers to implement volume replication using the facilities in the storage
backend.  As such, this spec provides guidance as to how volume replication
should be implemented but the actual implementation will vary depending
upon the backend in question.&lt;/p&gt;
&lt;p&gt;The key to enabling replication starts with adding an extra spec to the
volume type to indicate that replication is desired.  That extra spec is
then used in the volume driver to enable the set-up and control of
replication on the storage backend in each of the different functions
documented below.&lt;/p&gt;
&lt;p&gt;Since Cinder is just providing the framework for backend volume drivers
to implement replication, details of replication implementation are left
to the backend to implement.  The backend driver developer will need to
decide for their storage backend the best way to enable replication.  For
instance one storage provider may feel that implementing synchronous
replication is the best choice while another storage provider may choose
asynchronous.  A provider could also choose to make it a configurable
option.  Implementing volume replication in Cinder in this manner allows
the greatest flexibility to the backend developer to implement replication.&lt;/p&gt;
&lt;p&gt;It is also important to note that the developer documentation must provide
examples of how this is implemented in the Storwize driver.  This is an
important item to note as it is not currently possible to demonstrate
volume replication in Cinder’s reference implementation, LVM.  Therefore
developer documentation will have to serve as the reference.&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Add extra-specs in the volume type to indicate replication:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;capabilities:replication &amp;lt;is&amp;gt; True - if True, the volume is to be replicated,
if supported, by the backend driver.  If the option is not specified or
False, then replication is not enabled. This option is required to enable
replication.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Create volume with replication enabled:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Backend drivers that wish to enable replication will need to update their
create_volume() function to check for the
‘capabilities:replication &amp;lt;is&amp;gt; True’ extra spec.  It is up to the backend
driver developers to implement replication in a manner that is compatible
with their storage backend.&lt;/p&gt;
&lt;p&gt;When a replicated volume is created it is expected that the volume dictionary
will be populated as follows:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;volume[‘replication_status’] = ‘copying’&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;volume[‘replication_extended_status’] = &amp;lt;driver specific value&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;volume[‘driver_data’] = &amp;lt;driver specific value&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;The replica volume is hidden from the end user as the end user will
never need to directly interact with the replica volume.  Any interaction
with the replica happens through the primary volume.&lt;/p&gt;
&lt;p&gt;Further details around the dictionary fields above may be seen in the data
“Data Model Impact” section below.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Create Volume from Snapshot:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;If the volume type extra specs include ‘capabilities:replication &amp;lt;is&amp;gt; True’
for the new volume, the driver needs to create a volume replica at volume
creation time and set up replication between the newly created volume and its
associated replica.  The volume dictionary should be populated in the same
manner as create volume.&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Create Cloned Volume:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;If the volume type extra specs include ‘capabilities:replication &amp;lt;is&amp;gt; True’
for the new volume, the driver needs to create a volume replica at clone
creation time and set up replication between the newly created volume and its
associated replica.  The volume dictionary should be populated in the same
manner as create volume.&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Create Replica Test Volume:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;Create a clone of the replica (secondary) volume.  This clone can then be
used for testing replication to ensure that fail-over can be executed when
necessary.  It is important to note that this doesn’t actually execute the
the promote path as the intention is not to promote the replica but it gives
a method to ensure that the replica contains data and would be useful if
it had to be promoted.&lt;/p&gt;
&lt;p&gt;The administrator is able to access this functionality using the
–source-replica option when creating a volume.&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Delete volume:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;For volumes with replication enabled the replica needs to be deleted
along with the primary copy.  So, if a volume type has
‘capabilities:replication &amp;lt;is&amp;gt; True’ set, the driver will need to do the
additional deletion.&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Get Volume Stats:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;If the storage backend driver supports replication the following state should
be reported:
* replication = True (None or False disables replication)&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Re-type volume:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;Changing volume-type is the mechanism an admin can use to make an existing
volume replicated, or to disable replication for a volume.  Change the
volume-type of a volume to a volume-type that includes
‘capabilities:replication: &amp;lt;is&amp;gt; True’ (and didn’t have it before) should
result in adding a secondary copy to a volume.  Change the volume-type of
a volume to a volume-type that no longer includes
‘capabilities:replication: &amp;lt;is&amp;gt; True’ should result in removing the secondary
copy while preserving the primary copy.&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Returns either:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;A boolean indicating whether the retype occurred, or
A tuple (retyped, model_update) where retyped is a boolean
indicating if the retype occurred, and the model_update includes
changes for the volume db.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;The steps to implement this would look as follows:
* Do a diff[‘extra_specs’] and see if ‘replication’ is included.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;If replication was enabled for the original volume_type but is not
not enabled for the new volume_type, then replication should be disabled.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The replica should be deleted.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The volume dictionary should be updated as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;volume[‘replication_status’] = ‘disabled’&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;volume[‘replication_extended_status’] = None&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;volume[‘driver_data’] = None&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If replication was not enabled for the original volume_type but is
enabled for the new volume_type, then replication should be enabled.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A volume replica should be created and the replication should
be set up between the volume and the newly created replica.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The volume dictionary should be updated as follows:
- volume[‘replication_status’] = ‘copying’
- volume[‘replication_extended_status’] = &amp;lt;driver specific value&amp;gt;
- volume[‘driver_data’] = &amp;lt;driver specific value&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Get Replication Status:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;This will be used to update the status of replication between the primary and
secondary volume.&lt;/p&gt;
&lt;p&gt;This function is called by the “_update_replication_relationship_status”
function in ‘manager.py’ and is the mechanism to update the status
replication between the primary and secondary copies.&lt;/p&gt;
&lt;p&gt;The actual state of the replication, as the storage backed is aware of,
should be returned and the Cinder database should be updated to reflect the
status reported from the storage backend.&lt;/p&gt;
&lt;p&gt;It is expected that the following model update for the volume will
happen:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;volume[‘replication_status’] = &amp;lt;error | copying | active | active-stopped |
inactive&amp;gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;‘error’ if an error occurred with replication.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;‘copying’ replication copying data to secondary (inconsistent)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;‘active’ replication copying data to secondary (consistent)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;‘active-stopped’ replication data copy on hold (consistent)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;‘inactive’ if replication data copy is stopped (inconsistent)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;volume[‘replication_extended_status’] = &amp;lt;driver specific value&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;volume[‘driver_data’] = &amp;lt;driver specific value&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Note for get replication status, that the replication_extended_status and
driver_data may not need to be updated.&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Promote replica:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;Promotion of a replica means that the secondary volume will take over
for the primary volume.  This can be thought of as a ‘fail over’ operation.
Once promotion has happened replication between the two volumes, at the
storage level, should be stopped, the replica should be available to be
attached and the replication status should be changed to ‘inactive’ if the
change is successful, otherwise it should be ‘error’.&lt;/p&gt;
&lt;p&gt;A model update for the volume is returned.&lt;/p&gt;
&lt;p&gt;As with the functions above, the volume driver is expected to update the
volume dictionary as follows:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;volume[‘replication_status’] = &amp;lt;error | inactive&amp;gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;‘error’ if an error occurred with replication.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;‘inactive’ if replication data copy on hold (inconsistent)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;volume[‘replication_extended_status’] = &amp;lt;driver specific value&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;volume[‘driver_data’] = &amp;lt;driver specific value&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Re-enable replication:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;Re-enabling replication would be used to fix the replication between
the primary and secondary volumes.  Replication would need to be
re-enabled as part of the fail-back process to make the promoted
volume and the old primary volume consistent again.&lt;/p&gt;
&lt;p&gt;The volume driver returns a model update to reflect the actions taken.&lt;/p&gt;
&lt;p&gt;The backend driver is expected to update the following volume dictionary
entries:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;volume[‘replication_status’] = &amp;lt;error | copying | active | active-stopped |
inactive&amp;gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;‘error’ if an error occurred with replication.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;‘copying’ replication copying data to secondary (inconsistent)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;‘active’ replication copying data to secondary (consistent)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;‘active-stopped’ replication data copy on hold (consistent)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;‘inactive’ if replication data copy is stopped (inconsistent)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;volume[‘replication_extended_status’] = &amp;lt;driver specific value&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;volume[‘driver_data’] = &amp;lt;driver specific value&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Notes:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;The replication_extended_status should be used to store information that
the backend driver will need to track replication status.  For instance,
the Storwize driver, will use the replication_extended_status to track
the primary copy status and synchronization status for the primary volume
and the copy status, synchronization status and synchronization progress for
the replica (secondary) volume.&lt;/p&gt;
&lt;p&gt;The driver_data field may be, optionally, used to contain any additional data
that the backend driver may require.  Some backend drivers may not need to
use the driver_data field.&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Driver API:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;promote:  Promotes a replica that is in active or active-stopped state to&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;be the primary.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;reenable: Reenables replication on a volume that is in inactive,&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;active-stopped or error status.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Replication can be performed outside of Cinder, and OpenStack can be
unaware of it. However, this requires vendor specific scripts, and
is not visible to the admin user, as only the storage system admin
will see the replica and the state of the replication.
Also all recovery actions (failover, failback) will require both the
the storage and cloud admins to work together.
While replication in Cinder reduces the role of the storage admin to
only the setup phase, and the cloud admin is responsible for failover
and failback with (typically) no need for intervention from the cloud
admin.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;The volumes table will be updated:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add replication_status column (string) for indicating the status of
replication for a give volume.  Possible values are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;‘copying’ - Data is being copied between volumes, the secondary is
inconsistent.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;‘disabled’ - Volume replication is disabled.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;‘error’ - Replication is in error state.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;‘active’ - Data is being copied to the secondary and the secondary is
consistent.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;‘active-stopped’ - Data is not being copied to the secondary (on hold),
the secondary volume is consistent.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;‘inactive’ - Data is not being copied to the secondary, the secondary
copy is inconsistent.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add replication_extended_status column to contain details with regards
to replication status of the primary and secondary volumes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add replication_driver_data column to contain additional details that
may be needed by a vendor’s driver to implement replication on a backend.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;State diagram for replication (status)&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                                         &lt;span class="nb"&gt;any&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;
                                         &lt;span class="n"&gt;condition&lt;/span&gt;    &lt;span class="o"&gt;+-------+&lt;/span&gt;
&lt;span class="n"&gt;Create&lt;/span&gt; &lt;span class="n"&gt;volume&lt;/span&gt;   &lt;span class="o"&gt;+-----+&lt;/span&gt;                &lt;span class="o"&gt;+------------&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
                      &lt;span class="o"&gt;|&lt;/span&gt;                               &lt;span class="o"&gt;+---+---+&lt;/span&gt;
                      &lt;span class="o"&gt;|&lt;/span&gt;                                   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Storage&lt;/span&gt; &lt;span class="n"&gt;admin&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt;
                      &lt;span class="o"&gt;|&lt;/span&gt;                                   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;fix&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;
                      &lt;span class="o"&gt;|&lt;/span&gt;                                   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;check&lt;/span&gt; &lt;span class="n"&gt;will&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt;
                &lt;span class="o"&gt;+-----+-----+&lt;/span&gt;                             &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+-------------&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;copying&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="nb"&gt;any&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;               &lt;span class="o"&gt;+-----+-----+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="n"&gt;check&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="n"&gt;check&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;               &lt;span class="o"&gt;+----+-----+&lt;/span&gt; &lt;span class="o"&gt;+------&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;+----------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;active&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;active&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;stopped&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;               &lt;span class="o"&gt;+----+-----+&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;------+&lt;/span&gt; &lt;span class="o"&gt;+----------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="n"&gt;check&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;promote&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;primary&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;enable&lt;/span&gt;     &lt;span class="o"&gt;+----+-----+&lt;/span&gt;
&lt;span class="o"&gt;+------------+&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;inactive&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
                &lt;span class="o"&gt;+----------+&lt;/span&gt;

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;Create volume API will have “source-replica” added:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"volume"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"source-replica"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Volume uuid of primary to clone"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Promote volume to be the primary volume&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Promote the secondary copy to be primary. the primary will become
secondary and Replication should become inactive.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Method type: POST&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Normal Response Code: 202&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Expected error http response code(s)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;500: Replication is not enabled for volume&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;500: Replication status for volume must be active or active-stopped,
but current status is: &amp;lt;status&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;500: Volume status for volume must be available, but current status
is: &amp;lt;status&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;V2/&amp;lt;tenant id&amp;gt;/volumes/os-promote-replica/&amp;lt;volume uuid&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This API has no body&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Re-enable replication between the primary and secondary volume.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Re-enable the replication between the primary and secondary volume.
Typically follows a promote operation on the replication.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Method type: POST&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Normal Response Code: 202&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Expected error http response code(s)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;500: Replication is not enabled&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;500: Replication status for volume must be inactive, active-stopped,
or error, but current status is: &amp;lt;status&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;/v2/&amp;lt;tenant id&amp;gt;/volumes/os-reenable-replica/&amp;lt;volume uuid&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This API has no body&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Does this change touch sensitive data such as tokens, keys, or user data?
&lt;em&gt;No&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Does this change alter the API in a way that may impact security, such as
a new way to access sensitive information or a new way to login?
&lt;em&gt;No&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Does this change involve cryptography or hashing?
&lt;em&gt;No&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Does this change require the use of sudo or any elevated privileges?
&lt;em&gt;No&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Does this change involve using or parsing user-provided data? This could
be directly at the API level or indirectly such as changes to a cache layer.
&lt;em&gt;No&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Can this change enable a resource exhaustion attack, such as allowing a
single API interaction to consume significant server resources? Some
examples of this include launching subprocesses for each connection, or
entity expansion attacks in XML.
&lt;em&gt;Yes&lt;/em&gt;, enabling replication consume cloud and storage resources.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;Will add notification for promoting and re-enabling replication for
volumes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;End-user to use volume types to enable replication.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cloud admin to use the &lt;em&gt;replication-promote&lt;/em&gt;, &lt;em&gt;replication-reenable&lt;/em&gt; and
&lt;em&gt;create –source-replica&lt;/em&gt; commands in the python-cinderclient to execute
failover, failback and test.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Extra db calls identifying if replication exists are added to retype,
snapshot operations, etc will add a small latency to these functions.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Added options for volume types (see above)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add new driver capabilities, needs to be supported by the volume drivers,
which may imply changes to the driver configuration options.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This change will require explicit enablement (to be used by users)
from the cloud administrator.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Change to the driver API is noted above. Third party backends that wish
to enable replication will need to add replication support to their driver.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The API will expand to include consistency groups following the merge of
consistency group support to Cinder.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;ronenkat&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Jay Bryant - E-Mail: &lt;a class="reference external" href="mailto:jsbryant%40us.ibm.com"&gt;jsbryant&lt;span&gt;@&lt;/span&gt;us&lt;span&gt;.&lt;/span&gt;ibm&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;   IRC: jungleboyj&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Cinder public (admin) APIs for replication&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DB schema updates for replication&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cinder driver API additions for replication&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cinder manager update for replication&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Related blueprints: Consistency groups
&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/consistency-groups"&gt;https://blueprints.launchpad.net/cinder/+spec/consistency-groups&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;LVM to support replication using DRBD, in a separate contribution.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Testing in gate is not supported due to the following considerations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;LVM has no replication support, to be addressed using DRBD in a separate
contribution.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;requires setting up at least two nodes using DRBD&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Should be discussed/addressed as support for LVM is added.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;3rd party driver CI will be expected to test replication.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Public (admin) API changes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Details how replication is used by leveraging volume types.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Driver docs explaining how replication is setup for each driver.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Provide examples of volume replication implementation for
the Storwize backend.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Etherpad on improvements needed in documentation:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://etherpad.openstack.org/p/cinder-replication-redoc"&gt;https://etherpad.openstack.org/p/cinder-replication-redoc&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
</description><pubDate>Thu, 16 Nov 2017 00:00:00 </pubDate></item><item><title>Introduce abstract interface model in volume drivers</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/kilo/abc-volume-drivers.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/abc-volume-drivers"&gt;https://blueprints.launchpad.net/cinder/+spec/abc-volume-drivers&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Instead of using a loose interface definition of volumes drivers use the ABC
python library to build abstract classes that enforces the driver to implement
the needed functionality. Goal is to fail fast and not using exceptions during
runtime if the driver is not using the correct interface.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;The defined volume interface in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cinder.volume.driver&lt;/span&gt;&lt;/code&gt; is quite lose. A
driver can decide whether to implement a certain functionality or not. From
the outside (manager layer) it is not visible which functionality a driver
implements. So the only way to discover that is to try to call a function of
a feature set and to see if it raises a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;NotImplementedError&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Build a base VolumeDriver class and subclasses that describe feature sets,
like:&lt;/p&gt;
&lt;div class="highlight-console notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="go"&gt;                         +-------------------------+&lt;/span&gt;
&lt;span class="go"&gt;        +----------------+     BaseVolumeDriver    +---------------+&lt;/span&gt;
&lt;span class="go"&gt;        |                |       {abstract}        |               |&lt;/span&gt;
&lt;span class="go"&gt;        |                +-----------^-------------+               |&lt;/span&gt;
&lt;span class="go"&gt;        |                            |                             |&lt;/span&gt;
&lt;span class="go"&gt;        |                            |                             |&lt;/span&gt;
&lt;span class="go"&gt;+-------+-------------+  +-----------+-------------+  +------------+---------+&lt;/span&gt;
&lt;span class="go"&gt;| VolumeDriverBackup  |  |   VolumeDriverSnapshot  |  |  VolumeDriverImport  |&lt;/span&gt;
&lt;span class="go"&gt;|     {abstract}      |  |      {abstract}         |  |      {abstract}      |&lt;/span&gt;
&lt;span class="go"&gt;+---------------------+  +-------------------------+  +----------------------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;If a driver implements the backup functionality and supports volume import it
should inherit from the interface classes like:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;FooDriver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;VolumeDriverBackup&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;VolumeDriverImport&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The management layer can observe the feature set’s of a given driver by using
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;isinstanceof()&lt;/span&gt;&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;volume_driver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;FooDriver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;isinstanceof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;volume_driver&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;VolumeDriverBackup&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;pass&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Usage of python &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ABC&lt;/span&gt;&lt;/code&gt; is preferable since it gives a variety of advantages
(see [1], [2]). It will fail on instantiation level with an TypeExcetion.
Other OpenStack project already using this library (see [3]).&lt;/p&gt;
&lt;section id="driver-migration"&gt;
&lt;h3&gt;Driver Migration&lt;/h3&gt;
&lt;p&gt;Instead of changing all drivers in one big step it better to migrate
stepwise. In order to do so the VolumeDriver class can exist with the same
interface and use &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;NotImplementedError&lt;/span&gt;&lt;/code&gt; exceptions as before. With that all
existing drivers can be migrated to the new concept one after another.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Only implement subclasses and don’t use &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ABC&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;There is no heavy performance implication expected due to the reason ABCMeta
and it’s functionality is only very limited used inside of the relevant data
path. The following general object function are potential less performant than
before (see [5]):&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="fm"&gt;__new__&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="fm"&gt;__subclasscheck__&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nb"&gt;issubclass&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="fm"&gt;__instancecheck__&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nb"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The performance is depending on the depths of used class hierarchy. The
proposed concept is quite plain in that aspect (maximum 2 levels). In general
it’s a comparison between the used cycles for raising/catching an exception
and iteration in a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;for&lt;/span&gt; &lt;span class="pre"&gt;loop&lt;/span&gt;&lt;/code&gt; over all abstract classes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;This change will change all implemented drivers slightly. The functionality
itself shouldn’t  be changed at all but all driver need to be adopted to the
new class model.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Marc Koderer (m-koderer)&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Danny Al-Gaaf (danny-al-gaaf)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;Will be tracked in etherpad.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit tests need to be adapted massively since there are catching
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;NotImplementedError&lt;/span&gt;&lt;/code&gt; exceptions all over the place.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;[1]: &lt;a class="reference external" href="http://legacy.python.org/dev/peps/pep-3119/"&gt;http://legacy.python.org/dev/peps/pep-3119/&lt;/a&gt;
[2]: &lt;a class="reference external" href="http://dbader.org/blog/abstract-base-classes-in-python"&gt;http://dbader.org/blog/abstract-base-classes-in-python&lt;/a&gt;
[3]: &lt;a class="reference external" href="http://lists.openstack.org/pipermail/openstack-dev/2013-August/014089.html"&gt;http://lists.openstack.org/pipermail/openstack-dev/2013-August/014089.html&lt;/a&gt;
[4]: &lt;a class="reference external" href="https://bugs.launchpad.net/tempest/+bug/1346797"&gt;https://bugs.launchpad.net/tempest/+bug/1346797&lt;/a&gt;
[5]: &lt;a class="reference external" href="https://hg.python.org/cpython/file/2.7/Lib/abc.py"&gt;https://hg.python.org/cpython/file/2.7/Lib/abc.py&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 16 Nov 2017 00:00:00 </pubDate></item><item><title>Add support for chiscsi iscsi helper</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/kilo/chiscsi-iscsi-helper.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/chiscsi-iscsi-helper"&gt;https://blueprints.launchpad.net/cinder/+spec/chiscsi-iscsi-helper&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The Chelsio iSCSI target(chiscsi) serves as a drop in replacement for the IET
target, aiming to provide the same functionality as IET. This spec aims at
adding support for said target implementation as a pure iscsi_helper.&lt;/p&gt;
&lt;p&gt;chiscsi supports offloading of iSCSI PDU’s when required hardware (supported
Chelsio Network cards) is available but will work on any regular NIC as well.
Offloading or lack thereof requires no user intervention once target drivers
are installed. Implementation is initiator agnostic as well, no changes needed
on initiator side.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;chiscsi target is not currently supported by openstack&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;For a Deployer trying to use offloaded iSCSI support on target side, no
option is currently available.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Manual intervention is currently required to export volumes, as cinder does
not understand chiscsi target implementation.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Add one more iscsi_helper option to cover chiscsi, the driver for this will
interact with the chiscsi target implementation to provide same functionality
as iet.&lt;/p&gt;
&lt;p&gt;Use of offloading is dependent on required hardware being present but is
completely optional. No intervention is required to enable offload and
offloading will happen in a manner completely transparent to initiator side.&lt;/p&gt;
&lt;p&gt;No initiator side changes are required to make use of chiscsi, with or without
offload support. No extra configuration options are required.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;If iSCSI offload is available, there is a significant performance boost to be
gained. If offloading is not used, performance and resource usage would be
roughly on par with IET or better.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;No new config options are required besides an extra allowed value for
‘iscsi_helper’ that would need to be explicitly set to ‘chiscsi’.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;chiscsi target needs to be installed before it can be used.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;anish7&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;kxie&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;Using iet helper as base, create iscsi_helper for chiscsi, with equivalent
commands for all required apis&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Ability to use chiscsi target obviously depends on target driver being
installed, and command utility available on path. No other dependencies&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Current test for IET target should work just fine for chiscsi&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None except listing chiscsi as an available iscsi_helper&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://www.chelsio.com/iscsi-target-software/"&gt;http://www.chelsio.com/iscsi-target-software/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Thu, 16 Nov 2017 00:00:00 </pubDate></item><item><title>Consistency Groups Kilo Update</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/kilo/consistency-groups-kilo-update.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/consistency-groups-kilo-update"&gt;https://blueprints.launchpad.net/cinder/+spec/consistency-groups-kilo-update&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Consistency Groups support was introduced in Juno. This proposal is to
enhance it by adding a few new features.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Create CG from CG snapshot&lt;/p&gt;
&lt;p&gt;Currently a user can create a Consistency Group and create a snapshot of a
Consistency Group.  To restore from a Cgsnapshot, however, the following
steps need to be performed:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Create a new Consistency Group.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Do the following for every volume in the Consistency group:&lt;/p&gt;
&lt;ol class="loweralpha simple"&gt;
&lt;li&gt;&lt;p&gt;Call “create volume from snapshot” for snapshot associated with every
volume in the original Consistency Group.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;There’s no single API that allows a user to create a Consistency Group from
a Cgsnapshot.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify CG
After a CG is created and volumes are created and added to CG, you can
delete the entire CG with all volumes in it, but there’s no API to add an
existing volume to the CG or remove a volume from it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DB Schema Changes
Volume types are required when creating a Consistency Group.  Currently
volume types are stored in a field in the consistencygroups table in the
Cinder database.  There’s a limitation to this approach, however, because
the size of the column is fixed.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Create CG from CG snapshot&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add an API that allows a user to create a Consistency Group from a
Cgsnapshot.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a Volume Driver API accordingly.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify Consistency Group&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add an API that adds existing volumes to CG and removing volumes from CG
after it is created.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a Volume Driver API accordingly.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DB Schema Changes&lt;/p&gt;
&lt;p&gt;The following changes are proposed:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;A new cg_volumetypes table will be created.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This new table will contain 3 columns:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;uuid of a cg_volumetype entry&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;uuid of a consistencygroup&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;uuid of a volume type&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Upgrade and downgrade functions will be provided for db migrations.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Without these propsed changes, we have to deal with the current limitations.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;DB Schema Changes
The following changes are proposed:
* A new cg_volumetypes table will be created.
* This new table will contain 3 columns:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;uuid of a cg_volumetype entry&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;uuid of a consistencygroup&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;uuid of a volume type&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;New Consistency Group APIs changes&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Create Consistency Group from Cgsnapshot
* V2/&amp;lt;tenant id&amp;gt;/consistencygroups
* Method: POST
* JSON schema definition for V2:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"consistencygroup"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"my_cg"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"My consistency group"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"cgsnapshot"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;my_cgsnapshot&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;In the Create Consistency Group API, if cgsnapshot is not specified, the
code path stays the same as before and the request goes to the scheduler;
If cgsnapshot is specified, the request will be sent to the backend where
the original Consistency Group resides.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cinder API will be responsible for creating the consistencygroup entry
and volume entries in the database. Cinder driver will be responsible for
creating it in the backend.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update Consistency Group
* V2/&amp;lt;tenant id&amp;gt;/consistencygroups/&amp;lt;cg uuid&amp;gt;
* Method: PUT
* JSON schema definition for V2:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"consistencygroup"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"my_cg"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"My consistency group"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"addvolumes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;volume&lt;/span&gt; &lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;volume&lt;/span&gt; &lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="s2"&gt;"removevolumes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;volume&lt;/span&gt; &lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;volume&lt;/span&gt; &lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;This method can update name, description, as well as volumes in the
consistency group. The list after “addvolumes” will contain UUIDs of
volumes to be added to the group and the list after “removevolumes”
will contain UUIDs of volumes to be removed from the group. The API
will validate the input name, description, UUIDs in addvolumes and
removevolumes fields against the information in Cinder db and send
the request to the volume manager. Manager will call driver to do
the update on the backend. The API will update Cinder db.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cinder Volume Driver API&lt;/p&gt;
&lt;p&gt;The following new volume driver APIs will be added:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;create_consistencygroup_from_cgsnapshot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;consistencygroup&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cgsnapshot&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;snapshots&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;modify_consistencygroup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;consistencygroup&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;old_volumes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;new_volumes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;python-cinderclient needs to be changed to support the new APIs.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Create CG from CG snapshot&lt;/p&gt;
&lt;div class="highlight-bash notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;cinder&lt;span class="w"&gt; &lt;/span&gt;consisgroup-create&lt;span class="w"&gt; &lt;/span&gt;--name&lt;span class="w"&gt; &lt;/span&gt;&amp;lt;name&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;--description&lt;span class="w"&gt; &lt;/span&gt;&amp;lt;description&amp;gt;
--cgsnapshot&lt;span class="w"&gt; &lt;/span&gt;&amp;lt;cgsnapshot&lt;span class="w"&gt; &lt;/span&gt;uuid&lt;span class="w"&gt; &lt;/span&gt;or&lt;span class="w"&gt; &lt;/span&gt;name&amp;gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify CG&lt;/p&gt;
&lt;div class="highlight-bash notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;cinder&lt;span class="w"&gt; &lt;/span&gt;consisgroup-modify&lt;span class="w"&gt; &lt;/span&gt;&amp;lt;cg&lt;span class="w"&gt; &lt;/span&gt;uuid&lt;span class="w"&gt; &lt;/span&gt;or&lt;span class="w"&gt; &lt;/span&gt;name&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;--name&lt;span class="w"&gt; &lt;/span&gt;&amp;lt;new&lt;span class="w"&gt; &lt;/span&gt;name&amp;gt;
--description&lt;span class="w"&gt; &lt;/span&gt;&amp;lt;new&lt;span class="w"&gt; &lt;/span&gt;description&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;--addvolumes
&amp;lt;volume&lt;span class="w"&gt; &lt;/span&gt;uuid&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&amp;lt;volume&lt;span class="w"&gt; &lt;/span&gt;uuid&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;...&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;--removevolumes
&amp;lt;volume&lt;span class="w"&gt; &lt;/span&gt;uuid&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&amp;lt;volume&lt;span class="w"&gt; &lt;/span&gt;uuid&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;...&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None. The db schema changes are internal and should be transparent to
end users.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Driver developers can implement the new driver APIs.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;xing-yang&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Other contributors:&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;API changes:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create CG from CG snapshot API&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify CG API&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Volume Driver API changes:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create CG from CG snapshot&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify CG&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DB schema changes&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;New unit tests will be added to test the changed code.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Documentation changes are needed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;/section&gt;
</description><pubDate>Thu, 16 Nov 2017 00:00:00 </pubDate></item><item><title>Failover to alternative iSCSI portals on login failure</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/kilo/iscsi-alternative-portal.html</link><description>

&lt;p&gt;Include the URL of your launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/iscsi-alternative-portal"&gt;https://blueprints.launchpad.net/cinder/+spec/iscsi-alternative-portal&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This spec proposes to add fail-over feature to alternative iSCSI portals on
attaching iSCSI volumes when the main iSCSI portal is unaccessible.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;When the main iSCSI portal is unreachable by network failure etc., volume
attach/detach will fail even though the other portal addresses is reachable.
To enable nova-compute to fall-back to alternative portal addresses, cinder
should tell the alternative portal addresses to nova.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Add optional parameters ‘target_alternative_portals’,
‘target_alternative_iqns’, and ‘target_alternative_luns’ into ‘connection_info’
returned by os-initialize_connection volume action API that represents a list
of alternative addresses of the iSCSI portals and the corresponding iqn and lun
to each portal. (iqns and luns can be the same when the addresses are pointing
the same portal.)&lt;/p&gt;
&lt;p&gt;When nova-compute recognizes these parameters, it will fall-back to alternative
portal address/target/lun specified by the parameters on failure during
discovery. Old nova-compute just ignores the new parameters, so it works
without changes if the primary portal address is alive.&lt;/p&gt;
&lt;p&gt;Note that this proposal is for single iSCSI data path use-case (fail-over).
This means, if the primary portal and target is failed, the other LUNs already
attached on the path will be unaccessible until the path is recovered manually.
Multiple data path (multipath) use-case is covered with another spec.&lt;/p&gt;
&lt;p&gt;This change must be applied also to cinder/brick/initiator.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;Backend drivers, if they need, may put multiple portal addresses and iqns into
‘provider_location’ field of volume tables.&lt;/p&gt;
&lt;p&gt;For example, the LVM iSCSI driver will put the addresses in the following
format in order to pass them as a volume dict to target admin helpers:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;provider_location = ‘&amp;lt;portal ip&amp;gt;:&amp;lt;port&amp;gt;;&amp;lt;portal ip 2&amp;gt;:&amp;lt;port&amp;gt;,&amp;lt;portal&amp;gt; &amp;lt;iqn&amp;gt;’&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;e.g.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;provider_location = ‘10.0.1.2:3260;10.0.2.2:3260,0 iqn.2010-10.org.openstack:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;volume-12345678-abcd-1234-5678-12345678abcd’&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;(Note that ‘volume-12345678…’ is a name of target, not a volume; they are
the same in LVM iSCSI driver.)&lt;/p&gt;
&lt;p&gt;Other backend drivers can add multiple portal addresses and iqns into
cinder.conf, or can retrieve them dynamically from the array.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;‘os-initialize_connection’ volume action API response may have additional
parameters ‘target_alternative_portals’ and ‘target_alternative_iqns’, which
contain a list of portal IP address:port pairs, a list of alternative iqn’s and
lun’s corresponding to each portal address. For example:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"connection_info"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"driver_volume_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"iscsi"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;
                     &lt;span class="s2"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"target_portal"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"10.0.1.2:3260"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                              &lt;span class="s2"&gt;"target_alternative_portals"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                                               &lt;span class="s2"&gt;"10.0.2.2:3260"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                               &lt;span class="s2"&gt;"10.0.3.2:3260"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                              &lt;span class="s2"&gt;"target_iqn"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"iqn.2014-2.org.example:vol1-1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                              &lt;span class="s2"&gt;"target_alternative_iqns"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                                            &lt;span class="s2"&gt;"iqn.2014-2.org.example:vol1-2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                            &lt;span class="s2"&gt;"iqn.2014-2.org.example:vol1-3"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                              &lt;span class="s2"&gt;"target_lun"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                              &lt;span class="s2"&gt;"target_alternative_luns"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                              &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;}}}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;In this case,
“iqn.2014-2.org.example:vol1-1”, lun=1 is for portal “10.0.1.2:3260”,
“iqn.2014-2.org.example:vol1-2”, lun=2 is for portal “10.0.2.2:3260”, and
“iqn.2014-2.org.example:vol1-3”, lun=3 is for portal “10.0.3.2:3260”.&lt;/p&gt;
&lt;p&gt;The portals may have the same targets and/or luns in some backends.&lt;/p&gt;
&lt;p&gt;Backend drivers are responsible to specify the order of alternative portals.
Nova and Cinder brick library should first try connecting to the main portal
and target. If failed, it should try connecting to the alternative portals and
targets in the order of the list provided. For example, if a backend driver
wants to round-robin portals for each LUN, the driver may return different
portal addresses as main addresses for LUNs in the same target.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;p&gt;Note that if any CHAP credentials are provided in connection_info, they must
be applied on the all target_portals.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;Backend driver may have additional settings to enable alternative iSCSI
portals. For example, to utilize this feature in iSCSI LVM driver, we needs to
specify a list of alternative IP addresses of the cinder-volume node where
iSCSI targets run on.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;To enable multiple iSCSI portals functionality, backend drivers must change
the implementation of initialize_connection method to return the additional
parameters ‘target_alternative_portals’, ‘target_alternative_iqns’ and
‘target_alternative_luns’.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;tsekiyama&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Implement this feature in LVM iSCSI driver as a sample&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify Nova and Cinder brick library to fail-over to alternative portals&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit tests should be added for drivers which support this feature, so that
initialize_connection will return correct connection_info.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To test this feature in tempest, multiple addresses must be asigned to the
test environment in order to access alternative portal addresses.
Implementation in LVM iSCSI driver would be useful for testing.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;A section to describe this feature should be added.&lt;/p&gt;
&lt;p&gt;If the driver needs additional settings for this feature, the documentation
for them should be added.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;nova-specs: Failover to alternative iSCSI portals on login failure
&lt;a class="reference external" href="https://review.openstack.org/#/c/137468/"&gt;https://review.openstack.org/#/c/137468/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;cinder-specs: Enhance iSCSI multipath support (multipath use-case)
&lt;a class="reference external" href="https://review.openstack.org/#/c/136500/"&gt;https://review.openstack.org/#/c/136500/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Thu, 16 Nov 2017 00:00:00 </pubDate></item><item><title>Enhance iSCSI multipath support</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/kilo/iscsi-multipath-enhancement.html</link><description>

&lt;p&gt;Include the URL of your launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/enhance-iscsi-multipath"&gt;https://blueprints.launchpad.net/cinder/+spec/enhance-iscsi-multipath&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This spec proposes to enhance iSCSI multipath support by defining the way to
tell multiple iSCSI portals/iqns/luns to access a volume (LU) to Nova.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently, nova-compute supports multipath for iSCSI volume data path.
It depends on response to targets discovery of from the main iSCSI portal,
expecting multiple portal addresses are contained.&lt;/p&gt;
&lt;p&gt;However, some arrays only respond to discovery with a single portal address,
even if secondary portals are available. In this case, nova-compute cannot know
secondary portals and corresponding iSCSI target IQN, so nova-compute cannot
establish multiple sessions for the target(s). To enable nova-compute to
login to secondary portals, cinder should tell the secondary portal
addresses and corresponding target iqns/luns.&lt;/p&gt;
&lt;p&gt;Telling secondary portal addresses and iqns/luns is also useful for arrays
which can respond to discovery with multiple portals addresses and IQNs, since
compute can access to the volume via secondary portals even when the main
portal is unaccessible due to network trouble.
(Note that compute should attach the volume via multipath device “dm-X” so
that the session to the main portal can be re-established when the network
is recovered.)&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;If nova-compute can support multipath for iSCSI (that is, if multipathd is
installed and CONF.libvirt.iscsi_use_multipath is set True), nova-compute
should call Cinder initialize_connection API with a new ‘multipath=True’
optional key in ‘connector’ dictionary. This parameter is passed to the
backend driver so that the driver can export a volume to multiple ports.&lt;/p&gt;
&lt;p&gt;When the ‘multipath=True’ is specified, ‘connection_info’ of the API response
will contain multiple portal addresses and corresponding target iqns/luns.
Current ‘target_portal’/’target_iqn’/’target_lun’ parameters will be replaced
with ‘target_portals’/’target_iqns’/’target_luns’ which have a list of the
addresses of the iSCSI portals and the corresponding iqn/lun to each portal.
When nova-compute recognizes these parameters, it will log into every
portal address/target/lun. When the backend doesn’t support (or not configured
to support) multipath, the driver may return current ‘target_portal’/
‘target_iqn’/’target_lun’ set.&lt;/p&gt;
&lt;p&gt;When the ‘multipath=False’ is specified or the key is omitted, the API must
return ‘target_portal’/’target_iqn’/’target_lun’ set.&lt;/p&gt;
&lt;p&gt;This change must be applied also to cinder/brick/initiator.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;‘os-initialize_connection’ volume action API will take new optional parameter
‘multipath’ in the connector argument, that means the connector can handle
multipath to iSCSI volumes.&lt;/p&gt;
&lt;p&gt;When the ‘multipath=True’ is specified, ‘os-initialize_connection’ volume
action API respond with ‘target_portals’/’target_iqns’/’target_luns’ in
‘connection_info’ which contain a list of portal IP address:port pairs,
a list of secondary iqn’s and lun’s corresponding to each portal address.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"connection_info"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"driver_volume_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"iscsi"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;
                     &lt;span class="s2"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"target_portals"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"10.0.1.2:3260"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                                 &lt;span class="s2"&gt;"10.0.2.2:3260"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                              &lt;span class="s2"&gt;"target_iqns"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                                            &lt;span class="s2"&gt;"iqn.2014-2.org.example:vol1-1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                            &lt;span class="s2"&gt;"iqn.2014-2.org.example:vol1-2"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                              &lt;span class="s2"&gt;"target_luns"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                              &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;}}}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;In this case,
“iqn.2014-2.org.example:vol1-1”, lun=1 is for portal “10.0.1.2:3260”, and
“iqn.2014-2.org.example:vol1-2”, lun=2 is for portal “10.0.2.2:3260”.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;p&gt;Note that if any CHAP credentials are provided in connection_info, they must
be applied on the all target_portals.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Since nova-compute can omit discovery query to find multiple portals and
targets, this change may make volume-attach/detach operations faster.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;Backend driver may have additional settings to enable iSCSI portal multipath.
For example, to utilize this feature in iSCSI LVM driver, we needs to
specify a list of secondary IP addresses of the cinder-volume node where iSCSI
targets run on.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;If drivers want to use iSCSI multipath, and the connector has the
‘multipath=True’ value, then drivers should change to return ‘target_portals’,
‘target_iqns’ and ‘target_luns’.&lt;/p&gt;
&lt;p&gt;Existing drivers that support target_portal discovery via the existing
process won’t need to change unless they want to honor the ‘multipath=True’
connector entry when exporting a volume.&lt;/p&gt;
&lt;p&gt;Existing drivers which support multipath with the existing design must work
even if they don’t support this change. Such drivers will return single
‘target_portal’/’target_iqn’/’target_lun’ even if ‘multipath=True’ is
specified. Then the connector must send discovery query to the returned portal
in order to find the multipath portals and targets, like the existing design.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;tsekiyama&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Implement this feature in LVM iSCSI driver as a sample&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enable nova and brick library to handle multiple portals/iqns/luns.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit tests should be added for drivers which support this feature, so that
initialize_connection will return correct connection_info.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To test this feature in tempest, multiple addresses must be asigned to the
test environment in order to establish multiple sessions to volumes.
Implementation in LVM iSCSI driver would be useful for testing.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;A section to describe this feature should be added.&lt;/p&gt;
&lt;p&gt;If the driver needs additional settings for this feature, the documentation
for them should be added.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Enable multipath for libvirt iSCSI Volume Driver (merged)
&lt;a class="reference external" href="https://review.openstack.org/#/c/17946/"&gt;https://review.openstack.org/#/c/17946/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Failover to alternative iSCSI portals on login failure (for single path)
&lt;a class="reference external" href="https://review.openstack.org/#/c/131502/"&gt;https://review.openstack.org/#/c/131502/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Nova-specs: Support iSCSI portal multipath
&lt;a class="reference external" href="https://review.openstack.org/#/c/134299/"&gt;https://review.openstack.org/#/c/134299/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Thu, 16 Nov 2017 00:00:00 </pubDate></item><item><title>Limit Volume Copy Bandwidth Per Backend</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/kilo/limit-volume-copy-bps-per-backend.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/limit-volume-copy-bps-per-backend"&gt;https://blueprints.launchpad.net/cinder/+spec/limit-volume-copy-bps-per-backend&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Currently, cinder has a global configuration to limit a volume copy bandwidth
to mitigate slow down of instances volume access during large image copies.
( &lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/limit-volume-copy-bandwidth"&gt;https://blueprints.launchpad.net/cinder/+spec/limit-volume-copy-bandwidth&lt;/a&gt; )&lt;/p&gt;
&lt;p&gt;This spec proposes to make this config variable per backend.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;The current global config has some issues.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;When multiple backends exist, we cannot assign different bandwidth limit.
For instance, it is desirable to allow large bps for SSD than for HDD.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If volume copy runs concurrently, bandwidth larger than the bps limit is
consumed. From the viewpoint of QoS (to keep bandwidth for access from
instances), we should limit total volume copy bandwidth per backend.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Make the cinder.conf parameter ‘volume_copy_bps_limit’ writable in each
backend section. (If volume_copy_bps_limit is specified in DEFAULT section as
existing design, that value is used as a global default. This keeps backwards
compatibility.)&lt;/p&gt;
&lt;p&gt;The bps limit is divided if multiple volume copy operations run concurrently.
For example, if volume_copy_bps_limit is set to 100MB/s, and 2 copies are
running at the same time in a backend, each copy can use up to 50MB/s.
If one of the copies finished, the other copy’s limit is updated to 100MB/s.&lt;/p&gt;
&lt;p&gt;On initialization of VolumeDriver class, a ‘Throttle’ class object is created
and stored in ‘_throttle’ member for each backend driver object, that manages
the total bandwidth allowed and volume copy operations in flight.&lt;/p&gt;
&lt;p&gt;It should be passed to copy_volume() as following, so that it can set/update
the bandwidth limit.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;volume_utils.copy_volume(…, throttle=self._throttle)&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;In copy_volume method, Throttle class method is called to setup cgroups
(or some other QoS feature, when the Throttle class is overridden).&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;When volume copy I/O bandwidth is limited, it takes more time to complete
volume copy. Users are required to balance between volume copy performance
and interference to instances performance.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;This feature is disabled by default. Users who want to use this feature need
to set ‘volume_copy_bps_limit’ in cinder.conf.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;A ‘_throttle’ member is added to VolumeDriver class, which should be passed
to volume_utils.copy_volume() and related function. Otherwise, bandwidth
limit will be ignored.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In Linux environments, ‘_throttle’ object will be implemented using cgroups.
Drivers for non-Linux environments (e.g. Windows) can override the
initialization of ‘_throttle’ to use another method for throttling.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;tsekiyama (&lt;a class="reference external" href="mailto:tomoki.sekiyama%40hds.com"&gt;tomoki&lt;span&gt;.&lt;/span&gt;sekiyama&lt;span&gt;@&lt;/span&gt;hds&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Use ‘backend_driver.configuration.volume_copy_bps_limit’ etc. if
‘CONF.volume_copy_bps_limit’ is not specified.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Replace current setup_blkio_cgroup() with new ‘Throttle’ class&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pass the Throttle object from the backend drivers to copy_volume()&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;With volume_copy_bps_limit = 100MB/s for a fake backend driver:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;start a volume copy, then the bps limit is set to 100MB/s&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;start a second volume copy, then the limit is updated to 50MB/s for both&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;finish one of the copies, then the limit is resumed to 100MB/s&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;The cinder client documentation about volume_copy_bps_limit in cinder.conf
should address that copy bps limit can be specified for each backend driver
by writing this config in the backend section.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 16 Nov 2017 00:00:00 </pubDate></item><item><title>Adopt Guru Meditation report</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/liberty/adopt-guru-meditation-report.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/guru-meditation-report"&gt;https://blueprints.launchpad.net/cinder/+spec/guru-meditation-report&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This spec proposes adoption for Oslo Guru Meditation reports in Cinder.
The new feature will enhance debugging capabilities of all official Cinder
services, by providing an easy way to gather runtime data about current
threads and configuration, among other things, to developers, operators,
and tech support.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently Cinder does not have a way to gather runtime data from active
service processes. The only information that is available to deployers,
developers, and tech support to analyze is what was actually logged by the
service in question. Additional data could be usefully used to debug and solve
problems that occur during Cinder operation. Among other things, we could be
interested in stack traces of all (both green and real) threads, pid/ppid info,
package version, configuration as seen by the service, etc.&lt;/p&gt;
&lt;p&gt;Oslo Guru reports provide an easy way to add support for gathering this kind of
information to any service. Report generation is triggered by sending a special
(USR1) signal to a service. Reports are generated on stderr, that can be piped
into system log, if needed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;Guru reports are extensible, meaning that we will be able to add more
information to those reports in case we see it needed.&lt;/p&gt;
&lt;p&gt;Guru reports has been supported by Nova.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;First, a new oslo-incubator module (reports.*) should be synchronized into
cinder tree. Then, each service entry point should be extended to register
reporting functionality before proceeding to its real main().&lt;/p&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;In theory, the change could expose service internals to someone who is able to
send the needed signal to a service. That said, we can probably assume that the
user is already authorized to achieve a lot more than just having an access to
stack traces and configuration used. Also, if deployers are afraid of the
information leak for some reason, they could also make sure their stderr output
is channeled into safe place.&lt;/p&gt;
&lt;p&gt;Because this report is triggered by user, there is no need to add config option
to turn on/off this feature.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;The feature does not require any additional resources until it’s triggered by
the user. Default report generation is not expected to take too long. Report
extensions will need to be assessed on case by case basis. In any case, reports
are not expected to be generated too often and are assumed to be debugging
capability, not something to trigger once per minute just in case.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;Deployers may be interested in making sure those reports are collected
somewhere (e.g. stderr should be captured by syslog).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;We could reimplement the wheel, but we hopefully won’t.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;wanghao&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;sync reports.* module from oslo-incubator&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;adopt it in all cinder services using a wrapper located under
cinder/cmd/…&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;reports.* module is currently going thru graduation consideration. In case it’s
graduated into oslo.reports library before cinder switches to it, we won’t
actually need to sync any code from oslo-incubator but instead add a new
external oslo dependency. If Cinder switches to the module before graduation
is complete, then we’ll need to adopt oslo.reports later as part of usual oslo
liaison effort.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Automated tests are needed to ensure the guru report is working correctly.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;User documentation will need to be updated to introduce this changes.&lt;/p&gt;
&lt;p&gt;Developer documentation should be updated to include information on how to add
support for the reporting feature.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;oslo-incubator module: &lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/oslo-incubator/tree/openstack/common/report"&gt;http://git.openstack.org/cgit/openstack/oslo-incubator/tree/openstack/common/report&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;blog about nova guru reports: &lt;a class="reference external" href="https://www.berrange.com/posts/2015/02/19/nova-and-its-use-of-olso-incubator-guru-meditation-reports/"&gt;https://www.berrange.com/posts/2015/02/19/nova-and-its-use-of-olso-incubator-guru-meditation-reports/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;oslo.reports repo: &lt;a class="reference external" href="https://github.com/directxman12/oslo.reports"&gt;https://github.com/directxman12/oslo.reports&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Thu, 16 Nov 2017 00:00:00 </pubDate></item><item><title>Cinder internal tenant</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/liberty/cinder-internal-tenant.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/cinder-internal-tenant"&gt;https://blueprints.launchpad.net/cinder/+spec/cinder-internal-tenant&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This spec proposes the addition of config options and internal plumbing
required for a cinder-internal tenant. This tenant can then be used by Cinder
as the owner of internal objects that we don’t really want owned by any
normal users.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;There are several use cases for ‘internal’ cinder objects where we would like
to prevent a normal user from seeing them. The approach that seems to have
the most backing is to a special tenant that cinder can use for owning these
internal volumes/snapshots/etc.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;There are a few different use cases for the internal tenant. The generic use
case is for any volume or snapshot object in Cinder that we do not want
exposed to normal users, but would like to keep track of and have treated as
normal volumes and snapshots.&lt;/p&gt;
&lt;p&gt;There are a few features which would be able to take advantage of this:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Image Caching - Volumes (and potentially snapshots) that are used as part
of the image cache could be owned by the tenant.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Volume Migration - Temporary volumes while migrations are taking place could
be owned by the cinder-internal tenant.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Non-Disruptive Backups - Temporary snapshots and volumes could be owned by
the cinder-internal tenant.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;I think initially the easiest way to make this work is to add new config
options that take in the credentials for the tenant. This would require an
admin to create and configure the tenant manually and then set the values in
cinder.conf. These config options will be:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;cinder_internal_tenant_username&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;cinder_internal_tenant_password&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These config options will default to ‘None’. For some features like the image
cache this isn’t such a big deal. If the credentials are none, and the tenant
is unavailable the cache just won’t actually create cache objects and things
fall back to the original functionality. It will however be more difficult for
features like migration or backups where they may not be able to fall back
nicely to a behavior that does not need the credentials.&lt;/p&gt;
&lt;p&gt;Things like quota and other permissions would be managed by an admin only,
cinder will not modify things automatically. In the future it would be
possible to have default values for the config options, and allow cinder
to mange the tenant. That functionality will be out of scope for this initial
implementation.&lt;/p&gt;
&lt;p&gt;For the initial change I don’t think we should keep any of this info in the
cinder db. Everything comes from the config file and is re-checked at startup.&lt;/p&gt;
&lt;p&gt;Any usage of the tenants objects should assume they could be deleted or
cleaned up at any time, I don’t think this is any different than the case
today where a user could delete a second volume halfway through migration
though. So this is not a regression. The idea behind this being that as an
admin you could periodically clean these objects up if they start to
accumulate, but you wouldn’t really need to worry about which ones are ‘safe’.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Another way to approach this problem is to add ‘hidden’ flags to volumes and
snapshots. The biggest downside of this is that all API’s need to then know
about this and start filtering, and potentially clients and commands need
new ‘–hidden’ or ‘–show-all’ kind of flags. In addition these hidden volumes
may either take quota from a real user or not be accounted for at all.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;Care will need to be taken to ensure the tenant credentials are not exposed
to anyone other than cloud administrators and that users cannot create volumes
or other objects as the internal tenant.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;This change by itself shouldn’t have any end user impact. Things built on top
of it may change what a user sees while using commands like migrate.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;New config options and setup steps when configuring cinder.&lt;/p&gt;
&lt;p&gt;Additional documentation to read.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;New internal API’s to use to create objects as the internal tenant.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;patrick-east&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;None&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add in support for the new config options.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add in utility functions to get the tenant information and anything else
required to use the internal tenant for operations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Possibly add support in to DevStack to configure this by default for future
development on top of the feature.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation on how to create and configure the tenant.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit tests for the utility functions.&lt;/p&gt;
&lt;p&gt;This change by itself won’t require tempest test changes or additions, but
features utilizing it will.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;New instructions for how to create and configure the tenant in the
installation instructions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/trunk/config-reference/content/"&gt;http://docs.openstack.org/trunk/config-reference/content/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/user-guide-admin/"&gt;http://docs.openstack.org/user-guide-admin/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://eavesdrop.openstack.org/meetings/cinder/2015"&gt;http://eavesdrop.openstack.org/meetings/cinder/2015&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;/cinder.2015-05-27-16.00.log.html&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/image-volume-cache"&gt;https://blueprints.launchpad.net/cinder/+spec/image-volume-cache&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Thu, 16 Nov 2017 00:00:00 </pubDate></item><item><title>Cinder Nested Quota Driver</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/liberty/cinder-nested-quota-driver.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/cinder-nested-quota-driver"&gt;bp cinder-nested-quota-driver&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Nested quota driver will enable OpenStack to enforce quota in nested
projects.&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/keystone/+spec/hierarchical-multitenancy"&gt;bp hierarchical-multitenancy&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;OpenStack is moving towards support for hierarchical ownership of projects.
In this regard, Keystone will change the organizational structure of
OpenStack, creating nested projects.&lt;/p&gt;
&lt;p&gt;The existing Quota Driver in Cinder called &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DbQuotaDriver&lt;/span&gt;&lt;/code&gt; is useful to
enforce quotas at both the project and the project-user level provided that all
the projects are at the same level (i.e. hierarchy level cannot be greater
than 1).&lt;/p&gt;
&lt;p&gt;The proposal is to develop a new Quota Driver called &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;NestedQuotaDriver&lt;/span&gt;&lt;/code&gt;,
by extending the existing &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DbQuotaDriver&lt;/span&gt;&lt;/code&gt; which will allow enforcing quotas
in nested projects in OpenStack. The nested projects are having a hierarchical
structure, where each project may contain users and projects (can be called
sub-projects).&lt;/p&gt;
&lt;p&gt;Users can have different roles inside each project: A normal user can make
use of resources of a project. A project-admin, for example can be a user
who in addition is allowed to create sub-projects, assign quota on resources
to these sub-projects and assign the sub-project admin role to individual users
of the sub-projects. Resource quotas of the root project can only be set by the
admin of the root project. The user roles can be set as inherited, and if set,
then an admin of a project is automatically an admin of all the projects in the
tree below.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Actors&lt;/strong&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Mike - Cloud Admin (i.e. role:cloud-admin) of ProductionIT&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Jay - Manager (i.e. role: project-admin) of Project CMS&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;John - Manager (i.e. role: project-admin) of Project ATLAS&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Eric - Manager (i.e. role: project-admin) of Project Operations&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Xing - Manager (i.e. role: project-admin) of Project Services&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Walter - Manager (i.e. role: project-admin) of Project Computing&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Duncan - Manager (i.e. role: project-admin) of Project Visualisation&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The nested structure of the projects is as follows.&lt;/p&gt;
&lt;div class="highlight-javascript notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="nx"&gt;ProductionIT&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;                  &lt;/span&gt;&lt;span class="nx"&gt;CMS&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;                            &lt;/span&gt;&lt;span class="nx"&gt;Computing&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;                            &lt;/span&gt;&lt;span class="nx"&gt;Visualisation&lt;/span&gt;
&lt;span class="w"&gt;                        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;                  &lt;/span&gt;&lt;span class="nx"&gt;ATLAS&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;                            &lt;/span&gt;&lt;span class="nx"&gt;Operations&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;                            &lt;/span&gt;&lt;span class="nx"&gt;Services&lt;/span&gt;
&lt;span class="w"&gt;                      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;               &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Mike is an infrastructure provider and offers cloud services to Jay for
Project CMS, and John for Project ATLAS. CMS has two sub projects below it
named, Visualisation and Computing, managed by Duncan and Walter respectively.
ATLAS has two sub projects called Services and Operations, managed by
Xing and Eric respectively.&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Mike needs to be able to set the quotas for both CMS and ATLAS, and also
manage quotas across the entire projects including the root project,
ProductionIT.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Jay should be able to set and update the quota of Visualisation and
Computing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Jay should be able to able to view the quota of CMS, Visualisation and
Computing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Jay should not be able to update the quota of CMS, although he is the
Manager of it. Only Mike can do that.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Jay should not be able to view the quota of ATLAS. Only John and Mike
can do that.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Duncan, the Manager of Visualisation should not be able to see the quota of
CMS. Duncan should be able to see the quota of Visualisation only, and also
the quota of any sub projects that will be created under Visualisation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;The total resources consumed by a project is divided into&lt;/dt&gt;&lt;dd&gt;&lt;ol class="loweralpha simple"&gt;
&lt;li&gt;&lt;p&gt;hard_limit - Maximum capacity that can be consumed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;used - Resources used by the resource “volumes” in a project.&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;(excluding child-projects)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;reserved - Resources reserved for future use by the project does&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;not include descendants.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The quota information regarding number of volumes in different projects
are as follows,&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Name&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;hard_limit&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;used&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;reserved&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;ProductionIT&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;1000&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;100&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;100&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;CMS&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;300&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;25&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;15&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Computing&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;100&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;50&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;50&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Visualisation&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;150&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;25&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;25&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;ATLAS&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;400&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;25&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;25&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Services&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;100&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;25&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;25&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Computing&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;200&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;50&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;50&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Consider following use-cases :-&lt;/p&gt;
&lt;ol class="loweralpha simple"&gt;
&lt;li&gt;&lt;p&gt;Suppose, Mike(admin of root project or cloud admin) increases the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;hard_limit&lt;/span&gt;&lt;/code&gt; of volumes in CMS to 400&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Suppose, Mike increases the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;hard_limit&lt;/span&gt;&lt;/code&gt; of volumes in CMS to 500&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Suppose, Mike delete the quota of CMS&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Suppose, Mike reduces the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;hard_limit&lt;/span&gt;&lt;/code&gt; of volumes in CMS to 350&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Suppose, Mike reduces the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;hard_limit&lt;/span&gt;&lt;/code&gt;  of volumes in CMS to 200&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Suppose, Jay(Manager of CMS)increases the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;hard_limit&lt;/span&gt;&lt;/code&gt; of
volumes in CMS to 400&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Suppose, Jay tries to view the quota of ATLAS&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Suppose, Duncan tries to reduce the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;hard_limit&lt;/span&gt;&lt;/code&gt; of volumes in CMS to
400.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Suppose, Mike tries to increase the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;hard_limit&lt;/span&gt;&lt;/code&gt; of volumes in
ProductionIT to 2000.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Suppose, Mike deletes the quota of Visualisation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Suppose, Mike deletes the project Visualisation.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;ol class="arabic simple" start="9"&gt;
&lt;li&gt;&lt;p&gt;Suppose the company doesn’t want a nested structure and want to
restructure in such a way that there are only four projects namely,
Visualisation, Computing, Services and Operations.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;section id="project-priority"&gt;
&lt;h3&gt;Project Priority&lt;/h3&gt;
&lt;p&gt;The code in the existing DBQuotaDriver is deprecated and hence we need an
update. Also as the entire OpenStack community is moving toward hierarchical
projects this can be an useful addition to Cinder.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;p&gt;The default quota (hard limit) for any newly created sub-project is set
to 0.
The neutral value of zero ensures consistency of data in the case of race
conditions when several projects are created by admins at the same time.
Suppose the default value of number of volumes allowed per project is 100,
and A is the root project. And an admin is creating B, a child project of A,
and another admin is creating C, again a child project of A. Now, the sum
of default values for number of volumes of B and C are crossing the default
value of A. To avoid this type of situations, default quota is set as Zero.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A project is allowed to create a volume, only after setting the quota to a
non-zero value (as default value is 0). After the creation of a new project,
quota values must be set explicitly by a Cinder API call to a value which
ensures availability of free quota, before resources can be claimed in the
project.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A user with role “cloud-admin” in the root project and with inherited roles
is called Cloud-Admin and is permitted to do quota operations across the
entire hierarchy, including the top level project. Cloud-Admins are the only
users who are allowed to set the quota of the root project in a tree.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A person with role “project-admin” in a project is permitted to do quota
operations on its sub-projects and users in the hierarchy. If the
role “project-admin” in a project is set as inheritable in Keystone, then
the user with this role is permitted to do quota operations starting from
its immediate child projects to the last level project/user under the
project hierarchy.
Note: The roles like “cloud-admin” and “project-admin” are not hard coded.
It is used in this Blueprint, just for demonstration purpose.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The total resources consumed by a project is divided into&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ol class="loweralpha simple"&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;Used Quota  - Resources used by the volumes in a project.&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;(excluding child-projects)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;Reserved Quota - Resources reserved for future use by the project does&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;not include descendants.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;Allocated Quota - Sum of the quota &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;hard_limit&lt;/span&gt;&lt;/code&gt; values of immediate&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;child projects&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;free&lt;/span&gt;&lt;/code&gt; quota available within a project is calculated as&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;free&lt;/span&gt; &lt;span class="pre"&gt;quota&lt;/span&gt; &lt;span class="pre"&gt;=&lt;/span&gt; &lt;span class="pre"&gt;hard_limit&lt;/span&gt; &lt;span class="pre"&gt;-&lt;/span&gt; &lt;span class="pre"&gt;(used&lt;/span&gt; &lt;span class="pre"&gt;+&lt;/span&gt; &lt;span class="pre"&gt;reserved&lt;/span&gt; &lt;span class="pre"&gt;+&lt;/span&gt; &lt;span class="pre"&gt;allocated)&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Free quota is not stored in the database; it is calculated for each
project on the fly.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;An increase in the quota value of a project is allowed only if its parent
has sufficient free quota available. If there is free quota available with
the parent, then the quota update operation will result in the update of
the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;hard_limit&lt;/span&gt;&lt;/code&gt; value of the project and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;allocated&lt;/span&gt;&lt;/code&gt; value update of
its parent project. That’s why, it should be noted that updating the quota
of a project requires the token to be scoped at the parent level.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Hierarchy of Projects is as A-&amp;gt;B-&amp;gt;C (A is the root project)&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Name&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;hard_limit&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;used&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;reserved&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;allocated&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;100&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;50&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;B&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;50&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;20&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;10&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;C&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;10&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;10&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Free quota for projects would be:&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;A:Free Quota = 100 {A:hard_limit} - ( 0 {A:used} + 0 {A:reserved} +&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;50 {A:Allocated to B}) = 50&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;B:Free Quota = 50  {B:hard_limit} - ( 20 {B:used} + 0 {B:reserved} +&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;10 {B:Allocated to C}) = 20&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;C:Free Quota = 10  {C:hard_limit} - ( 10 {C:used} + 0 {C:reserved} +&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;0 {C:Allocated}) = 0&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;If Project C &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;hard_limit&lt;/span&gt;&lt;/code&gt; is increased by 10, then this change results
in:&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Name&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;hard_limit&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;used&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;reserved&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;allocated&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;100&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;50&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;B&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;50&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;20&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;20&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;C&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;20&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;10&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;If Project C hard_limit needs to be increased further by 20, then this
operation will be aborted, because the free quota available with its
parent i.e. Project B is only 10. So, first project-admin of A should
increase the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;hard_limit&lt;/span&gt;&lt;/code&gt; of Project B (using scoped token to
Project A, because of action at level A) and then increase the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;hard_limit&lt;/span&gt;&lt;/code&gt; of Project C (again scoped token to Project B)&lt;/p&gt;
&lt;p&gt;Please consider the use cases mentioned above. The quota information
of various projects, including the allocated quota is as follows,&lt;/p&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;ProductionIT  : hard_limit=1000, used=100, reserved=100, allocated=700&lt;/div&gt;
&lt;div class="line"&gt;CMS           : hard_limit=300, used=25, reserved=15, allocated=250&lt;/div&gt;
&lt;div class="line"&gt;Computing     : hard_limit=100, used=50, reserved=50, allocated=0&lt;/div&gt;
&lt;div class="line"&gt;Visualisation : hard_limit=150, used=25, reserved=25, allocated=0&lt;/div&gt;
&lt;div class="line"&gt;ATLAS         : hard_limit=400, used=25, reserved=25, allocated=300&lt;/div&gt;
&lt;div class="line"&gt;Services      : hard_limit=100, used=25, reserved=25, allocated=0&lt;/div&gt;
&lt;div class="line"&gt;Computing     : hard_limit=200, used=50, reserved=50, allocated=0&lt;/div&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Suppose Mike tries to increase the volumes quota in CMS to 400.
Since Mike is having the role of admin in ProductionIT which is the
parent of CMS, he can increase the quota of CMS provided that the
token is scoped to ProductionIT. This is required because the increase
of quota limit in CMS results in the corresponding reduction of
free quota in ProductionIT.&lt;/p&gt;
&lt;p&gt;Using the above formula, free quota of ProductionIT is given by,
free quota = hard_limit - used - reserved - allocated
free quota = 1000 - 100 - 100 - (400 + 400)
free quota = 0&lt;/p&gt;
&lt;p&gt;So maximum permissible quota for CMS is 300 + 100 = 400&lt;/p&gt;
&lt;p&gt;Note:ProductionIT:allocated = CMS:hard_limit + ATLAS:hard_limit&lt;/p&gt;
&lt;p&gt;Minimum quota of CMS is given by,
CMS:used + CMS:reserved + CMS:allocated = 25 + 15 + 250 = 290&lt;/p&gt;
&lt;p&gt;Note: CMS:allocated = Visualisation:hard_limit + Computing:hard_limit&lt;/p&gt;
&lt;p&gt;Since 290(minimum quota) &amp;lt;= 400(new quota) &amp;lt;=400(maximum quota),
quota operation will be successful. After update, the quota of
ProductionIT and CMS will be as follows,&lt;/p&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;ProductionIT : hard_limit=1000, used=100, reserved=100, allocated=800&lt;/div&gt;
&lt;div class="line"&gt;CMS          : hard_limit=400, used=25, reserved=15, allocated=250&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Suppose Mike tries to increase the intances quota in CMS to 500. Then
it will not be successful, since the maximum quota available
for CMS is 400.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Suppose Jay who is the Manager of CMS increases the volumes
quota in CMS to 400, then it will not be successful, since Jay is not
having admin or project-admin role in ProductionIT which is the parent
of CMS.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Suppose Mike tries to increase the quota of ProductionIT to 2000,
then it will be successful. Since ProductionIT is the root project,
there is no limit for the maximum quota of ProductionIT. And also,
Mike is having admin role in ProductionIT. For a private cloud the
hard_limit depends on the internal inventory that is maintained
internally by the cloud provider. Mike the Cloud Admin will have
an access to these details and will update the hard_limit depending
on the available inventory. So hard_limit is bounded by the available
inventory for the Private Cloud and it will vary for each Private Cloud.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A decrease in the quota value of a project is allowed only if it has free
quota available, free quota &amp;gt; 0 (zero), hence the maximum decrease in
quota value is limited to free quota value.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul&gt;
&lt;li&gt;&lt;dl&gt;
&lt;dt&gt;Hierarchy of Projects is A-&amp;gt;B-&amp;gt;C, where A is the root project&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Project A (hard_limit = 100, used = 0, reserved = 0, allocated = 50)
Project B (hard_limit = 50, used = 20, reserved = 0, allocated = 10)
Project C (hard_limit = 10, used = 10, reserved = 0, allocated = 0)&lt;/p&gt;
&lt;p&gt;If Project B hard_limit is reduced by 10, then this change results in
Project A (hard_limit = 100, used = 0, reserved = 0, allocated = 40)
Project B (hard_limit = 40, used = 20, reserved = 0, allocated = 10)
Project C (hard_limit = 10, used = 10, reserved = 0, allocated = 0)&lt;/p&gt;
&lt;p&gt;If Project B’s hard_limit needs to be reduced further by 20, then this
operation will be aborted, because the free quota of Project B should
be greater than or equal to (20+0+10).&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;ol class="arabic simple" start="9"&gt;
&lt;li&gt;&lt;p&gt;Suppose Mike tries to reduce the volumes quota in CMS to 350,
it will be successful since the minimum quota required for CMS is 290.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Suppose Mike tries to reduce the volumes quota of CMS to 200,
then it will not be successful, since it violates the minimum quota
criteria.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete quota is equivalent to updating the quota with zero values. It
will be successful if the allocated quota is zero. Authentication logic
is same as that of update logic.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Suppose Mike tries to  delete the quota of CMS then it will not be
successful, since allocated quota of CMS is non-zero.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Suppose Mike deletes the quota of Visualisation, then it will be
successful since the allocated quota of Visualisation is zero. The
deleted quota of Visualisation will add to the free_quota of CMS. The
quota of CMS will be CMS :hard_limit=300, used=25, reserved=15,
allocated=100.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Suppose, Mike deletes the project Visualisation, the quota of
Visualisation should be released to its parent, CMS. But in the
current setup, Cinder will not come to know, when a project is
deleted from keystone. This is because, Keystone service is not
synchronized with other services, including Cinder. So even if
the project is deleted from keystone, the quota information
remains there in cinder database. This problem is there in
the current running model of OpenStack. Once the keystone service
is synchronized, this will be automatically taken care of. For
the time being, Mike has to delete the quota of Visualisation,
before he is deleting that project. Synchronization of keystone
with other OpenStack services is beyond the scope of this blueprint.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Suppose if Jay, who is the Manager of CMS tries to view the quota of
ATLAS, it will not be successful, since Jay is not having any role in
ATLAS or in the parent of ATLAS.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Suppose Duncan who is the Manager of Visualisation tries to update the
quota of CMS, it will not be successful, because he is not having admin or
project-admin role in the parent of CMS.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Suppose if the organization doesn’t want a nested structure and wants
only four projects namely, Visualisation, Computing, Services and
Operations, then the setup will work like the current setup where there is
only one level of projects. All the four projects will be treated as root
projects.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In case of parallel quota consumption i.e. quota consumption by various
sub-projects at the same time, if the request is not satisfied, then
the request should be re-tried after sometime after increasing the parent
quota. This needs admin intervention for this spec. As discussed in
notifications impact section going ahead with notification/event based
support we can overcome admin intervention. In upcoming work I
will add details on how do we serialize request. This is
important because increase in hard_limit for a subproject
(depending on the free_quota in the parent) and updating the allocated
quota at the parent level needs to be an atomic operation. Once the
atomic operation is performed new incoming request can be served.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;For quota update and delete operations of a project, the token can be scoped to
the project itself, instead to its parent. But, we are avoiding that, because
the quota change in the child project lead to change in the free quota of the
parent. Because of that, according to this bp, for quota update and delete
operations, the token is scoped to the parent.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;Create a new column &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;allocated&lt;/span&gt;&lt;/code&gt; in table &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;quotas&lt;/span&gt;&lt;/code&gt; with default value 0.
This can be done by adding a migration script to do the same.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;The parameter hard_limit used in the spec needs to be closely tied
to the actual inventory present in each individual private cloud. As
most of the calculations are based of hard_limit the transparent view
of available inventory is needed for quota calculations. This is beyond
the scope of this spec but bringing it up for clarity. Also care
should be taken to ensure that this does not allow any quota escape
vulnerabilities. Given it is a more complex model, it is well worth
reviewers spending time on actively trying to subvert the
model (time of check v/s time of use, etc).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;Any change of quota values (not usage, but limits) will
generate an event. This can be useful for general debugging,
auditing to figure out who did what. For this spec will restrict
the notification scope to just tracing and auditing but going ahead
event or notification mechanism can be used to notify the starving
sub-project, to retry later, when the parent has enough
free quota available. Also going ahead when Keystone deletes
a project a notification can go to a queue and then cinder
can consume this event to proactively free up the quota from
cinder db.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;Only Cloud-Admin or immediate parent can set quota on sub-project.
Cloud-Admin can even set and update his/her own quota.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;vilobhmm&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Other contributors:&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;p&gt;For the first implementation patch of this spec we will only
fix up the quota calculations to be sub-project aware not add
any new editing capabilities. Also we will skip updating of
quotas by anybody except root project admin.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For second implementation patch of this spec we will add
quota editing by project admin of sub-projects as well.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A role called “cloud-admin” will be created and assigning
that role to a user in root project and making it inheritable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Role called  “project-admin” will be created. The user with “project-admin”
role in a project will be  able to do quota operations in projects
starting  from its immediate child projects to the last level
project/user under the project hierarchy, provided it is inheritable.&lt;/p&gt;
&lt;p&gt;Note:The roles like “cloud-admin” and “project-admin” are not hard coded.
It is used in this Blueprint, just for demonstration purpose.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A new Quota Driver called &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;NestedQuotaDriver&lt;/span&gt;&lt;/code&gt; will be implemented by
extending the existing &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DbQuotaDriver&lt;/span&gt;&lt;/code&gt;, to enforce quotas in hierarchical
multitenancy in OpenStack.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A migration script will be added to create the new column &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;allocated&lt;/span&gt;&lt;/code&gt; in
table &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;quotas&lt;/span&gt;&lt;/code&gt;, with default value 0.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;Depends on &lt;a class="reference external" href="https://blueprints.launchpad.net/keystone/+spec/hierarchical-multitenancy"&gt;bp hierarchical-multitenancy&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit tests will be added for all the REST APIs calls.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add unit tests for integration with other services.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Documentation will be updated to give details about the quota calculation and
how the quota will be assigned and managed by the projects while using
nested quota driver(in projects which have hierarchical support). These
deployment need to be on or later Kilo since the hierarchical support was
added since Kilo release.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://wiki.openstack.org/wiki/HierarchicalMultitenancy"&gt;Hierarchical Projects Wiki&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://specs.openstack.org/openstack/keystone-specs/specs/juno/hierarchical_multitenancy.html"&gt;Hierarchical Projects&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/keystone/+spec/hierarchical-multitenancy-improvements"&gt;Hierarchical Projects Improvements&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Thu, 16 Nov 2017 00:00:00 </pubDate></item><item><title>Clone Consistency Group</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/liberty/clone-cg.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/clone-cg"&gt;https://blueprints.launchpad.net/cinder/+spec/clone-cg&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This proposal is to add a feature to create a cloned consistency group
from an existing one.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently a user can create a Consistency Group first and then clone
one volume from the existing CG at a time and add it to the new CG
until all volumes are cloned and added to the CG.&lt;/p&gt;
&lt;p&gt;The proposal wants to enhance the existing create CG from source API
and make this a one step rather than multi-step process.&lt;/p&gt;
&lt;p&gt;Note: The cloned volumes in the new CG are not guanranteed to be
consistent. From the consistency point of view, it’s no different from
creating a empty CG first and then creating volume one after another and
adding to the CG.&lt;/p&gt;
&lt;p&gt;The existing Create CG from source API allows user to create a CG from
the group snapshot (CG snapshot), which should be consistent.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;Suppose a user already has a CG with volumes in it. He/she now wants
to create another CG with all volumes cloned from the other CG. The
proposed change will make this much easier for the user.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The existing Create CG from Source API takes an existing CG snapshot
as the source.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This blueprint proposes to modify the existing API to accept an existing
CG as the source.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Without the proposed changes, we can create a CG from an existing CG
with these steps:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create an empty CG.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a cloned volume from an existing volume in an existing CG
and add to the new CG.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Repeat the above step for all volumes in the CG.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;DB Schema Change: A new column source_cg_id will be added to the
consistencygroups table.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;Consistency Group API change&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Create Consistency Group from Source&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;V2/&amp;lt;tenant id&amp;gt;/consistencygroups/create_from_src&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Method: POST&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;JSON schema definition for V2:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"consistencygroup-from-src"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"my_cg"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# existing&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"My consistency group"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# existing&lt;/span&gt;
        &lt;span class="s2"&gt;"cgsnapshot_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"xxxxxxxx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# existing&lt;/span&gt;
        &lt;span class="s2"&gt;"consistencygroup_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"xxxxxxxx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# new&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the existing Create Consistency Group from Source API, add a new
parameter “consistencygroup_id” to allow an existing CG to be the source
of the new CG.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cinder Volume Driver API&lt;/p&gt;
&lt;p&gt;Two new optional parameters will be added to the existing volume driver API:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;def create_consistencygroup_from_src(self, context, group, volumes,
cgsnapshot=None, snapshots=None, src_group=None, src_volumes=None)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Note only “src_group” and “src_volumes” are new parameters.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;python-cinderclient needs to be changed to support the modified API.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create Cloned CG
cinder consisgroup-create-from-src –name &amp;lt;name&amp;gt; –description &amp;lt;description&amp;gt;
–consistencygroup &amp;lt;cg uuid or name&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Driver developers can add support to this feature in the modified driver API.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;xing-yang&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Other contributors:&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;API change:
* Modify Create CG from Source API&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Volume Driver API change:
* Modify corresponding driver API&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DB schema change&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;New unit tests will be added to test the changed code.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Documentation changes are needed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;/section&gt;
</description><pubDate>Thu, 16 Nov 2017 00:00:00 </pubDate></item><item><title>Cinder DB Archiving</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/liberty/db-archiving.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/db-archiving"&gt;https://blueprints.launchpad.net/cinder/+spec/db-archiving&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;We actually don’t delete rows from db, we mark it only as deleted
(we have special column). So the DB is growing and growing,
so this causes problem with performance.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;A lot of unused data in the DB causes different kind of problems with
performance and maintaining:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Need to filter ‘marked as deleted’ rows in every query&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DB contains a lot of unused data in each table and operators
need to filter it if they use database directly in an emergency case&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Storage usage utilization (low priority)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Create shadow table for each table and copy “deleted” rows from main to shadow
table.&lt;/p&gt;
&lt;p&gt;We need to provide several method for archiving data:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;archive not more than N “deleted” rows in each table&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;archive “deleted” rows older than specified data&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;archive all “deleted” data&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Shadowing could be started as a periodic task or admin management util.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Create event-based solution to make opportunity operators to subscribe on
“deleting” events and store deleted data somewhere.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create shadow tables&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement migrations to store current “deleted” rows in shadow table&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Shadow tables could have blob field to store some “deleted” data and to not
impose restrictions on database schema changes.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;No performance hit from filtering out a potentially massive number of deleted
records on every query.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Operator or deployer could use periodic task or Cinder management tool to
archive “deleted” data.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Developers should care about migrations for shadow tables as well, as for
original tables:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;table creation or deletion requires creating or deleting corresponding
shadow tables&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;when a table is modified, the shadow tables have to get modified&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;when one or more columns are moved to a new table, columns from shadow table
should also moved to a new shadow table with data migration&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;downgrades should be implemented for shadow tables too: new tables
have to get removed and the migrated columns will have to get reverted&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Ivan Kolodyazhny (e0ne)&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Boris Pavlovich (boris-42)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit tests for both API and Tempest will be implemented,&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Cloud Administration Guide will be updated to introduce new cinder-manage
command:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/admin-guide/blockstorage-manage-volumes.html"&gt;http://docs.openstack.org/admin-guide/blockstorage-manage-volumes.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Nova’s spec for db archiving: &lt;a class="reference external" href="https://review.openstack.org/#/c/18493/"&gt;https://review.openstack.org/#/c/18493/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Discussion in openstack-dev mailing list:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://lists.openstack.org/pipermail/openstack-dev/2014-March/029952.html"&gt;http://lists.openstack.org/pipermail/openstack-dev/2014-March/029952.html&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Thu, 16 Nov 2017 00:00:00 </pubDate></item><item><title>Enhance List Operations with Pagination Keys</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/liberty/enhance-list-operations-pagination-keys.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/extend-limit-implementations"&gt;https://blueprints.launchpad.net/cinder/+spec/extend-limit-implementations&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Currently, the pagination keys, like limit, marker, sort key and sort
direction and the next link generation, have been implemented for the volume
list operations, but not available in other list operations. This blueprint
implements the pagination keys and the next link generation for other items,
like snapshots, volume transfers, consistency group, consistency group
snapshots and backups.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;The pagination keys mentioned in the above section have been implemented in
the list operations for volumes. This feature can be extended to other cinder
concepts. The reason why snapshots, volume transfers, consistency groups,
consistency group snapshots, and backups are being targeted is because these
entities have relatively high frequencies to query and it is more probable for
them to reach a large amount comparing to other entities, like type,
availability zone, etc.&lt;/p&gt;
&lt;p&gt;The next link generation is already available in volume list, so it is
straightforward to implement it for other cinder concepts. Please refer to
the _get_collection_links function in the cinder.api.common.ViewBuilder class.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;Suppose the maximum page size 1000 and there are more than 1000 volume
snapshots. If there is no pagination key marker implemented for
snapshot, the maximum snapshots the user can query from the API is 1000. The
only way to query more than 1000 snapshots is to increase the default maximum
page size, which is a limitation to the cinder list operations. If no next link
is generated, it is not possible to retrieve more items than the maximum page
size. Even if the next link is generated in this case, it will still return
the same results as the previous request without the key marker honored. In
conclusion, both the pagination keys and the next link generation are necessary
to add for the cinder entities.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;The change depends on some work items, which have been put in the
“Dependencies” section.&lt;/p&gt;
&lt;p&gt;The list APIs for snapshots, volume transfers, consistency group, consistency
group snapshots and backups will support the following parameters:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;limit: Key used to determine the number of returned items in the response&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;marker: Key used to determine the item, where to start the query&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;sort: This key is a comma-separated list of sort keys. Sort directions
can optionally be appended to each sort key, separated by the ‘:’ character&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Multiple sort keys and sort directions will be implemented as they are done
for volumes in the patch “GET volumes API sorting REST/volume/DB updates”,
&lt;a class="reference external" href="https://review.openstack.org/#/c/141915/"&gt;https://review.openstack.org/#/c/141915/&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The change is compliant with the syntax for client sorting arguments defined
in the patch “CLI Sorting Argument Guidelines”,
&lt;a class="reference external" href="https://review.openstack.org/#/c/145544/"&gt;https://review.openstack.org/#/c/145544/&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The caller can specify these parameters in the request to query the list of
the items,
e.g. /snapshots?limit=5&amp;amp;marker=snapshot_id&amp;amp;sort=key1:asc,key2:desc,key3:asc&lt;/p&gt;
&lt;p&gt;If there are more items available to query in further requests, the next link
should be correctly generated for snapshots, volume transfers, consistency
group, consistency group snapshots and backups.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;It is possible that we define different pagination keys, other than limit,
marker, sort information to implement the pagination for other items
in Cinder.&lt;/p&gt;
&lt;p&gt;However, to keep the consistency in code change, it is better to follow the
pattern that volume list does.&lt;/p&gt;
&lt;p&gt;Another alternative is cinder sticks with no pagination for other entities
except volumes. However, the default maximum page size 1000 can be exceeded,
by some entities, like snapshots, in the production environment. It will
cause issues in other entities in future.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;The following existing v2 GET APIs will support the new sorting parameters:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;/v2/{tenant_id}/{items}&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;/v2/{tenant_id}/{items}/detail&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;{items} will be replaced by the appropriate entities as follows:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;For snapshots:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;/v2/{tenant_id}/snapshots&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;/v2/{tenant_id}/snapshots/detail&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For volume transfers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;/v2/{tenant_id}/os-volume-transfer&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;/v2/{tenant_id}/os-volume-transfer/detail&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For consistency group:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;/v2/{tenant_id}/consistencygroups&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;/v2/{tenant_id}/consistencygroups/detail&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For consistency group snapshots:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;/v2/{tenant_id}/cgsnapshots&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;/v2/{tenant_id}/cgsnapshots/detail&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For backups:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;/v2/{tenant_id}/backups&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;/v2/{tenant_id}/backups/detail&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The existing API needs to support the following new Request Parameters for
the above cinder concepts:&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Parameter&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Style&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;limit&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;query&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;integer&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Key used to determine the number of
returned items in the response&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;marker&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;query&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Key used to determine the item, where
to start the query&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;sort&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;query&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;list&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;A comma-separated list of sort keys, with
the sort directions optionally appended to
each sort key&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;In the event that an invalid pagination key is specified then a “badRequest”
error response (code 400) will be returned.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;For the limit key, it returns a message like “Invalid input received:
Invalid limit key”.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For the marker key, it returns a message like “Invalid input received:
Invalid marker key”.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For the sort information, it returns a message like “Invalid input received:
Invalid sort key” or “Invalid input received: Invalid sort direction”
depending on different circumstances.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The next link will be put in the response returned from cinder if it is
necessary.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;For snapshots, it replies:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"snapshots"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;snapshots&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="s2"&gt;"snapshots_links"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="s1"&gt;'href'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&amp;lt;next_link&amp;gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'rel'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'next'&lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For volume transfers, it replies:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"transfers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;transfers&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="s2"&gt;"transfers_links"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="s1"&gt;'href'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&amp;lt;next_link&amp;gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'rel'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'next'&lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For consistency group, it replies:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"consistencygroups"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;consistencygroups&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="s2"&gt;"consistencygroups_links"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="s1"&gt;'href'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&amp;lt;next_link&amp;gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'rel'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'next'&lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For consistency group snapshots, it replies:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"cgsnapshots"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;cgsnapshots&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="s2"&gt;"cgsnapshots_links"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="s1"&gt;'href'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&amp;lt;next_link&amp;gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'rel'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'next'&lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For backups, it replies:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"backups"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;backups&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="s2"&gt;"backups_links"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="s1"&gt;'href'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&amp;lt;next_link&amp;gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'rel'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'next'&lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;The cinderclient should be updated to accept limit, marker, sort information,
in snapshots, volume transfers, consistency group, consistency group snapshots
and backups.&lt;/p&gt;
&lt;p&gt;The user will be able to specify pagination keys, like limit, marker, sort
information to list snapshots, volume transfers, consistency group, consistency
group snapshots and backups.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;The deployer should be aware that the flag osapi_max_limit can set the maximum
number of items that a collection resource returns in ONE single response, but
it will not limit the number of items returned for the cinderclient request any
longer.&lt;/p&gt;
&lt;p&gt;After the pagination keys and the next link generation are implemented for the
cinder entities, the cinderclient request can retrieve more items than the flag
osapi_max_limit sets, because it can fetch the items multiple times via the
next link with the marker key until all the items are returned if no limit key
is set or the number of items equals to limit if the limit key is set.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Vincent Hou (&lt;a class="reference external" href="mailto:sbhou%40cn.ibm.com"&gt;sbhou&lt;span&gt;@&lt;/span&gt;cn&lt;span&gt;.&lt;/span&gt;ibm&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;)&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;None&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;Since the logic code of next link generation is finished in a common class. We
do not need to repeat the work any more.&lt;/p&gt;
&lt;p&gt;Therefore, I see the following work items:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add the code to call the common functions to get the limit, marker and
sort parameters processed for snapshots, volume transfers,
consistency group, consistency group snapshots and backups.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the code to do the database query with the paginations keys for
snapshots, volume transfers, consistency group, consistency group snapshots
and backups.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the support of the paginations keys for snapshots, volume transfers,
consistency group, consistency group snapshots and backups in cinderclient.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify the existing APIs to support passing the limit, marker, and sort
information from the API layer to the database layer.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unit tests to ensure that these pagination keys and the next link generation
is supported for snapshots, volume transfers, consistency group, consistency
group snapshots and backups.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Cinder pagination:
&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/cinder-pagination"&gt;https://blueprints.launchpad.net/cinder/+spec/cinder-pagination&lt;/a&gt;, accepted&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;GET volumes API sorting REST/volume/DB updates:
&lt;a class="reference external" href="https://review.openstack.org/#/c/141915/"&gt;https://review.openstack.org/#/c/141915/&lt;/a&gt;, WIP&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CLI Sorting Argument Guidelines: &lt;a class="reference external" href="https://review.openstack.org/#/c/145544/"&gt;https://review.openstack.org/#/c/145544/&lt;/a&gt;,
accepted&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server sorting guidelines: &lt;a class="reference external" href="https://review.openstack.org/#/c/145579"&gt;https://review.openstack.org/#/c/145579&lt;/a&gt;, merged&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Both unit and Tempest tests need to be created to ensure that snapshots, volume
transfers, consistency group, consistency group snapshots and backups support
the pagination keys of limit, marker, and sort information, and the next link
generation is available if necessary.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;The API documentation will need to be updated to accept limit, marker,
sort key and sort direction, in snapshots, volume transfers, consistency
group, consistency group snapshots and backups as it does for volumes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 16 Nov 2017 00:00:00 </pubDate></item><item><title>Retrieve Supported Volume Type Extra Specs</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/liberty/get-vol-type-extra-specs.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/get-volume-type-extra-specs"&gt;https://blueprints.launchpad.net/cinder/+spec/get-volume-type-extra-specs&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Provide an interface to obtain a volume driver’s &lt;em&gt;capabilities&lt;/em&gt;.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;section id="definitions"&gt;
&lt;h3&gt;Definitions&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Volume Type:&lt;/em&gt; A group of volume policies.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Extra Specs:&lt;/em&gt; The definition of a volume type. This is a group of policies
e.g. provision type, QOS that will be used to define a volume at creation
time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Capabilities:&lt;/em&gt; What the current deployed backend in Cinder is able to do.
These correspond to extra specs.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The current implementation of &lt;em&gt;volume type&lt;/em&gt; &lt;em&gt;extra specs&lt;/em&gt; management process in
Horizon and the cinder client are error-prone. Operators manage extra specs
without having guidance on what capabilities are possible with a backend.
Without knowing the capabilities, the operator doesn’t know what the possible
&lt;em&gt;extra spec&lt;/em&gt; key/values are.&lt;/p&gt;
&lt;p&gt;Today operators have to make sure they’re reading the right documentation that
corresponds to the version of their storage backend. Documentation can
become out of date with their volume driver.&lt;/p&gt;
&lt;p&gt;It would be more convenient, and a better user experience if the operator was
able to ask Cinder for the capabilities of the current deployed storage
backends, instead of having to guess.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;As an operator, I want to get a list of the capabilities for my deployed
storage backends in Cinder.&lt;/p&gt;
&lt;p&gt;With these capabilities, I have keys and possible values that can be used
within a volume type’s extra specs.&lt;/p&gt;
&lt;p&gt;Potentially with the API endpoint, Horizon could use it to improve the GUI for
managing extra specs.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Cinder volume drivers will implement a new method &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;get_capabilities&lt;/span&gt;&lt;/code&gt;, which
will return a dictionary of supported capabilities from the storage backend.&lt;/p&gt;
&lt;p&gt;The dictionary will include some brief information about the backend, and
capabilities that correspond to extra spec keys and values.&lt;/p&gt;
&lt;p&gt;Features like create volume, create snapshots, etc are considered minimum
features [1]. Unlike &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;well&lt;/span&gt; &lt;span class="pre"&gt;defined&lt;/span&gt;&lt;/code&gt; keys [2], minimum features are required
to implement. With &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;well&lt;/span&gt; &lt;span class="pre"&gt;defined&lt;/span&gt;&lt;/code&gt; keys, drivers just need to report if the
capability is not supported.
If the backend has some vendor unique capabilities, the backend driver can
also define &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vendor&lt;/span&gt; &lt;span class="pre"&gt;unique&lt;/span&gt;&lt;/code&gt; keys for supported capabilities.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Operators could continue to guess what extra specs they should be setting in
volume types. Operators could attempt to find documentation for volume type
extra specs. As a last resort, operators could dig through different Cinder
volume driver code to figure out the possible extra types. These aren’t
reliable solutions.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;New endpoint GET &lt;a class="reference external" href="mailto:/v2/tenant/get_capabilities/ubuntu%40lvm1_pool"&gt;/v2/tenant/get_capabilities/ubuntu&lt;span&gt;@&lt;/span&gt;lvm1_pool&lt;/a&gt;:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"namespace"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"OS::Storage::Capabilities::ubuntu@lvm1_pool"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"volume_backend_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"lvm"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"pool_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"pool"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"driver_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"storage_protocol"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"iSCSI"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"display_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Capabilities of Cinder LVM driver"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
   &lt;span class="s2"&gt;"These are volume type options provided by Cinder LVM driver, blah, blah."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"visibility"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"public"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"properties"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="s2"&gt;"thin_provisioning"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Thin Provisioning"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Sets thin provisioning."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"boolean"&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="s2"&gt;"compression"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Compression"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Enables compression."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"boolean"&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="s2"&gt;"vendor:compression_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Compression type"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Specifies compression type."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"string"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"enum"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s2"&gt;"lossy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"lossless"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"special"&lt;/span&gt;
      &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="s2"&gt;"replication"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Replication"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Enables replication."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"boolean"&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="s2"&gt;"qos"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"QoS"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Enables QoS."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"boolean"&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="s2"&gt;"vendor:minIOPS"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Minimum IOPS QoS"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Sets minimum IOPS if QoS is enabled."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"integer"&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="s2"&gt;"vendor:maxIOPS"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Maximum IOPS QoS"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Sets maximum IOPS if QoS is enabled."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"integer"&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="s2"&gt;"vendor:minIOPS"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Burst IOPS QoS"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Sets burst IOPS if QoS is enabled."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"integer"&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="s2"&gt;"vendor:persona"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Persona"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"I am something..."&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"default"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Generic"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"enum"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s2"&gt;"Generic"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"ONTAP-legacy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"VMware"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"OpenVMS"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"HPUX"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"WindowsServer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"Generic-ALUA"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"Generic-legacy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"HPUX-legacy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"AIX-legacy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"EGENERA"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;well&lt;/span&gt; &lt;span class="pre"&gt;defined&lt;/span&gt;&lt;/code&gt; keys are indicated without a prefix like the “qos”.
These are fairly standard base keys for Cinder backends. We expect most
devices to report at least a boolean True/False for these keys.&lt;/p&gt;
&lt;p&gt;The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vendor&lt;/span&gt; &lt;span class="pre"&gt;unique&lt;/span&gt;&lt;/code&gt; keys are optional and are indicated with a prefix
of vendor name + colon(:). (ex. abcd:minIOPS)
Vendor driver can use anything for the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vendor&lt;/span&gt; &lt;span class="pre"&gt;unique&lt;/span&gt;&lt;/code&gt; keys, but the
vendor name prefix shouldn’t contain colon because of the separator and
it will be automatically replaced by underscore(_). (abc:d -&amp;gt; abc_d)&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;Let’s look at compression here:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;This is a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;well&lt;/span&gt; &lt;span class="pre"&gt;defined&lt;/span&gt;&lt;/code&gt; key, we expect devices to report True or False
regarding whether they support it or not. In the case where not only does
a device support it, but it can be configured, the option keys are listed
under the “options” portion. This is simply the &amp;lt;key-name&amp;gt; of the option,
and a list of valid values that can be specified for it. NOTE, if the options
key is empty ({}) that means there are NO options that can be set on that
capability key.&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;The vendor:fireproof capability:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;This is a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vendor&lt;/span&gt; &lt;span class="pre"&gt;unique&lt;/span&gt;&lt;/code&gt; key, and is indicated by being prefixed with
“vendor name” + “:”. Also, note that the default is True and that there
are NO options. The example indicates that this device is ALWAYS fireproof,
you can’t change that, it just is, what it is.&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;The thin_provisioning capability:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;This is a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;well&lt;/span&gt; &lt;span class="pre"&gt;defined&lt;/span&gt;&lt;/code&gt; key which is not supported by this particular
vendor. As a result, it defaults to False, and provides no options.&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;The qos capability describes some corner cases for us:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;This key is a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;well&lt;/span&gt; &lt;span class="pre"&gt;defined&lt;/span&gt;&lt;/code&gt; key, that’s very customizable via options.
Well defined portion is whether the capability is supported or not (again
True/False), again, some devices may allow deploying volumes with or without
QoS on the same device, so you can specify that with
&amp;lt;capability-key-name&amp;gt;=true|false.&lt;/p&gt;
&lt;p&gt;If a device doesn’t support this (ie always true), then this entry is
omitted.&lt;/p&gt;
&lt;p&gt;The other key piece is &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vendor&lt;/span&gt; &lt;span class="pre"&gt;unique&lt;/span&gt;&lt;/code&gt; keys. For those that allow
additional special keys to set QoS those key names are provided in list
format as valid keys that can be specified and set as related to Quality of
Service.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;The vendor:persona key is another good example of a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vendor&lt;/span&gt; &lt;span class="pre"&gt;unique&lt;/span&gt;&lt;/code&gt;
capability:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;This is very much like QoS, and again, note that we’re just providing what
the valid values are.&lt;/p&gt;
&lt;p&gt;You’ll notice that the data-structure follows the settings you would put in
your extra-specs. This particular case doesn’t have any options other than
the base key itself, so the structure is rather simple.&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;The endpoint mentioned in the API Impact will only be available through the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;admin_api&lt;/span&gt;&lt;/code&gt; policy. Operators or other OpenStack services will have the
ability to query this information.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;Cinder Client Example:&lt;/p&gt;
&lt;p&gt;The operator wants to define new volume types for their OpenStack cloud. The
operator would fetch a list of capabilities for a particular backend’s pool:&lt;/p&gt;
&lt;p&gt;First get list of services:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;$ cinder service-list
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;With one of the listed pools, pass that to capabilities-list:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;$ cinder capabilities-list block1@lvm#pool

host_name: block1
volume_backend_name: lvm
pool_name: pool
driver_version: 2.0.0
storage_protocol: iSCSI

capabilities:

  compression:
    default: true
    options:
      compression: true, false
      compression_type: lossy, lossless, special

  thin_provisioning:
    default: false

  replication:
    default: false

  qos:
    default: true,
    options:
      qos: true, false
      vendor_keys:
        vendor:minIOPS,
        vendor:maxIOPS,
        vendor:burstIOPS

  vendor:fireproof:
    default: true
    options: {}

  vendor:persona:
    default: Generic
    options:
      Generic
      ONTAP-legacy
      VMware
      OpenVMS
      HPUX
      WindowsServer
      Generic-ALUA
      Generic-legacy
      HPUX-legacy
      AIX-legacy
      EGENERA
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Horizon:&lt;/p&gt;
&lt;p&gt;Horizon will be updated to include the displaying of the supported capabilities
so operators can select and set the values while creating or editing the
volume type extra specs.&lt;/p&gt;
&lt;p&gt;If the volume type does not have any volume backend name associated with it,
Horizon will not have any extra specs keys to display. Administrators can still
enter in key/value pairs of their own. This is the same behavior as the current
process.&lt;/p&gt;
&lt;p&gt;If a driver does not publish the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;extra&lt;/span&gt; &lt;span class="pre"&gt;specs&lt;/span&gt;&lt;/code&gt; dictionary, which will be the
case for any drivers that do not get updated, then no client-side filtering
will be performed, and the behavior will basically revert to the current
situation where the administrator in horizon will need to know and enter the
key/value pairs without any additional guidance.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Driver maintainers would need to implement a method &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;get_capabilities&lt;/span&gt;&lt;/code&gt;. This
should fetch from the storage backend a list of capabilities and translate it
to the dictionary structure:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s1"&gt;'driver_version:'&lt;/span&gt; &lt;span class="s1"&gt;'2.0.0'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'storage_protocol:'&lt;/span&gt; &lt;span class="n"&gt;iSCSI&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'capabilities:'&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'compression'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s1"&gt;'options'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s1"&gt;'compression_type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'lossy'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'lossless'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'special'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s1"&gt;'compression'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="s1"&gt;'thin_provisioning'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s1"&gt;'thin_provisioning'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="s1"&gt;'qos'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s1"&gt;'qos'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="s1"&gt;'replication'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="n"&gt;replication&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;There’s nothing keeping a vendor reporting fewer or more keys, but the
following are strictly enforced:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The data structure&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The information in the capabilities&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;well&lt;/span&gt; &lt;span class="pre"&gt;defined&lt;/span&gt;&lt;/code&gt; capabilities.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Driver version&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Storage protocol&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;jgravel (&lt;a class="reference external" href="mailto:julie.gravel%40hp.com"&gt;julie&lt;span&gt;.&lt;/span&gt;gravel&lt;span&gt;@&lt;/span&gt;hp&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;gary-smith (&lt;a class="reference external" href="mailto:gary.w.smith%40hp.com"&gt;gary&lt;span&gt;.&lt;/span&gt;w&lt;span&gt;.&lt;/span&gt;smith&lt;span&gt;@&lt;/span&gt;hp&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;thingee (&lt;a class="reference external" href="mailto:thingee%40gmail.com"&gt;thingee&lt;span&gt;@&lt;/span&gt;gmail&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;mtanino (&lt;a class="reference external" href="mailto:mitsuhiro.tanino%40hds.com"&gt;mitsuhiro&lt;span&gt;.&lt;/span&gt;tanino&lt;span&gt;@&lt;/span&gt;hds&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add new endpoint to Cinder API.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add RPC call.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add new volume manager method for get_capabilities.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update LVM reference implementation with get_capabilities method.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;The decision on what the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;well&lt;/span&gt; &lt;span class="pre"&gt;defined&lt;/span&gt;&lt;/code&gt; capabilities will be [2].&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Eventually, tempest tests once all drivers are supporting it.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Update the Cinder developer documentation for driver maintainers to reference
how to push capabilities from their volume driver.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;[1] - &lt;a class="reference external" href="http://docs.openstack.org/developer/cinder/devref/drivers.html#minimum-features"&gt;http://docs.openstack.org/developer/cinder/devref/drivers.html#minimum-features&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[2] - &lt;a class="reference external" href="https://review.openstack.org/#/c/150511"&gt;https://review.openstack.org/#/c/150511&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Related horizon spec: &lt;a class="reference external" href="https://blueprints.launchpad.net/horizon/+spec/vol-type-extra-specs-describe"&gt;https://blueprints.launchpad.net/horizon/+spec/vol-type-extra-specs-describe&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Thu, 16 Nov 2017 00:00:00 </pubDate></item><item><title>Generic image cache functionality</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/liberty/image-volume-cache.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/image-volume-cache"&gt;https://blueprints.launchpad.net/cinder/+spec/image-volume-cache&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Currently some volume drivers implement the clone_image method and use an
internal cache of volumes on the backend that hold recently used images. For
storage backends that can do very efficient volume clones it is a potentially
large performance improvement over having to attach and copy the image
contents to a each volume. To make this functionality easier for other volume
drivers to use, and prevent any duplication in the code base, we should
implement a more unified way to do this caching.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;If we don’t create a unified approach to this image caching we will end up
with multiple vendors implementing it in volume drivers. This means duplicated
code, redundant vendor prefixed config options, and a non-uniform way for
admins to set up and configure image caching.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;The primary (and I think only) use case for this is when creating a volume
from an image more than once. As an end user I will see (potentially) faster
volume creation from an image after the first time, and as an admin once I
set this up once in the backend configuration it should require no more
interaction.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;When creating a volume from an image using the cache there are a few high
level steps to take:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Check if an image has a corresponding entry in the cache.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If it is in the cache but has been updated, delete it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;If it wasn’t in the cache (or isn’t anymore)&lt;/dt&gt;&lt;dd&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Evict an old image entry if room is needed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a volume from an image (the ‘normal’ way of copying data over),
this volume will henceforth be known as the ‘image-volume’. This volume
would be owned by a special tenant that is controlled by Cinder.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update the cache to know about this new image-volume and its image
contents.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Clone the image-volume.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This new behavior would be enabled via a new volume driver config option
called ‘image_volume_cache_enabled’. The size of this cache will then be
defined by a few new config options:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;image_volume_cache_max_size_gb&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;image_volume_cache_max_size_percent&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;image_volume_cache_max_count&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These options are scoped to each backend.&lt;/p&gt;
&lt;p&gt;In the _create_from_image of CreateVolumeFromSpecTask we can add in the logic
to check first if the image cache is enabled for the target backend. If it is
then we can use the cache, if not we use the slow path only. This would be
done after driver.clone_image is called to give a backend a chance to do an
even more optimal clone if possible.&lt;/p&gt;
&lt;p&gt;For the actual image-volume I think it would be best if we can re-use the
normal Cinder Volume model and database table. Ideally we can leverage the
cinder-internal tenant feature so that the special tenant will own these
cached images.&lt;/p&gt;
&lt;p&gt;We then would need a new table to track our image cache. This table will have
Volume, Image, and Host id’s, as well as image meta-data to make a decision
as to whether or not it is still ‘valid’. More details in the Data Model
Impact section.&lt;/p&gt;
&lt;p&gt;This information gives us enough to look up whether or not a image is in the
cache for a target backend, and make the decision to either create a new one
or not and then call _create_from_source_volume with the image-volume.&lt;/p&gt;
&lt;p&gt;As far as the volume driver is concerned it would be creating volumes from an
image and cloning volumes, it would not need to be aware of the cache at all
for the creation methods.&lt;/p&gt;
&lt;p&gt;For any backends which need to use snapshots they will have to transition from
image-volume -&amp;gt; snapshot -&amp;gt; volume. In the future this image cache table could
always be expanded to have a snapshot_id in addition to the volume_id, but for
the first iteration of this it will only deal with volumes as the cache
backing.&lt;/p&gt;
&lt;p&gt;There is a possibility of a race within the cache where an image-volume would
be getting evicted and is selected to be used for a clone operation. If this
happens we should catch the error and attempt to create the volume by
downloading the image. It is also possible that multiple of the same images
are cached at the same time, this is considered ‘OK’, eventually extra ones
will be evicted if space is needed.&lt;/p&gt;
&lt;p&gt;In future iterations of this we could expose the objects in the cache as
public snapshots, and store the backing volume for other public snapshots
in the same way we do the cached objects. This should allow for quite a bit
of re-use in the code, and give users another way to get quick copies of
volumes for backends with optimized snapshot-&amp;gt;volume and volume-&amp;gt;volume
operations. In the first iteration this functionality will not be provided.
It is worth noting so that we can ensure the implementation is extensible to
allow for it in the future.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;A very simple alternative to this is to simply push all this logic and
behavior into each volume driver and live with the duplicated code and config
options. This however prohibits backends that cannot store meta-data for their
volumes anywhere.&lt;/p&gt;
&lt;p&gt;Another alternative is to not use the actual Volume objects and to expand the
image cache table to have enough information for a backend to create volumes
and clones from it (maybe metadata type values?). Then we could add new API’s
to the volume driver such as ‘create_cached_image_volume’,
‘delete_cached_image_volume’, ‘create_volume_from_cached_image’, and so on.
This would put more of the logic into the volume drivers, but requires them to
implement these new methods. The benefit here is that we don’t start having
special ‘internal’ volumes. The downside being that each driver then has to
implement all of these methods which would do almost the same thing as
create_volume, delete_volume, etc, but with different parameters.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;A new database table for the image cache.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;+------------+-----------+--------------------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="n"&gt;NAME&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="n"&gt;TYPE&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="n"&gt;DESCRIPTION&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+------------+-----------+--------------------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;                                &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;String&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;Auto&lt;/span&gt; &lt;span class="n"&gt;generated&lt;/span&gt; &lt;span class="n"&gt;UUID&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;                                &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;updated_at&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;DateTime&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="n"&gt;updated_at&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;the&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="n"&gt;metadata&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;                                &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;host_id&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;String&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;ForeignKey&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;Host&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="n"&gt;that&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;has&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;backing&lt;/span&gt; &lt;span class="n"&gt;volume&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;                                &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;volume_id&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;String&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;ForeignKey&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;Volume&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;backing&lt;/span&gt; &lt;span class="n"&gt;volume&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;                                &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;image_id&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;String&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;the&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;metadata&lt;/span&gt;                       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+------------+-----------+--------------------------------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;The special Cinder owned tenant could potentially be a risk if someone was able
to get a hold of its credentials or access the image-volumes. Worst case
someone could alter the cached image volumes if they had permission to attach
and write to them directly.&lt;/p&gt;
&lt;p&gt;Care will have to be taken to ensure it isn’t accessible by normal users.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;New info log messages and event notifications for whether the cache hit
or missed. That way there is enough info to determine how effective it is and
if settings need to be adjusted.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;This should improve performance on average for systems that can do efficient
volume clones when doing create volume from image. There will be many factors
involved as to how much it changes, but it is unlikely to be much slower.&lt;/p&gt;
&lt;p&gt;It is possible this will add some delay on occasional requests which hit a
‘worst case’ scenario of having to do the database lookups, trying to create
from a cached image, failing because it got evicted, and then doing the image
download. In situations where that occurs frequently the cache size could be
modified or the feature disabled.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;New configuration options for a cinder backend that would potentially need to
be set:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;image_volume_cache_enabled (Boolean)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;image_volume_cache_max_size_gb (Integer)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;image_volume_cache_max_size_percent (Integer)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;image_volume_cache_max_count (Integer)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Just new DB API’s and tables to be aware of.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;patrick-east&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;None&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;DB changes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;create_volume flow changes&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;DB migration tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unit tests for DB API’s&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unit tests for flow changes&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;New configuration options.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/cinder-internal-tenant"&gt;https://blueprints.launchpad.net/cinder/+spec/cinder-internal-tenant&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Thu, 16 Nov 2017 00:00:00 </pubDate></item><item><title>Implement force_detach for safe cleanup</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/liberty/implement-force-detach-for-safe-cleanup.html</link><description>

&lt;p&gt;Include the URL of your launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/implement-force-detach-for-safe-cleanup"&gt;https://blueprints.launchpad.net/cinder/+spec/implement-force-detach-for-safe-cleanup&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Currently, there is no API to synchronize the state in the Cinder database and
the backend storage when a volume is in a stuck ‘attaching’ or ‘detaching’
state. For example, if a volume is stuck in detaching, but is
attached/connected by the storage driver, the admin is allowed to use
‘cinder reset-state &amp;lt;vol_id&amp;gt;’ to set the state of the volume to ‘detached’.
This will be mismatched with the backend storage state, which has the volume
connected/exported to the compute host and nova instance. If the volume state
is reset to ‘available’ and ‘detached’, it can be attached to a second
instance (note that this is not multi-attach) and lead to data corruption.
This spec proposes to plumb cinder APIs that allow an admin to set the state to
‘available’ and ‘detached’ in a safe way, meaning that the backend storage and
cinder db are synchronized.
An attempt was made to merge a Nova spec to add a ‘–force’ option, but it has
stalled and will likely be replaced with some Nova code changes. See:
&lt;a class="reference external" href="https://review.openstack.org/#/c/84048/44"&gt;https://review.openstack.org/#/c/84048/44&lt;/a&gt;
Nova devs have proposed an idempotent ‘nova volume-detach…’ that will
1) detach the volume from the VM (libvirt.detach) 2) call cinder to detach
and Ignore Cinder Errors 3) remove the BlockDeviceMapping from Nova DB.
This will have the effect of cleaning up Nova side but possibly leaving
Cinder in an error/out_of_sync state, and will require a manual cleanup for
Cinder, i.e. cinderclient ‘force-detach’.
(cinderclient patch: &lt;a class="reference external" href="https://review.openstack.org/#/c/187305/"&gt;https://review.openstack.org/#/c/187305/&lt;/a&gt;)&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;It is not uncommon to have a volume stuck in a state that prevents the user
from using the volume or changing state, i.e. ‘attaching’, ‘deleting’,
‘creating’, ‘detaching’. The python-cinderclient has the command ‘reset-state’
to allow an admin to change the volume state in the cinder database to any
state desired.
In order to fix the problem in a safe and robust way, however, the admin must
check the state of the volume with regards to the backend storage and Nova. Is
the volume attached according to the metadata of the backend? Is there an iSCSI
connection (or FC) to the compute host? Does Nova BlockDeviceMapping have an
entry for the volume? Cleanup to the Cinder DB is possible, cleanup on the
storage backend may be possible, and changing the Nova DB requires direct
changes (SQL commands) on the Nova database. Synchronizing state requires
detailed knowledge of all of the components, and often invasive and dangerous
changes to production systems.
Changing python-cinderclient ‘reset-state’ has been proposed[1], but that
idea was rejected in favor of implementing separate APIs for achieving the
desired state[2]. This spec is to implement ‘force_detach’. There is already a
‘force_delete’ API for help with volumes stuck in ‘creating’ or ‘deleting’.
In fact, there is already a force_detach API that calls terminate_connection
and detach, but this appears to be unused elsewhere in the code base and
should be properly implemented to test whether the driver can comply, and in
the case of success from the driver the function should cleanup the Cinder DB.
It could be argued that there should be an analogous ‘force_attach’ or perhaps
more aptly named ‘force_rollforward_attach’, but it seems that simply forcing
a detach of a volume will put the volume back in a state where the attach can
be attempted again.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;UseCase1: Cinder DB ‘attaching’, storage back end ‘available’, Nova DB
does not show block device for this volume.
An attempt was made to attach a volume using ‘nova volume-attach &amp;lt;instance&amp;gt;
&amp;lt;volume_id&amp;gt;’
The Cinder DB is set to ‘attaching’, but the volume was never attached.
Current Fix: Using python-cinderclient ‘reset-state’ to set the Cinder DB to
‘available’ will fix this.
Proposed Fix: An attempt to detach from Nova will fail, since Nova does not
know about this volume.
Implementing Cinder force_detach and exposing to the cinderclient will allow
cinder to call the backend to cleanup (default implementation is
terminate_connection and detach, but can be overridden) and then set Cinder DB
state to ‘available’ and ‘detached’.&lt;/p&gt;
&lt;p&gt;UseCase2: Cinder DB ‘attaching’, storage back end ‘attached’, Nova DB
shows block device for this volume.
The Cinder DB is set to ‘attaching’, but the volume was attached.
Current Fix: Using python-cinderclient ‘reset-state’ to set the Cinder DB to
‘available’ will result in an out-of-sync state, since the volume is, in fact,
attached. Nova will not allow this volume to be re-attached.
Proposed Fix: An attempt to detach from Nova will cleanup on the Nova side
(after proposed Nova changes) but fail in Cinder since the state is
‘attaching’.
Implementing Cinder force_detach and exposing to the cinderclient will allow
cinder to call the backend to cleanup (default implementation is
terminate_connection and detach, but can be overridden) and then set Cinder DB
state to ‘available’ and ‘detached’.&lt;/p&gt;
&lt;p&gt;UseCase3: Cinder DB ‘detaching’, storage back end ‘available’, Nova DB
does not show block device for this volume.
An attempt was made to detach a volume using ‘nova volume-detach &amp;lt;instance&amp;gt;
&amp;lt;volume_id&amp;gt;’
The Cinder DB is set to ‘detaching’ and the volume is actually detached.
Current Fix: Using python-cinderclient ‘reset-state’ to set the Cinder DB to
‘available’ will fix this.
Proposed Fix: An attempt to detach from Nova will fail, since Nova does not
know about this volume.
Implementing Cinder force_detach and exposing to the cinderclient will allow
cinder to call the backend to cleanup (default implementation is
terminate_connection and detach, but can be overridden) and then set Cinder DB
state to ‘available’ and ‘detached’.&lt;/p&gt;
&lt;p&gt;UseCase4: Cinder DB ‘detaching’, storage back end ‘attached’, Nova DB
has a block device for this volume.
An attempt was made to detach a volume using ‘nova volume-detach &amp;lt;instance&amp;gt;
&amp;lt;volume_id&amp;gt;’
The Cinder DB is set to ‘detaching’, but the volume is actually attached.
Current Fix: Using python-cinderclient ‘reset-state’ to set the Cinder DB to
‘available’ will result in an out-of-sync state, since the volume is, in fact,
attached. Nova will not allow this volume to be re-attached.
Proposed Fix: An attempt to detach from Nova will cleanup on the Nova side
(after proposed Nova changes) but fail in Cinder since the state is
‘attaching’.
Implementing Cinder force_detach and exposing to the cinderclient will allow
cinder to call the backend to cleanup (default implementation is
terminate_connection and detach, but can be overridden) and then set Cinder DB
state to ‘available’ and ‘detached’.&lt;/p&gt;
&lt;p&gt;UseCase5: During an attach, initialize_connection() times out. Cinder DB is
‘available’, volume is attached, Nova DB does not show the block device.
Current Fix: None via reset-state. Manual intervention on the back end
storge is required
Proposed Fix: Code in nova/volume/cinder.py L#366 calls initialize_connection,
which can time out. A patch is up for review to put this in a try block and
cleanup if there is an exception:
&lt;a class="reference external" href="https://review.openstack.org/#/c/138664/6/nova/volume/cinder.py"&gt;https://review.openstack.org/#/c/138664/6/nova/volume/cinder.py&lt;/a&gt;
This patch could be modified to call force_detach() instead of
terminate_connection to insure the DB status entry is set to available
and allow for driver detach and any driver specific code to be called for
cleanup.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Nova must be changed, since it currently checks the state in the Cinder DB
and will fail a call to ‘volume-detach’ if Cinder does not show the volume
to be ‘attached’ and ‘in-use’. It is being proposed that Nova ingnore Cinder
state and do the libvirt.detach and removal of volume entry in BDM. Nova will
call Cinder and ignore any errors, leaving cleanup on the Cinder side to be
accomplished via manual intervention (i.e. ‘cinder force-detach….’
(Links to proposed Nova changes will be provided ASAP)&lt;/p&gt;
&lt;p&gt;Cinder force-detach API currently calls:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;volume_api&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;terminate_connection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;volume_api&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;detach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This will be modified to call into the VolumeManager with a new
force_detach(…)&lt;/p&gt;
&lt;p&gt;api/contrib/volume_actions.py: force_detach(…)&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;volume_rpcapi&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;force_detach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="c1"&gt;#catch and add debug message&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="c1"&gt;#something&lt;/span&gt;

&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_reset_status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;#fix DB if backend cleanup is successful&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;volume/manager.py: force_detach(…)&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;force_detach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Individual drivers will implement force_detach as needed by the driver, most
likely calling terminate_connection(..) and possibly other cleanup. The
force_detach(..) api should be idempotent: It should succeed if the volume is
not attached, and succeed if the volume starts off connected and can be
successfully detached.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Leave things as they are, requiring the admin to make manual changes using APIs
or commands on the back end storage to keep the state in sync. Nova has no API
to cleanup the BlockDeviceMapping table. Using ‘reset-state’ can work, as in
UseCase1 and UseCase3, or it can break things and render a volume incapable
of being attached, as in UseCase2 and UseCase4.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;Detach notification will indicate force_detach&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;BaseVD class will implement force_detach as it is today, calling
terminate_connection and detach. Driver developers can override this
function if there is more they wish to do in their driver.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Primary assignee:
scott-dangelo&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;Changes to core Cinder code
Drivers implementation of force_detach, if it is desired to override
cinderclient changes (&lt;a class="reference external" href="https://review.openstack.org/#/c/187305/"&gt;https://review.openstack.org/#/c/187305/&lt;/a&gt;)&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None
Nova changes are independent of this spec&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit tests for test_force_detach* will be modified as appropriate.
Tempest tests will be added to verify a volume in an attaching or detaching
state can be force_detached and then successfuly re-attached.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Docs will need to be updated for the python-novaclient changes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;[1] &lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/reset-state-with-driver"&gt;https://blueprints.launchpad.net/cinder/+spec/reset-state-with-driver&lt;/a&gt;&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/134366/2"&gt;https://review.openstack.org/#/c/134366/2&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;[2] &lt;a class="reference external" href="https://etherpad.openstack.org/p/cinder-meetup-winter-2015"&gt;https://etherpad.openstack.org/p/cinder-meetup-winter-2015&lt;/a&gt; L#405&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 16 Nov 2017 00:00:00 </pubDate></item><item><title>Non Disruptive Backup</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/liberty/non-disruptive-backup.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/non-disruptive-backup"&gt;https://blueprints.launchpad.net/cinder/+spec/non-disruptive-backup&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Currently a backup operation can only be performed when a volume is
detached. This blueprint proposes to use a temporary snapshot or
volume to do non-disruptive backup.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;If a volume is attached, it has to be detached first before it can
be backed up. This is not efficient and it disrupts normal operations
by cloud users just to do a backup.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;The use case is that an end user would like to do a backup without
detaching the volume.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;For an attached volume, taking a temporary snapshot is usually less
expensive than creating a whole temporary volume. If we can attach the
snapshot and read it directly, we do not have to create another
temporary volume. It is quicker to complete the backup this way.&lt;/p&gt;
&lt;p&gt;If a driver has not implemented attach snapshot and does not have a way
to read from a snapshot, we can create a temporary volume from the
attached source volume, and backup the temporary volume.&lt;/p&gt;
&lt;p&gt;For the LVM driver, because the backup service is on the same node as
the volume driver, we can just read the local path of the temporary
snapshot after it is created from the attached source volume. We will
create a temporary snapshot, but there is no need to attach snapshot
for LVM.&lt;/p&gt;
&lt;p&gt;In the future, if the backup service can be on a different node than
the volume driver, then we can look into whether to do attach snapshot
for LVM as well, however, there are concerns that introducing the
attach snapshot logic will complicate the LVM code. This is for the
future, so it can be decided later.&lt;/p&gt;
&lt;p&gt;This proposal will be implemented in multiple steps.&lt;/p&gt;
&lt;p&gt;Step 1:&lt;/p&gt;
&lt;p&gt;For the LVM driver, take a temporary snapshot of the attached volume
and back it up.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Take a temporary snapshot&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Do backup from the local path of the temporary snapshot&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cleanup temporary snapshot&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For other drivers, provide a default implementation by creating a
temporary volume and backing it up.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create a temporary volume from the source volume&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Attach the temporary volume&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Do backup from the temporary volume&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Detach the temporary volume&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cleanup temporary volume&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Note: If the volume is not attached, it will be backed up the same
way as before.&lt;/p&gt;
&lt;p&gt;Step 2:&lt;/p&gt;
&lt;p&gt;Provide a more optimized way for other drivers to use a temporary
snapshot to backup an attached volume. For drivers that cannot read
from a local path of a snapshot, we need to define an interface for
attaching a snapshot, similar to attaching a volume.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Take a temporary snapshot&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Attach the temporary snapshot&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Do backup from the temporary snapshot&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Detach the temporary snapshot&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cleanup temporary snapshot&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Step 3 (future):&lt;/p&gt;
&lt;p&gt;If the backup service can use the volume driver on a remote node
in the future, we can provide a way for the call to happen through
RPC. This is similar to step 2, except that it will call the volume
manager on a remote node using RPC API to attach snapshot.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;There are a couple of alternatives:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Detach the volume and back it up.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Take a snapshot of the attached volume, create a volume from the
snapshot and then back it up.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;Step 1:&lt;/p&gt;
&lt;p&gt;Add the following new columns to the backups table for the temporary
volume and snapshot id:&lt;/p&gt;
&lt;p&gt;temp_volume_id = Column(String(36))
temp_snapshot_id = Column(String(36))&lt;/p&gt;
&lt;p&gt;Add the following new column to the volumes table to persist the
status of a volume before it is changed to ‘backing-up’ status.
This will be used to restore the volume status back to either
‘available’ or ‘in-use’ after the backup is complete. This is
also used for cleaning up failed backups when the backup service
is restarted. This is because the cleanup procedure is different
for ‘available’ and ‘in-use’ volumes.&lt;/p&gt;
&lt;p&gt;previous_status = Column(String(255))&lt;/p&gt;
&lt;p&gt;Step 2:&lt;/p&gt;
&lt;p&gt;Add the following new column to the snapshots table. The snapshots
table already has provider_id and provider_location like the volumes
table. This provider_auth column is needed to save the authentication
data when a target is created for the snapshot. This is needed if we
want to attach the snapshot.&lt;/p&gt;
&lt;p&gt;provider_auth = Column(String(255))&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;Step 1:&lt;/p&gt;
&lt;p&gt;Change the existing create backup API to take a force flag.
If the volume is ‘in-use’, the force flag has to be True.
By default it is False. The force flag is not needed for
‘available’ volumes.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Create backup
* V2/&amp;lt;tenant id&amp;gt;/backups
* Method: POST
* JSON schema definition for V2:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"backup"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"display_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"nightly001"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# existing&lt;/span&gt;
        &lt;span class="s2"&gt;"display_description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Nightly backup"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# existing&lt;/span&gt;
        &lt;span class="s2"&gt;"volume_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"xxxxxxxx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# existing&lt;/span&gt;
        &lt;span class="s2"&gt;"container"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"nightlybackups"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"force"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# new&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Step 2:&lt;/p&gt;
&lt;p&gt;The following driver APIs will be added to support attach snapshot and
detach snapshot.&lt;/p&gt;
&lt;p&gt;attach snapshot:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;_attach_snapshot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;snapshot&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                     &lt;span class="n"&gt;remote&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;create_export_snapshot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;conext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;snapshot&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;initialize_connection_snapshot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;snapshot&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                   &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;detach snapshot:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;_detach_snapshot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;attach_info&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;snapshot&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                     &lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;force&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;remote&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;terminate_connection_snapshot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;snapshot&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                  &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;remove_export_snapshot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;snapshot&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Alternatively we can use an is_snapshot flag for volume and snapshot
to share common code without adding new functions, but it will make
the code confusing and hard to read. So there is a trade off between
reducing code duplication and increasing code readibilty here.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;End user will be able to create a backup without detaching the volume.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;No obvious performance impact.&lt;/p&gt;
&lt;p&gt;If we can attach the snapshot and back it up with the proposed change,
it will be cleaner and easier than manually taking a snapshot, creating
a volume from the snapshot, and then backing it up and deleting it.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;The deployer will be able to backup an attached volume.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Driver developers can implement the proposed new driver APIs for
more efficient backup. This is not required though. A default
implementation will be provided to create a temporary volume from
the source volume as discussed earlier.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&amp;lt;xing-yang&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&amp;lt;None&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Step 1: Provide a default implementation.
Patch in review here: &lt;a class="reference external" href="https://review.openstack.org/#/c/193937/"&gt;https://review.openstack.org/#/c/193937/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Step 2: Provide a more optimal implementation by adding new driver
APIs to support attach snapshot.
WIP patch proposed here: &lt;a class="reference external" href="https://review.openstack.org/#/c/201249/"&gt;https://review.openstack.org/#/c/201249/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Step 3 (future): This will happen after the backup service is
decoupled from the volume driver.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit tests will be provided.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Documentation will be modified to describe this feature.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Link to summit discussion:
&lt;a class="reference external" href="https://etherpad.openstack.org/p/cinder-liberty-backup-using-snapshot"&gt;https://etherpad.openstack.org/p/cinder-liberty-backup-using-snapshot&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Thu, 16 Nov 2017 00:00:00 </pubDate></item><item><title>Offload rbd’s copy_volume_to_image function from host to ceph cluster</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/liberty/optimze-rbd-copy-volume-to-image.html</link><description>

&lt;p&gt;Include the URL of your launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/optimze-rbd-copy-volume-to-image"&gt;https://blueprints.launchpad.net/cinder/+spec/optimze-rbd-copy-volume-to-image&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Offload rbd’s copy_volume_to_image function from cinder-volume host to
ceph cluster if cinder volume back end and glance storage back end are in
the same ceph storage cluster.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Suppose cinder volume back end and glance storage back end are in the same
ceph storage cluster.
Suppose the volume’s capacity and data size in the following description
are 1G.
Suppose cinder volume back end use “volumes” pool, and glance storage back end
use “images” pool.&lt;/p&gt;
&lt;p&gt;Currently upload-to-image routine works as follows:
1. cinder use command “rbd export” to export the rbd image as a local file in
cinder-volume host. Read 1G, and Write 1G.
2. cinder call glance upload/update API to upload the exported local file to
glance storage back end. Read 1G, and write 1G.&lt;/p&gt;
&lt;p&gt;So when we upload a 1G volume to image, we would read 2G data and write 2G
data. If we offload this function from cinder-volume host to ceph storage
cluster, we may only need to read 1G data and write 1G data, which could
reduce the half amount of data transmission compared to the current routine.&lt;/p&gt;
&lt;p&gt;Benefits:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Reduce the read/write cost of rbd’s copy_volume_to_image function,
especially when the volume’s capacity and data size are big.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reduce the IO pressure on cinder-volume host when doing the
copy_volume_to_image operation.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;By offload rbd’s copy_volume_to_image function from host to ceph cluster
, we need to do the following changes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Check whether cinder volume back end and glance storage back end are in the
same ceph storage cluster or not.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If not, keep the current work routine not change.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If yes, use rbd.Image.copy(dest_ioctx, dest_name) function to copy volume
from one pool to another pool because cinder volume back end and glance
storage back end always use different ceph pools.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Solution A: use rbd.Image.copy(dest_ioctx, dest_name) function to offload
rbd’s copy_volume_to_image function from host to ceph cluster.&lt;/p&gt;
&lt;p&gt;Solution B: use ceph’s functions of clone image and flatten clone image to
offload rbd’s copy_volume_to_image function from host to ceph cluster. It
contains the following steps.
* Create a volume snapshot snap_a and protect the snapshot snap_a.
* Clone a child image image_a of snap_a.
* Flatten the child image image_a, and snap_a has not been depended on.
* Unprotect the snapshot snap_a and delete it.&lt;/p&gt;
&lt;p&gt;Using a volume created based on “cirros-0.3.0-x86_64-disk” to show
the time-consuming between solution A and solution B.
* [Common]Create a volume based on image “cirros-0.3.0-x86_64-disk”.&lt;/p&gt;
&lt;div class="highlight-bash notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;root@devaio:/home#&lt;span class="w"&gt; &lt;/span&gt;cinder&lt;span class="w"&gt; &lt;/span&gt;list
+--------------------------------------+-----------+------+------+
&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt;                  &lt;/span&gt;ID&lt;span class="w"&gt;                  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;Status&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Name&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Size&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
+--------------------------------------+-----------+------+------+
&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;3d6e5781-e3ac-4106-bfed-0aa0dd3af1f8&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;available&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;None&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
+--------------------------------------+-----------+------+------+
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;[Solution-A-step-1]Copy
volumes/volume-3d6e5781-e3ac-4106-bfed-0aa0dd3af1f8 from “volumes” pool to
“images” pool.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-bash notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;root@devaio:/home#&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;rbd&lt;span class="w"&gt; &lt;/span&gt;cp
volumes/volume-3d6e5781-e3ac-4106-bfed-0aa0dd3af1f8&lt;span class="w"&gt; &lt;/span&gt;images/test

Image&lt;span class="w"&gt; &lt;/span&gt;copy:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;100&lt;/span&gt;%&lt;span class="w"&gt; &lt;/span&gt;complete...done.

real&lt;span class="w"&gt;    &lt;/span&gt;0m3.687s
user&lt;span class="w"&gt;    &lt;/span&gt;0m1.136s
sys&lt;span class="w"&gt;     &lt;/span&gt;0m0.557s
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;[Solution-B-step-1]Create a snapshot of volume
3d6e5781-e3ac-4106-bfed-0aa0dd3af1f8 and protect it.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-bash notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;root@devaio:/home#&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;rbd&lt;span class="w"&gt; &lt;/span&gt;snap&lt;span class="w"&gt; &lt;/span&gt;create&lt;span class="w"&gt; &lt;/span&gt;--pool&lt;span class="w"&gt; &lt;/span&gt;volumes&lt;span class="w"&gt; &lt;/span&gt;--image
volume-3d6e5781-e3ac-4106-bfed-0aa0dd3af1f8&lt;span class="w"&gt; &lt;/span&gt;--snap&lt;span class="w"&gt; &lt;/span&gt;image_test

real&lt;span class="w"&gt;    &lt;/span&gt;0m3.152s
user&lt;span class="w"&gt;    &lt;/span&gt;0m0.018s
sys&lt;span class="w"&gt;     &lt;/span&gt;0m0.013s

root@devaio:/home#&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;rbd&lt;span class="w"&gt; &lt;/span&gt;snap&lt;span class="w"&gt; &lt;/span&gt;protect
volumes/volume-3d6e5781-e3ac-4106-bfed-0aa0dd3af1f8@image_test

real&lt;span class="w"&gt;    &lt;/span&gt;0m3.043s
user&lt;span class="w"&gt;    &lt;/span&gt;0m0.016s
sys&lt;span class="w"&gt;     &lt;/span&gt;0m0.012s
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;[Solution-B-step-2]Do clone operation on
&lt;a class="reference external" href="mailto:volumes/volume-3d6e5781-e3ac-4106-bfed-0aa0dd3af1f8%40image_test"&gt;volumes/volume-3d6e5781-e3ac-4106-bfed-0aa0dd3af1f8&lt;span&gt;@&lt;/span&gt;image_test&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-bash notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;root@devaio:/home#&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;rbd&lt;span class="w"&gt; &lt;/span&gt;clone
volumes/volume-3d6e5781-e3ac-4106-bfed-0aa0dd3af1f8@image_test
images/snapshot_clone_image_test

real&lt;span class="w"&gt;    &lt;/span&gt;0m0.102s
user&lt;span class="w"&gt;    &lt;/span&gt;0m0.020s
sys&lt;span class="w"&gt;     &lt;/span&gt;0m0.016s
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;[Solution-B-step-3]Flatten the clone image images/snapshot_clone_image_test.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-bash notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;root@devaio:/home#&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;rbd&lt;span class="w"&gt; &lt;/span&gt;flatten&lt;span class="w"&gt; &lt;/span&gt;images/snapshot_clone_image_test

Image&lt;span class="w"&gt; &lt;/span&gt;flatten:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;100&lt;/span&gt;%&lt;span class="w"&gt; &lt;/span&gt;complete...done.

real&lt;span class="w"&gt;    &lt;/span&gt;0m10.228s
user&lt;span class="w"&gt;    &lt;/span&gt;0m1.375s
sys&lt;span class="w"&gt;     &lt;/span&gt;0m0.443s
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;[Solution-B-step-4]Unprotect the snap
&lt;a class="reference external" href="mailto:volumes/volume-3d6e5781-e3ac-4106-bfed-0aa0dd3af1f8%40image_test"&gt;volumes/volume-3d6e5781-e3ac-4106-bfed-0aa0dd3af1f8&lt;span&gt;@&lt;/span&gt;image_test&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-bash notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;root@devaio:/home#&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;rbd&lt;span class="w"&gt; &lt;/span&gt;snap&lt;span class="w"&gt; &lt;/span&gt;unprotect
volumes/volume-3d6e5781-e3ac-4106-bfed-0aa0dd3af1f8@image_test

real&lt;span class="w"&gt;    &lt;/span&gt;0m0.064s
user&lt;span class="w"&gt;    &lt;/span&gt;0m0.019s
sys&lt;span class="w"&gt;     &lt;/span&gt;0m0.015s
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;[Solution-B-step-5]Delete the no dependency snap
&lt;a class="reference external" href="mailto:volumes/volume-3d6e5781-e3ac-4106-bfed-0aa0dd3af1f8%40image_test"&gt;volumes/volume-3d6e5781-e3ac-4106-bfed-0aa0dd3af1f8&lt;span&gt;@&lt;/span&gt;image_test&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-bash notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;root@devaio:/home#&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;rbd&lt;span class="w"&gt; &lt;/span&gt;snap&lt;span class="w"&gt; &lt;/span&gt;rm
volumes/volume-3d6e5781-e3ac-4106-bfed-0aa0dd3af1f8@image_test

real&lt;span class="w"&gt;    &lt;/span&gt;0m0.235s
user&lt;span class="w"&gt;    &lt;/span&gt;0m0.017s
sys&lt;span class="w"&gt;     &lt;/span&gt;0m0.013s
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;By the above test result of solution A and solution B, solution A needs
(real:0m3.687s, user:0m1.136s, sys:0m0.557s) to finish the volume copy
operation and solution B needs (real:0m16.824s, user:0m1.465s, sys:0m0.512s)
to do that. So using solution A to offload rbd’s copy_volume_to_image function
from host to ceph cluster.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Offload rbd’s copy_volume_to_image function from host to ceph cluster could
make full use of ceph’s inherent data copy feature and the hardware capacity
of ceph storage cluster to expedite the volume data copy speed, reduce the
amount of data transmission and reduce the IO load on cinder-volume host.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;ling-yun&amp;lt;&lt;a class="reference external" href="mailto:zengyunling%40huawei.com"&gt;zengyunling&lt;span&gt;@&lt;/span&gt;huawei&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Implement code that mentioned in “Proposed change”.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;Cinder volume back end and glance storage back end are in the same
ceph storage cluster.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Both unit and Tempest tests need to be created to cover the code change that
mentioned in “Proposed change” and ensure that Cinder copy volume to image
feature works well while introducing the feature of offload rbd’s
copy_volume_to_image function from host to ceph cluster.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 16 Nov 2017 00:00:00 </pubDate></item><item><title>VolumeReplication_V2</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/liberty/replication_v2.html</link><description>

&lt;p&gt;Include the URL of your launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/replication-v2"&gt;https://blueprints.launchpad.net/cinder/+spec/replication-v2&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This spec proposes Version 2 of replication.  The goal is to take
some of the lessons we’ve learned from the first version of
replication that was added in the Juno release and see if we can
improve it a bit and make it something that is more widely usable
by other backend devices.&lt;/p&gt;
&lt;p&gt;This spec proposes a use of our entire tool-box to implement replication.&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Capabilities - determine if we can even do anything related to replication&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Types/Extra-Specs - provide mechanism for vendor-unique custom info and
help level out some of the unique aspects among the different back-ends.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;API Calls - provide some general API calls for things like enable,
disable etc&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;It would also be preferable to simplify the state management a bit if we can.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;The current implementation is fairly complex and  has proven to be difficult
to implement for backend devices as well as difficult to maintain.  There
is also some concern around how states are managed and stored in the data
base.&lt;/p&gt;
&lt;p&gt;The existing design is great for some backends, but is challenging for many
devices to fit in to.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;TBD.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;This spec proposes that we make some fairly significant changes to the
replication feature in Cinder.  We’d still rely on using capabilities and
types to identify whether a backend supports replication and ensure we
can place a volume correctly if we want to use the feature.  The big
difference however is around the creation of the replica and the life-cycle
that goes with it.  For the first iteration we would only support a single
remote device, but this is something that’s considered in this spec and
could easily be extended to be included in future work. Backend devices
(drivers) would be listed in the cinder.conf file and we add entries
to indicate pairing.  This could look something like this in the conf file:&lt;/p&gt;
&lt;div class="highlight-ini notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;[driver-foo]&lt;/span&gt;
&lt;span class="na"&gt;volume_driver&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;xxxx&lt;/span&gt;
&lt;span class="na"&gt;valid_replication_devices&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'backend=backend_name-a'&lt;/span&gt;&lt;span class="na"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;'backend&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;backend_name-b'....&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Alternatively the replication target can potentially be a device unknown
to Cinder&lt;/p&gt;
&lt;div class="highlight-ini notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;[driver-foo]&lt;/span&gt;
&lt;span class="na"&gt;volume_driver&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;xxxx&lt;/span&gt;
&lt;span class="na"&gt;valid_replication_devices&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'remote_device={'&lt;/span&gt;&lt;span class="na"&gt;some unique access meta}',...&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Or a combination of the two even&lt;/p&gt;
&lt;div class="highlight-ini notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;[driver-foo]&lt;/span&gt;
&lt;span class="na"&gt;volume_driver&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;xxxx&lt;/span&gt;
&lt;span class="na"&gt;valid_replication_devices&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'remote_device={'&lt;/span&gt;&lt;span class="na"&gt;some unique access meta}',&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;'backend&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;backend_name-b'....&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;NOTE That the remote_device access would have to be handled via the
configured driver.&lt;/p&gt;
&lt;p&gt;This proposal suggests that we would decouple the replication information
from the create call.  The flow would be something like this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Create a volume of type “replication_capable=True” and any custom info needed
by a specific backend.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cinder uses the existing functionality of the capabilities filter to pick
a backend that supports the requested replication type.  This is consistent
with the current create workflow, we just add another capability to the
scheduler.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the following API calls
- enable_replication(volume)
- disable_replication(volume)
- failover_replicated_volume(volume)
- update_replication_targets()&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;[mechanism to add tgts external to the conf file * optional]&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;get_replication_targets()
+ [mechanism for an admin to query what a backend has configured]&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="special-considerations"&gt;
&lt;h3&gt;Special considerations&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;volume-types
There should not be a requirement of an exact match of volume-types between
the primary and secondary volumes in the replication set.  If a backend “can”
match these exactly, then that’s fine, if they can’t, that’s ok as well.&lt;/p&gt;
&lt;p&gt;Ideally, if the volume fails over the type specifications would match, but if
this isn’t possible it’s probably acceptable, and if it needs to be handled
by the driver via a retype/modification after the failover, that’s fine as
well.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;async vs sync
This spec assumes async replication only for now.  It can easily be
extended later for the synchronous case, but for now it’s specific
to async.  If/When sync is added it can be specified as an additional
backend capability.  It’s also possible for this to be specified via
extra-specs if desired.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;transport
Implementation details and the &lt;em&gt;how&lt;/em&gt; the backend performs replication
is completely up to the backend.  The requirements are that the interfaces
and end results are consistent.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cinder does not need to be aware of both backend devices but CAN be
This spec is intended to provide flexibility, that means that if an
admin wishes to configure a backend device that is unknown to Cinder
that absolutely fine.  The opposite is true as well of course, that
detail is outlined in this spec.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tenant visibility
The visibility by tenants is LIMITED!!!  In other words the tenant
should know very little about what’s going on (if anything at all).&lt;/p&gt;
&lt;p&gt;For example, a service provider may sell replication simply as a
volume-type defined as “highly available” and have that equate to
replication.  The point is there’s absolutely no reason an end user
should have to know anything at all about replication (unless it costs
them more money).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;What about devices that can’t do individual volume-rep
It’s up to them to figure out what they want to do.  If for example
they replicate by pool, then maybe they can be sophisticated enough to
put all the volumes of replication type in the same pool and replicate
the entire pool.&lt;/p&gt;
&lt;p&gt;There are lots of options here I think, the point of this spec is that
it does not exclude any implementation.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="workflow-diagram"&gt;
&lt;h3&gt;Workflow diagram&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Create call on the left:&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;No change to workflow&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;Replication calls on the right:&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Direct to manager then driver via host entry&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;div class="highlight-console notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="go"&gt;     +-----------+&lt;/span&gt;
&lt;span class="go"&gt;+--&amp;lt; +Volume API + &amp;gt;---------+        Enable routing directly to&lt;/span&gt;
&lt;span class="go"&gt;|    +-----------+           |        Manager then driver, via host&lt;/span&gt;
&lt;span class="go"&gt;|                            |&lt;/span&gt;
&lt;span class="go"&gt;|                            |&lt;/span&gt;
&lt;span class="go"&gt;|    +-----------+           |&lt;/span&gt;
&lt;span class="go"&gt;+--&amp;gt; + TaskFlow  |           |&lt;/span&gt;
&lt;span class="go"&gt;+--&amp;lt; +-----------+           |&lt;/span&gt;
&lt;span class="go"&gt;|                            |&lt;/span&gt;
&lt;span class="go"&gt;|                            |&lt;/span&gt;
&lt;span class="go"&gt;|    +-----------+           |&lt;/span&gt;
&lt;span class="go"&gt;+--&amp;gt; + Scheduler |           |&lt;/span&gt;
&lt;span class="go"&gt;+--&amp;lt; +-----------+           |&lt;/span&gt;
&lt;span class="go"&gt;|                            |&lt;/span&gt;
&lt;span class="go"&gt;|                            |&lt;/span&gt;
&lt;span class="go"&gt;|    +-----------+           |&lt;/span&gt;
&lt;span class="go"&gt;+--&amp;gt; +  Manager  | &amp;lt;---------+&lt;/span&gt;
&lt;span class="go"&gt;+--&amp;lt; +-----------+ &amp;gt;---------+&lt;/span&gt;
&lt;span class="go"&gt;|                            |&lt;/span&gt;
&lt;span class="go"&gt;|                            |&lt;/span&gt;
&lt;span class="go"&gt;|    +-----+-----+           |&lt;/span&gt;
&lt;span class="go"&gt;+--&amp;gt; +  Driver   + &amp;lt;---------+&lt;/span&gt;
&lt;span class="go"&gt;     +-----+-----+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;In the case of calls like attach, extend, clone, delete etc;
if either the backend host is not reachable, or if the primary_host_status
column is set, we’ll redirect to the host in the secondary_hosts
column.  If that’s unavailable then we fail, just like we do today.&lt;/p&gt;
&lt;p&gt;See DB section below&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;There are all sorts of alternatives, the most obvious of which is to leave
the implementation we have and iron it out.  Maybe that’s good, maybe that’s
not.  In my opinion this approach is simpler, easier to maintain and more
flexible; otherwise I wouldn’t propose it.  The fact that there’s only
one vendor that’s implemented replication in the existing setup and they
have a number of open issues currently we’re not causing a terrible amount
of churn or disturbance if we move forward with this now.&lt;/p&gt;
&lt;p&gt;The result will be something that should be easier to implement and as an
option will have less impact on the core code.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;What new data objects and/or database schema changes is this going to
require?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;None, for the first pass we should be able to effectively use the existing
replication related columns.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;We would need to add the API calls mentioned above:&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;enable_replication(volume)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;disable_replication(volume)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;failover_replicated_volume(volume)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;udpate_replication_targets()
[mechanism to add tgts external to the conf file * optional]&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;get_replication_targets()
[mechanism for an admin to query what a backend has configured]&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;I think augmenting the existing calls is better than reusing them, but we can
look at that more closely in the submission stage.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;Describe any potential security impact on the system.  Some of the items to
consider include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Does this change touch sensitive data such as tokens, keys, or user data?&lt;/p&gt;
&lt;p&gt;Nope&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Does this change alter the API in a way that may impact security, such as
a new way to access sensitive information or a new way to login?&lt;/p&gt;
&lt;p&gt;Nope, not that I know of&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Does this change involve cryptography or hashing?&lt;/p&gt;
&lt;p&gt;Nope, not that I know of&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Does this change require the use of sudo or any elevated privileges?&lt;/p&gt;
&lt;p&gt;Nope, not that I know of&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Does this change involve using or parsing user-provided data? This could
be directly at the API level or indirectly such as changes to a cache layer.&lt;/p&gt;
&lt;p&gt;Nope, not that I know of&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Can this change enable a resource exhaustion attack, such as allowing a
single API interaction to consume significant server resources? Some examples
of this include launching subprocesses for each connection, or entity
expansion attacks in XML.&lt;/p&gt;
&lt;p&gt;Nope, not that I know of&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For more detailed guidance, please see the OpenStack Security Guidelines as
a reference (&lt;a class="reference external" href="https://wiki.openstack.org/wiki/Security/Guidelines"&gt;https://wiki.openstack.org/wiki/Security/Guidelines&lt;/a&gt;).  These
guidelines are a work in progress and are designed to help you identify
security best practices.  For further information, feel free to reach out
to the OpenStack Security Group at &lt;a class="reference external" href="mailto:openstack-security%40lists.openstack.org"&gt;openstack-security&lt;span&gt;@&lt;/span&gt;lists&lt;span&gt;.&lt;/span&gt;openstack&lt;span&gt;.&lt;/span&gt;org&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;Please specify any changes to notifications. Be that an extra notification,
changes to an existing notification, or removing a notification.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;Aside from the API, are there other ways a user will interact with this
feature?&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Does this change have an impact on python-cinderclient? What does the user
interface there look like?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Describe any potential performance impact on the system, for example
how often will new code be called, and is there a major change to the calling
pattern of existing code.&lt;/p&gt;
&lt;p&gt;Examples of things to consider here include:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;A periodic task might look like a small addition but when considering
large scale deployments the proposed call may in fact be performed on
hundreds of nodes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Scheduler filters get called once per host for every volume being created,
so any latency they introduce is linear with the size of the system.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A small change in a utility function or a commonly used decorator can have a
large impacts on performance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Calls which result in a database queries can have a profound impact on
performance, especially in critical sections of code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Will the change include any locking, and if so what considerations are there
on holding the lock?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;Discuss things that will affect how you deploy and configure OpenStack
that have not already been mentioned, such as:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;What config options are being added? Should they be more generic than
proposed (for example a flag that other volume drivers might want to
implement as well)? Are the default values ones which will work well in
real deployments?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Is this a change that takes immediate effect after its merged, or is it
something that has to be explicitly enabled?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If this change is a new binary, how would it be deployed?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Please state anything that those doing continuous deployment, or those
upgrading from the previous release, need to be aware of. Also describe
any plans to deprecate configuration values or features.  For example, if we
change the directory name that targets (LVM) are stored in, how do we handle
any used directories created before the change landed?  Do we move them?  Do
we have a special case in the code? Do we assume that the operator will
recreate all the volumes in their cloud?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Discuss things that will affect other developers working on OpenStack,
such as:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;If the blueprint proposes a change to the driver API, discussion of how
other volume drivers would implement the feature is required.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Who is leading the writing of the code? Or is this a blueprint where you’re
throwing it out there to see who picks it up?&lt;/p&gt;
&lt;p&gt;If more than one person is working on the implementation, please designate the
primary author and contact.&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;john-griffith&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&amp;lt;launchpad-id or None&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;Work items or tasks – break the feature up into the things that need to be
done to implement it. Those parts might end up being done by different people,
but we’re mostly trying to understand the timeline for implementation.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Include specific references to specs and/or blueprints in cinder, or in other
projects, that this one either depends on or is related to.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If this requires functionality of another project that is not currently used
by Cinder (such as the glance v2 API when we previously only required v1),
document that fact.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Does this feature require any new library dependencies or code otherwise not
included in OpenStack? Or does it depend on a specific version of library?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Please discuss how the change will be tested. We especially want to know what
tempest tests will be added. It is assumed that unit test coverage will be
added so that doesn’t need to be mentioned explicitly, but discussion of why
you think unit tests are sufficient and we don’t need to add more tempest
tests would need to be included.&lt;/p&gt;
&lt;p&gt;Is this untestable in gate given current limitations (specific hardware /
software configurations available)? If so, are there mitigation plans (3rd
party testing, gate enhancements, etc).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;What is the impact on the docs team of this change? Some changes might require
donating resources to the docs team to have the documentation updated. Don’t
repeat details discussed above, but please reference them here.&lt;/p&gt;
&lt;p&gt;Obviously this is going to need docs&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;Please add any useful references here. You are not required to have any
reference. Moreover, this specification should still make sense when your
references are unavailable. Examples of what you could include are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Links to mailing list or IRC discussions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Links to notes from a summit session&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Links to relevant research, if appropriate&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Related specifications as appropriate (e.g. link to any vendor documentation)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Anything else you feel it is worthwhile to refer to&lt;/p&gt;
&lt;p&gt;The specs process is a bit much, we should revisit it.  It’s rather
bloated, and while the first few sections are fantastic for requiring
thought and planning, towards the end it just gets silly.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Thu, 16 Nov 2017 00:00:00 </pubDate></item><item><title>RPC and VersionedObject Compatibility</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/liberty/rpc-object-compatibility.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/rpc-object-compatibility"&gt;https://blueprints.launchpad.net/cinder/+spec/rpc-object-compatibility&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The following proposal is to enable rolling upgrade in cinder.  More
specifically, it allows cinder services (cinder-api, cinder-scheduler,
cinder-backup, and cinder-volume) to be updated one at a time and yet still
be operational (only one service is taken down for upgrade instead of all).
It follows the rolling upgrade feature in nova, using oslo_versionedobjects,
but is different in that there is no indirection API.  Instead, RPC versions
and objects are going to be pinned to a backwards compatible version and
later switched to the latest version when all services are upgraded.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Today, when a new milestone is released, it can take quite a while to upgrade
all the service within an OpenStack cloud to the latest release.  Upgrade
involves: synching the database to the latest schema and updating each
distributed cinder service.  This process can take down part of a cloud for a
few hours or possibly longer.  Operators ideally like to reduce the down time
for their cloud when upgrading to the next release.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;As an operator, I want to individually upgrade each service to the latest
release, but not take down my entire cloud in the process.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;There are a couple of problems with upgrading a distributed service such as
cinder:
1. The content sent over RPC can change.
2. The RPC interface itself can change, i.e. new keyword arguments.&lt;/p&gt;
&lt;p&gt;To address these problems, the content can be made backwards compatible using
oslo_versionedobject, and the RPC interface can be pinned to a specific
version until all components within cinder are upgraded.&lt;/p&gt;
&lt;p&gt;The implementation is as follows:
1. When a service starts, it registers the RPC and object versions it knows
about, i.e. minimum and latest versions.&lt;/p&gt;
&lt;p&gt;2. On upgrade, the admin upgrades each individual cinder service.  When the
service starts, it knows that there is a newer version, but continue to run
at the current/pinned version indicated in the database.  The database is
the source of truth for which version a service should run.&lt;/p&gt;
&lt;p&gt;There is no specific order for which cinder service should be upgraded first.
The database keeps track of the RPC and object versions that the service
should be using.  The service will continue to use the specific versions
until an all clear is given by the admin (see below).&lt;/p&gt;
&lt;p&gt;3. While other cinder services are being upgraded, the service has to
constantly check the database for the current and available RPC and object
versions.  Since constantly accessing the database is a major performance hit,
it can be minimized by caching a copy of the table tracking the versions.
The copy will be valid for a few seconds (e.g. 5 seconds), and it is refreshed
afterwards.  This at least brings down the number of database access for each
RPC call.&lt;/p&gt;
&lt;p&gt;A flag is used internally within the service to track if it should
run in backwards compatibility mode (e.g. BACKWARD_COMPAT_MODE), i.e. RPC and
object versions to be made backwards compatible.  If the current version is
lower than the available version, then BACKWARD_COMPAT_MODE is set to true.
Otherwise, it is set to false.  There is logic in each service’s rpcapi.py
to set the correct keyword arguments for a given RPC version.  There is also
logic in the objects being sent over RPC to set the correct attributes for
a given target version.  More specifically, each object should be made
backwards compatible by a call to it’s own obj_make_compatible(), which
transforms the object to a given target version.&lt;/p&gt;
&lt;p&gt;4. Once all cinder services are upgraded, the admin executes a
“cinder-manage version upgrade” to switches the current/pinned versions to
the latest available versions.  This command basically updates the
service_versions table in the cinder database.  Since the current version is
equal to the available version, BACKWARD_COMPAT_MODE is set to false and each
RPC call no longer needs to check the database.&lt;/p&gt;
&lt;p&gt;By using the BACKWARD_COMPAT_MODE flag, each cinder service only needs to
be restarted once (i.e. once for upgrade).  Once the flag is turned off, each
cinder service can dynamically switch over to using the new RPC and object
versions.&lt;/p&gt;
&lt;p&gt;Once most of the cinder internals are switched to use oslo_versionedobject and
the RPC compatibility layer (this feature) is added, rolling upgrade should
be supported (hopefully in the Liberty release and onwards).  Rolling upgrade
should be limited to two releases older.  For example, release N would be
backwards compatible with release L (Liberty) and M, and release O would be
backwards compatible with release M and N.  For a host/service that is too
old, it should raise an exception on startup and not be allowed to start.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;The upgrade process can be left as-is, where all the components must be taken
down and upgraded at the same time.  Some cloud operators, e.g. Rackspace,
have automated their upgrade procedure to a few minutes.  However, other cloud
operators have a need for this feature.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;A new table, called service_versions, would be created to track the RPC and
object versions.  The schema would be as follows:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;service_versions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s1"&gt;'service_versions'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'created_at'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;timezone&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'updated_at'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;timezone&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'deleted_at'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;timezone&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'deleted'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;create_constraint&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;primary_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'service_id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'rpc_current_version'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'rpc_available_version'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'object_current_version'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'object_available_version'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="n"&gt;mysql_engine&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'InnoDB'&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The service_id is service name + host.  The *_current_version is the version
a service is currently running and pinned at.  The *_available_version is the
version a service knows about and (if newer) could upgrade to.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;A new command, i.e. “cinder-manage version upgrade”, would be introduced to
switch the cinder services to use the latest RPC and object versions.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;During upgrade, before a call is sent over RPC, it would have to check if
it needs to be backwards compatible.  If so, it would need to massage the RPC
interface and object to be backwards compatible.  It would incur a cost on
performance because there would be extra database calls to find the current
and available RPC and object versions.  Since accessing the database before
each RPC call is a major performance hit, it can be minimized by caching a copy
of the table tracking the versions.  The copy will be valid for a few seconds
(e.g. 5 seconds), and it is refreshed afterwards.  This at least brings down
the number of database access for each RPC call.  Once upgrade is done and
all services are upgrade to the latest versions, there would no longer be a
need to check the database.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Any new changes to the RPC interface within cinder-api, cinder-scheduler,
cinder-volume, or cinder-backup would have to add to the backwards compatible
layer from when this feature merges and onwards.  Also, any new changes to an
object, e.g. volume, snapshot, etc., must be made backwards compatible in the
object’s obj_make_compatible().&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;thang-pham&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;DuncanT (who thought of the feature)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create service_versions table to track RPC and object versions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Register each cinder service’s RPC and object versions on startup.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create RPC compatibility layer in each cinder component’s rpcapi.py to
massage the object and RPC interface before it is sent over RPC.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a “cinder-manage version upgrade” CLI to switch each cinder service
to use the latest versions.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;oslo_versionobjects for volumes, backups, service, consistency_group,
quota need to be merged so that objects can be made backwards compatible.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Ideally, there should be a rolling upgrade test within tempest (e.g. grenade)
to test basic RPC and object pinning between different releases.  However,
such testing would only apply to release M and onwards because most of the
oslo_versionedobject and RPC compatibility layers are not in previous
releases.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;It should be documented that operators can upgrade cinder components
individually, without taking down the entire cloud.  At the end of the
process, a “cinder-manage version upgrade” must be executed to switch the
services to use the latest RPC and object versions.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Etherpad: &lt;a class="reference external" href="https://etherpad.openstack.org/p/cinder-rolling-upgrade"&gt;https://etherpad.openstack.org/p/cinder-rolling-upgrade&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Versioning prototype: &lt;a class="reference external" href="https://review.openstack.org/#/c/184404/"&gt;https://review.openstack.org/#/c/184404/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Thu, 16 Nov 2017 00:00:00 </pubDate></item><item><title>Backup Force Delete API</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/liberty/support-force-delete-backup.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/support-force-delete-backup"&gt;https://blueprints.launchpad.net/cinder/+spec/support-force-delete-backup&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Provide an API to force delete a backup being stucked in creating or
restoring, etc..&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently there are volume force-delete and snapshot force-delete functions,
but there is not a force-delete function for backups. Force-delete for backups
would be beneficial when backup-create fails and the backup status is stuck in
‘creating’. This situation occurs when database just went down after backup
volume and metadata and update the volume’s status to ‘available’, leaving the
backup’s status to be ‘creating’ without having methods to deal with through
API, because backup-delete api could only delete backup item in status of
‘available’ and ‘error’.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;If backup create successfully in object storage, but become stuck in update
backup’s status because database just went down. Then use force-delete API,
we could directly delete the backup item(include all the stuff in storage
backend and db entry info) without manually change the backup’s status in
db to error or restart cinder-backup and call backup-delete function,
which is very useful for administrators.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;A new API function and corresponding cinder command will be added to force
delete backups.&lt;/p&gt;
&lt;p&gt;The proposal is to provide a method for administrator to quickly delete the
backup item that is not in the status of ‘available’ or ‘error’.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;It’s an admin-only operation.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;First, login in the cinder database, use the following update sql to change
the backup item status to ‘available’ or ‘error’.&lt;/p&gt;
&lt;p&gt;update backups set status=’available’(or ‘error’) where id=’xxx-xxx-xxx-xxx’;&lt;/p&gt;
&lt;p&gt;Second, call backup delete api to delete the backup item.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;Add a new REST API to delete backup in v2:&lt;/p&gt;
&lt;div class="highlight-console notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="go"&gt;POST /v2/{tenant_id}/backups/{id}/action&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"os-force_delete"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Normal http response code:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;202&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Expected error http response code:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;404&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;Delete notification should include whether force was used or not&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;A new command, backup-force-delete, will be added to python-cinderclient. This
command mirrors the underlying API function.&lt;/p&gt;
&lt;p&gt;Force delete a backup item can be performed by:
$ cinder backup-force-delete &amp;lt;backup&amp;gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;ling-yun&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Implement REST API&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement cinder client functions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement cinder command&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Need to test the force delete with an in-progress backup and ensure that it
deletes successfully and cleans up correctly.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;The cinder client documentation will need to be updated to reflect the new
command.&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/admin-guide/blockstorage-manage-volumes.html"&gt;http://docs.openstack.org/admin-guide/blockstorage-manage-volumes.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The cinder API documentation will need to be updated to reflect the REST API
changes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 16 Nov 2017 00:00:00 </pubDate></item><item><title>Support import/export snapshots in cinder</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/liberty/support-import-export-snapshots.html</link><description>

&lt;p&gt;Include the URL of your launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/support-import-export-snapshots"&gt;https://blueprints.launchpad.net/cinder/+spec/support-import-export-snapshots&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Provide a mean to import/export snapshots. Import/export snapshots function
could be an complement for the function of import/export volume.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Import/export snapshots function:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;It could provide the ability to import volumes’ snapshot from one cinder
to another cinder, and and import “non” OpenStack snapshots already on a
back-end device into OpenStack/cinder.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Export snapshots works the same way as export volumes.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Benefits:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;We could use the import snapshots as volume templates to create volumes from
snapshots.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Import snapshots function could provide an effective means to manage the
import volumes.&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;::&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;For those volume drivers which could not delete volume with snapshots,
we could not delete the import volume that has snapshots.
By using import snapshots function to import snapshots, we could first
delete the import snapshots, and then delete the import volumes.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;By supporting import/export snapshots, we need to do the following changes.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Add import/export snapshots API.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add import/export snapshots work flow.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;dl&gt;
&lt;dt&gt;::&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Import snapshots would check whether the snapshot’s parent volume
exists in cinder. If not, it would raise an exception.NotFound.
If the snapshot doesn’t exist in volume back end or the volume doesn’t
have related snapshot, it would raise
exception.ManageExistingInvalidReference.
Currently import snapshots function doesn’t support import those
snapshots(generally created by storage’s snap clone operation)
without parent volumes. We should use import volumes function to
import snapshots without parent volume.&lt;/p&gt;
&lt;p&gt;Export snapshots work almost the same as delete snapshot,
but it doesn’t delete the snapshot data.
For those volume drivers which could directly force delete volumes
with snapshots, export snapshots function has no side effect.
For those volume drivers which could not delete volumes with
snapshots, export snapshots function has a side effect that would
cause delete volumes failed.
For lvm driver and rbd driver, if unmange volume’s snapshots and
delete the volume, the delete operation fail and the volume’s status
is available because these two drivers would not continue to delete
volume if the volume has snapshots. Drivers raise an VolumeIsBusy
exception to volume manager, and volume manager reset the volume’s
status to available.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add manage_existing_snapshot, manage_existing_snapshot_get_size and
unmanage_snapshot interface in volume driver and implement these two
interface in LVM driver.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Add one API “manage_snapshot”&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The rest API look like this in v2:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;  &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s1"&gt;'snapshot'&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;
      &lt;span class="s1"&gt;'host'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'cinder-volume'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s1"&gt;'volume_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'volume-058660ab-6771-4f82-9627-687b179175d6'&lt;/span&gt;
      &lt;span class="s1"&gt;'ref'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'_snapshot-058660ab-6771-4f82-9627-687b179175d6'&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'host'&lt;/span&gt; &lt;span class="n"&gt;means&lt;/span&gt; &lt;span class="n"&gt;cinder&lt;/span&gt; &lt;span class="n"&gt;volume&lt;/span&gt; &lt;span class="n"&gt;host&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
  &lt;span class="n"&gt;No&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;

&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'volume_id'&lt;/span&gt; &lt;span class="n"&gt;means&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;snapshot&lt;/span&gt;&lt;span class="s1"&gt;'s volume id.&lt;/span&gt;
  &lt;span class="n"&gt;No&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;

&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'ref'&lt;/span&gt; &lt;span class="n"&gt;means&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;snapshot&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;
  &lt;span class="n"&gt;exist&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;storage&lt;/span&gt; &lt;span class="n"&gt;back&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
  &lt;span class="n"&gt;No&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The response body of it is like:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;  &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"snapshot"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"creating"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"created_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2014-08-25T11:14:31.469591"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"metadata"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt;
          &lt;span class="s2"&gt;"volume_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"fbd83a45-cce7-4333-b991-dafd2251edd4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"size"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"71543ced-a8af-45b6-a5c4-a46282108a90"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'status'&lt;/span&gt; &lt;span class="n"&gt;will&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;creating&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'description'&lt;/span&gt; &lt;span class="n"&gt;means&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;snapshot&lt;/span&gt; &lt;span class="n"&gt;display&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'created_at'&lt;/span&gt; &lt;span class="n"&gt;means&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;time.&lt;/span&gt;
&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;map&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'metadata'&lt;/span&gt; &lt;span class="n"&gt;means&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;snapshot&lt;/span&gt;&lt;span class="s1"&gt;'s metadata.&lt;/span&gt;
&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'volume_id'&lt;/span&gt; &lt;span class="n"&gt;means&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;snapshot&lt;/span&gt;&lt;span class="s1"&gt;'s volume id.&lt;/span&gt;
&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'id'&lt;/span&gt; &lt;span class="n"&gt;means&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;snapshot&lt;/span&gt;&lt;span class="s1"&gt;'s id.&lt;/span&gt;
&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'name'&lt;/span&gt; &lt;span class="n"&gt;means&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;alias&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;snapshot&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ol class="arabic simple" start="2"&gt;
&lt;li&gt;&lt;p&gt;Add one API “unmanage_snapshot”.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The rest API look like this in v2:&lt;/p&gt;
&lt;div class="highlight-console notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="go"&gt;POST /v2/{project_id}/os-snapshot-manage/{id}/action&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'os-unmanage'&lt;/span&gt;&lt;span class="p"&gt;:{}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The status code will be HTTP 202 when the request has succeeded.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Users can import snapshots that are already exist in volume back-end.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Export snapshots function has an side effect for those volume drivers
which could not delete volumes with snapshots. If using export snapshots
function, it would cause the subsequent delete volume operation fail.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;ling-yun&amp;lt;&lt;a class="reference external" href="mailto:zengyunling%40huawei.com"&gt;zengyunling&lt;span&gt;@&lt;/span&gt;huawei&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Implement code that mentioned in “Proposed change”.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement code in python-cinderclient.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add change API doc.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Both unit and Tempest tests need to be created to cover the code change that
mentioned in “Proposed change” and ensure that Cinder snapshot feature works
well while introducing import/export snapshots.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;The cinder API documentation will need to be updated to reflect the REST
API changes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the side effect of export snapshots function.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 16 Nov 2017 00:00:00 </pubDate></item><item><title>Support Modifying Volume Image Metadata</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/liberty/support-modify-volume-image-metadata.html</link><description>

&lt;p&gt;Include the URL of your launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/python-cinderclient/+spec/support-modify-volumn-image-metadata"&gt;https://blueprints.launchpad.net/python-cinderclient/+spec/support-modify-volumn-image-metadata&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This blueprint intends to support modifying volume image metadata, provide
Cinder API to allow a user to modify an image property or add new properties.&lt;/p&gt;
&lt;p&gt;Cinder should provide the similar mechanism for protected properties as what
Glance did, and it is the agreed approach according to the discussion in the
IRC and mailing list.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;When creating a bootable volume from an image, the image metadata (properties)
is copied into a volume property named volume_image_metadata.&lt;/p&gt;
&lt;p&gt;Cinder volume_image_metadata is the metadata on bootable volumes that Nova
looks at and uses for scheduling as well as for passing along to the individual
compute drivers.&lt;/p&gt;
&lt;p&gt;Cinder volume_image_metadata is used by nova for things like scheduling and
for setting device driver options. nova treat volume_image_metadata the same
way as the properties on images. This information may need to change after
the volume has been created from an image, besides, the additional properties
may also needed to make it available in the scheduler (detailed in the below
sections). So, There should be a way to support change/update image metadata.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;Here are some types of metadata properties that if set will affect runtime
characteristics of how Nova handles the booted volume. Many of them very
well could be a user deciding to basically build a new image using a volume,
but they want to twiddle with various handling properties as part of the
building process. Or they simply may have a bootable volume that they want
to modify some of these properties.&lt;/p&gt;
&lt;p&gt;Hypervisor selection: OpenStack Compute supports many hypervisors, although
most installations use only one hypervisor. For installations with multiple
supported hypervisors, you can schedule different hypervisors using the
ImagePropertiesFilter. This filters compute nodes that satisfy any
architecture, hypervisor type, or virtual machine mode properties specified
on the instance’s image properties (also volume_image_properties).&lt;/p&gt;
&lt;p&gt;Virtual CPU Topology: This provides the preferred socket/core/thread counts
for the virtual CPU instance exposed to guests. This enables the ability to
avoid hitting limitations on vCPU topologies that OS vendors place on their
products. See also:
&lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/nova-specs/tree/specs/juno/virt-driver-vcpu-topology.rst"&gt;http://git.openstack.org/cgit/openstack/nova-specs/tree/specs/juno/virt-driver-vcpu-topology.rst&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Watchdog Behavior: For the libvirt driver, you can enable and set the behavior
of a virtual hardware watchdog device for each flavor. Watchdog devices keep
an eye on the guest server, and carry out the configured action, if the server
hangs. The watchdog uses the i6300esb device (emulating a PCI Intel 6300ESB).
If hw_watchdog_action is not specified, the watchdog is disabled. Watchdog
behavior set using a specific image’s properties will override behavior
set using flavors.&lt;/p&gt;
&lt;p&gt;Shutdown Behavior: Numerous things coming:
&lt;a class="reference external" href="https://review.openstack.org/#/c/89650/12"&gt;https://review.openstack.org/#/c/89650/12&lt;/a&gt; What landed in Juno: By default,
guests will be given 60 seconds to perform a graceful shutdown. After that,
the VM is powered off. The os_shutdown_timeout property allows overriding
the amount of time (unit: seconds) to allow a guest OS to cleanly shut down
before power off. A value of 0 (zero) means the guest will be powered off
immediately with no opportunity for guest OS clean-up.&lt;/p&gt;
&lt;p&gt;Minimum Flavor Requirements: Minimum required CPU, Minimum RAM. These are
used by the Horizon UI to guide flavor selection. Somebody with a bootable
volume may install some new software on it and play around with setting
the minimum requirements before cloning to an image.&lt;/p&gt;
&lt;p&gt;The new Horizon UI is going to be providing more information about images,
flavors, volumes to admins and users in the UI leveraging the metadata and
looking up rich information about the metadata from the definition catalog
to display information to users and admins. This can include metadata about
software on the volume.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;This ONLY affects the individual volume, it’s has nothing to do with volume
types&lt;/p&gt;
&lt;p&gt;We are proposing the changes in Cinder to add update capability and provide
new Cinder API to allow a user to update an image properties.&lt;/p&gt;
&lt;p&gt;Since Glance has RBAC (role based access control) on some specific
properties, the RBAC config file is proposed to copied from Glance to Cinder,
and sync the protected properties code from Glance into Cinder (Glance
are happy to take code cleanups that make this easier; we can consider
OSLO or whatever in future but that’s a heavy weight process for another
day, copy and paste will do for now).&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;As to the strategy on protected properties, one proposal is providing new API
to query the properties protected or so per-property from Glance to Cinder,
but his approach seems will increase the overload of Glance.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;Since only image metadata is used by nova for VM scheduling or setting
device driver options, we proposed to add new REST APIs into Cinder for
the operations on image metadata of volume.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;update image metadata referenced with volume&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Common http response code(s)&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Modify Success: &lt;cite&gt;200 OK&lt;/cite&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Failure: &lt;cite&gt;400 Bad Request&lt;/cite&gt; with details.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Forbidden: &lt;cite&gt;403 Forbidden&lt;/cite&gt;&lt;/p&gt;
&lt;p&gt;e.g. no permission to update the specific metadata&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Not found: &lt;cite&gt;501 Not Implemented&lt;/cite&gt;&lt;/p&gt;
&lt;p&gt;e.g. The server doesn’t recognize the request method&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Not found: &lt;cite&gt;405 Not allowed&lt;/cite&gt;&lt;/p&gt;
&lt;p&gt;e.g. HEAD is not allowed on the resource&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Update volume image metadata&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Method type
PUT&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;API version&lt;/p&gt;
&lt;div class="highlight-console notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="go"&gt;PUT /v2/{project_id}/volumes/{volume_id}/image_metadata&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;JSON schema definition&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="s2"&gt;"image_metadata"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="s2"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"v2"&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;To unset a image metadata key value, specify only the key name.
To set a image metadata key value, specify the key and value pair.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;We intend to expose this via Horizon and are working on related blueprints.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Glance also need share its properties protection code to Cinder
and some code cleanups in Glance’s IMPL.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Provide Cinder API to allow a user to update an image property.
CLI-python API that triggers the update.&lt;/p&gt;
&lt;div class="highlight-console notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="gp"&gt;# &lt;/span&gt;Sets&lt;span class="w"&gt; &lt;/span&gt;or&lt;span class="w"&gt; &lt;/span&gt;deletes&lt;span class="w"&gt; &lt;/span&gt;volume&lt;span class="w"&gt; &lt;/span&gt;image&lt;span class="w"&gt; &lt;/span&gt;metadata
&lt;span class="go"&gt;cinder image-metadata  &amp;lt;volume-id&amp;gt; set &amp;lt;property-name = value&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None anticipated.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Two config file will be added into Cinder, that is property-protections-
policies.conf and property-protections-roles.conf
These file will be put in “/etc/cinder” by default and is configurable via
cinder.conf or point directly at the Glance files in devstack for example.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Deployer will be responsible for keeping the config files
in sync with Glance’s&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The config files will only take effect when they are present on the system.
So it is up to the deployer to ensure they are accurate. Otherwise, there
will be no impact to Cinder of the OpenStack environment by default.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Dave Chen (wei-d-chen)&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;None&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;Changes to Cinder:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Define property protections config files in Cinder
(Deployer need to keep the files in sync with Glance’s)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sync the properties protection code from Glance into Cinder
(The common protection code will be shared in Cinder)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Extend existing volume_image_metadatas(VolumeImageMetadataController)
controller extension to add update capability.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reuse update_volume_metadata method in volume API for updating image
metadata and differentiate user/image metadata by introducing a new
constant “meta_type”&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add update_volume_image_metadata method to volume API.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Check against property protections config files
(property-protections-policies.conf or property-protections-roles.conf)
if the property has update protection.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update DB API and driver to allow image metadata updates.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Changes to Cinder python client:&lt;/p&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;p&gt;Provide Cinder API to allow a user to update an image property.
CLI-python API that triggers the update.&lt;/p&gt;
&lt;p&gt;# Sets or deletes volume image metadata
cinder image-metadata  &amp;lt;volume-id&amp;gt; set &amp;lt;property-name = value&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;Same dependencies as Glance.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit tests will be added for all possible code with a goal of being able to
isolate functionality as much as possible.&lt;/p&gt;
&lt;p&gt;Tempest tests will be added wherever possible.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Since Glance has role based access control to properties. It could be the case
that we want to update a property in Cinder that is protected in Glance.
Eg: a license key is added in glance and it’s copied to cinder when the volume
is created. It should not be changed by an unauthorized user in Cinder because
this can be violating the billing policies for that image. Therefore, Property
Protections which is similar with Glance is proposed to be adopted into Cinder.&lt;/p&gt;
&lt;p&gt;We propose to define two samples config file in favor of Property Protections,
that is property-protections-roles.conf and property-protections-policies.conf.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;property-protections-policies.conf
This is a template file when using policy rule for property protections.&lt;/p&gt;
&lt;p&gt;Example: Limit all property interactions to admin only using policy
rule context_is_admin defined in policy.json.&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;[.*]&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;create = context_is_admin&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;read = context_is_admin&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;update = context_is_admin&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;delete = context_is_admin&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;property-protections-roles.conf&lt;/p&gt;
&lt;p&gt;This is a template file when property protections is based on user’s role.
Example: Allow both admins and users with the billing role to read and modify
properties prefixed with &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;x_billing_code_&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;[^x_billing_code_.*]&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;create = admin,billing&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;read = admin, billing&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;update = admin,billing&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;delete = admin,billing&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Please refer to here, &lt;a class="reference external" href="http://docs.openstack.org/developer/glance/property-protections.html"&gt;http://docs.openstack.org/developer/glance/property-protections.html&lt;/a&gt;
for the details explanation of the format.&lt;/p&gt;
&lt;p&gt;In case there is property which is protected strictly in Glance, license key
for example, deployer should aware the config files may turn out to be
inconsistent between Cinder and Glance, it’s up to deployer’s responsibility
to keep the config files in sync with Glance’s&lt;/p&gt;
&lt;p&gt;Other docs is also needed for new API extension and usage.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;This blueprint is actually a partial task of Graffiti project, many
parts of this concept have already been implemented for other pieces
of OpenStack, but that Cinder is outstanding (already completed for
images, flavors, host aggregates)&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://www.youtube.com/watch?v=Dhrthnq1bnw"&gt;Youtube summit recap of Graffiti Juno POC demo.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://openstack.10931.n7.nabble.com/cinder-glance-Update-volume-image-metadata-proposal-tt44371.html#a44523"&gt;Discussions in the mailing list.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://eavesdrop.openstack.org/meetings/glance/2014/glance.2014-06-26-20.03.log.html"&gt;Discussions in the IRC.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/112880/"&gt;The Horizon patch set which depends on this functionality&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/developer/glance/property-protections.html"&gt;Property Protections introduction in Glance&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 16 Nov 2017 00:00:00 </pubDate></item><item><title>Deletion of volumes with associated snapshots</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/liberty/volume-and-snap-delete.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/del-vols-with-snaps"&gt;https://blueprints.launchpad.net/cinder/+spec/del-vols-with-snaps&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Allow deletion of volumes with existing snapshots.  The proposal
is to integrate this with the existing volume delete path, using
an additional parameter to request deletion of snapshots as well
when deleting a volume.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;When deleting a volume, the delete operation may fail due to snapshots
existing for that volume.  The caller is forced to examine snapshot
information and make many calls to remove snapshots, even if they are not
interested in the snapshots at all, and just want the volume gone.&lt;/p&gt;
&lt;p&gt;Since snapshots are “children” of volumes in our model of the world, it
is reasonable to allow a volume and its snapshots to be removed in one
operation both for usability and performance reasons.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;More friendly and expected behavior for end-users.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Currently, if a volume has snapshots, the basic user experience is:&lt;/dt&gt;&lt;dd&gt;&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Try to delete volume&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Get back error message about it having snapshots&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Go delete X snapshots manually, become slightly frustrated&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete the volume&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Simpler for other software integrating with Cinder.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I received a request for this functionality because a project integrating
with Cinder would like to be able to just delete volumes without having to
handle logic for this.  I think that is a reasonable point of view (just as
it’s reasonable to figure that a user shouldn’t have to handle this).&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Faster and more efficient for some volume drivers.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are two losses of performance in requiring back and forth between
cinder-volume and the backend to delete a volume and snapshots:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ol class="upperalpha simple"&gt;
&lt;li&gt;&lt;p&gt;Extra time spent checking the status of X requests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Time spent merging snapshot data into another snapshot or volume
which is going to immediately be deleted.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;This means that we currently force a “delete it all” operation to take
more I/O and time than it really needs to.  (The degree of which depends
on the particular backend.)&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;A volume delete operation should handle this by default.&lt;/p&gt;
&lt;p&gt;Phase 1:&lt;/p&gt;
&lt;p&gt;This is the generic/”non-optimized” case which will work with any volume
driver.&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;When a volume delete request is received:&lt;/dt&gt;&lt;dd&gt;&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Look for snapshots belonging to the volume, set them all to “deleting”
status.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set the volume to “deleting” status.  (Done after #1 so as not to
diverge more than needed from our current model of state transitions.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Issue a snapshot delete for each snapshot.
(This loop happens in the volume manager.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If any snapshot delete operations fail, fail the operation and ensure
the volume returns to available.  Any snapshots that were successfully
deleted remain so.  Any snapshots which failed to be deleted are
marked as ‘error_deleting’.
It may make sense to continue deleting snapshots if an error occurs,
or it may be best to stop, depending on the type of error.  We
probably need some experience with implementing this to be sure of
the details for this.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Volume manager now moves all snapshots in ‘deleting’ state to deleted.
(volume_destroy/snapshot_destroy)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Phase 2:&lt;/p&gt;
&lt;p&gt;This case is for volume drivers that wish to handle mass volume/snapshot
deletion in an optimized fashion.&lt;/p&gt;
&lt;p&gt;When a volume delete request is received:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;Starting in the volume manager…&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Check for a driver capability of ‘volume_with_snapshots_delete’.
(Name TBD.)  This will be a new abc driver feature.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If the driver supports this, call driver.delete_volume_and_snapshots().
This will be passed the volume, and a list of all relevant
snapshots.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No exception thrown by the driver will indicate that everything
was successfully deleted.  The driver may return information indicating
that the volume itself is intact, but snapshot operations failed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Volume manager now moves all snapshots and the volume from ‘deleting’
to deleted.  (volume_destroy/snapshot_destroy)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If an exception occurred, set the volume and all snapshots to
‘error_deleting’.  We don’t have enough information to do anything
else safely.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The driver returns a list of dicts indicating the new statuses of
the volume and each snapshot.  This allows handling cases where
deletion of some things succeeded but the process did not complete.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Implement as the default behavior in volume delete.
- Deemed not a suitable change at this time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Introduce this as a separate volume_action instead of in the standard volume
delete path.
- Does not help usability without client modifications.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;No direct impact.&lt;/p&gt;
&lt;p&gt;In implementation, we need to ensure we don’t end up with strange things
like a volume in a “deleting” status that has snapshots in “available”
status.  Thus, failures to delete a single snapshot in this model may
cascade to marking the volume and all other associated snapshots as
errored.  (Only relevant for phase 2 above. This doesn’t happen if we
leave the snapshot and volume delete operations separate internally.)&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;Add a boolean parameter “delete_snapshots” to the delete volume
call, which defaults to false.&lt;/p&gt;
&lt;p&gt;A volume delete with snapshots which previously returned 400 will now
succeed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;p&gt;All snapshot/volume delete notifications will still be fired.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;New –delete-snapshots parameter for volume-delete in cinderclient.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Someone deleting a volume and all snapshots should be able to achieve
this more quickly, and with fewer REST calls.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Some storage backends will experience less load due to not having to
merge snapshots being deleted.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;dl&gt;
&lt;dt&gt;New, optional, driver interface:&lt;/dt&gt;&lt;dd&gt;&lt;dl&gt;
&lt;dt&gt;def delete_volume_and_snapshots(volume, snapshots[]):&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;This should take whatever driver-specific steps are needed
to delete the snapshots and associated volume data.&lt;/p&gt;
&lt;p&gt;The assumption can be made that any failed snapshot delete
results in a failed volume, so this does not have to account
for partial failures.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Note: None of this has to happen at a level above the volume manager since
the volume manager handles all related status updates.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;eharney (spec, some implementation)&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Other associates (implementation)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;Investigation:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Understand interaction w/ public/shared snapshots.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Implementation:&lt;/p&gt;
&lt;p&gt;Rough order should be:
* Add parsing for new parameter to volume delete API
* Implement volume manager logic to delete everything
* Create an abc class for the new driver interface
* Implement volume manager logic to talk to the new driver interface
* Implement an optimized case for the LVM driver&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Tempest tests will be added to cover this.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Need to document the new behavior of the volume delete call, as well
as related client examples, etc.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/133822/"&gt;https://review.openstack.org/#/c/133822/&lt;/a&gt;
This is not proposing the same thing as this spec!  It proposed to
orphan the snapshots and transform them into volumes, or similar.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/cinder/+bug/1276101"&gt;https://bugs.launchpad.net/cinder/+bug/1276101&lt;/a&gt;
Bug demonstrating one of the usability issues here&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Thu, 16 Nov 2017 00:00:00 </pubDate></item><item><title>Cinder Volume Active/Active support - General description</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/mitaka/cinder-volume-active-active-support.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/cinder-volume-active-active-support"&gt;https://blueprints.launchpad.net/cinder/+spec/cinder-volume-active-active-support&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Right now cinder-volume service can run only in Active/Passive HA fashion and
this spec proposes a possible path to support Active/Active configurations in
Cinder Volumes.&lt;/p&gt;
&lt;p&gt;This spec will only provide a general description of the problem enumerating
the different issues we have to resolve without actually going into too much
detail.  It’s more an eagle’s eye kind of view of the problem.&lt;/p&gt;
&lt;p&gt;Each specific issue will have its own spec that gives a detailed description of
the problem with proposed solution to the problem.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Right now cinder-volume service only accepts Active/Passive High Availability
configurations, and there are a number of things that need to change for it to
support Active/Active configurations.&lt;/p&gt;
&lt;section id="api-races"&gt;
&lt;h3&gt;API Races&lt;/h3&gt;
&lt;p&gt;On API nodes given current code we are open to races in the code that affect
resources on the database, and this will be exacerbated when working with
Active/Active configurations.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="local-manager-locks"&gt;
&lt;h3&gt;Local Manager Locks&lt;/h3&gt;
&lt;p&gt;We have multiple local locks in the manager code of the volume nodes to prevent
multiple green threads from accessing the same resource on specific operations.&lt;/p&gt;
&lt;p&gt;This locking is local to the nodes and doesn’t extend to other nodes, so we
need to solve mutual exclusion among volume nodes of the same cluster.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="job-distribution"&gt;
&lt;h3&gt;Job distribution&lt;/h3&gt;
&lt;p&gt;Cinder has no concept of clusters, only has the concept of hosts and each host
implements a specific backend/service.  A mechanism is needed to group hosts
from the same cluster under the same conceptual unit while retaining the
individual identities of the nodes belonging to the cluster for differentiation
in the clean up of crashed nodes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="cleanup"&gt;
&lt;h3&gt;Cleanup&lt;/h3&gt;
&lt;p&gt;Right now only one node can work on a specific backend, and therefore on the
resources that it contains, so the cleanup is done by the node itself on
startup. And if the node does not come up and the resources are left on a stale
state it is not a big deal.&lt;/p&gt;
&lt;p&gt;It is different with an Active/Active deployment since multiple nodes are
sharing the same storage back-end and a node can only do cleanup for the nodes
he was working on when he died/failed.&lt;/p&gt;
&lt;p&gt;It is also important to do proper cleanup even when a specific node does not
come back to life, since other nodes from the same cluster can still manage
those resources.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-corruption-prevention"&gt;
&lt;h3&gt;Data Corruption Prevention&lt;/h3&gt;
&lt;p&gt;Since multiple nodes will be accessing the same storage back-end we have to be
extra careful not to access resources that are accessed by other nodes.&lt;/p&gt;
&lt;p&gt;More relevant case is when we lose connection to the DB and we no longer can
send Service Heartbeats, since Scheduler’s cleanup process (explained in
Cleanup proposed changes) will come into place and we could have 2 different
nodes accessing the same resource, one because it’s still working on it and the
other because it is trying to do the cleanup.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="drivers-locks"&gt;
&lt;h3&gt;Drivers’ Locks&lt;/h3&gt;
&lt;p&gt;Some drivers require mutual exclusion for certain operations or when accessing
the same resources.&lt;/p&gt;
&lt;p&gt;This mutual exclusion is currently being done using local locks in the same way
the manager does and they need to be able to work when multiple nodes are
accessing the same storage back-end.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;Operators that have hard requirements, SLA or other reasons, to have their
cloud operational at all times or have higher throughput requirements will want
to have the possibility to configure their deployments with an Active/Active
configuration.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;section id="id1"&gt;
&lt;h3&gt;API Races&lt;/h3&gt;
&lt;p&gt;Races on the API nodes will be removed used compare-and-swap updates to the DB.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Specs: &lt;a class="reference external" href="https://review.openstack.org/207101/"&gt;https://review.openstack.org/207101/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="id2"&gt;
&lt;h3&gt;Job distribution&lt;/h3&gt;
&lt;p&gt;Job distribution will add the concept of cluster to cinder and send jobs using
a topic message queue using the cluster instead of the host like we are doing
now.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Specs: &lt;a class="reference external" href="https://review.openstack.org/232595"&gt;https://review.openstack.org/232595&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="id3"&gt;
&lt;h3&gt;Cleanup&lt;/h3&gt;
&lt;p&gt;Cleanup will keep track of resources that are have ongoing operations and will
have cleanup mechanisms on the Scheduler as well as the Volume nodes.&lt;/p&gt;
&lt;p&gt;Cleanup on the nodes will happen on initialization as it is doing now but we’ll
also have an automatic cleanup job on the scheduler for the cases where a node
with the same host name is not brought up.&lt;/p&gt;
&lt;p&gt;Automatic cleanup mechanism will be disabled by default and it will be possible
to trigger it manually.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Specs: &lt;a class="reference external" href="https://review.openstack.org/236977"&gt;https://review.openstack.org/236977&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="id4"&gt;
&lt;h3&gt;Data Corruption Prevention&lt;/h3&gt;
&lt;p&gt;Stop listening to new jobs from the Message Broker and halt all ongoing
operations so we are no longer accessing resources on the Storage Backend.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Specs: &lt;a class="reference external" href="https://review.openstack.org/237076"&gt;https://review.openstack.org/237076&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="manager-local-locks"&gt;
&lt;h3&gt;Manager Local Locks&lt;/h3&gt;
&lt;p&gt;Default solution will be using a DLM with TooZ as the abstraction layer:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Specs: &lt;a class="reference external" href="https://review.openstack.org/202615"&gt;https://review.openstack.org/202615&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;An alternative solution, that will be initially left as nice to have, will be
available for systems that don’t want to install a DLM solution and are using
drivers that don’t require distributed locking for Active-Active
configurations.  This solution replaces local file locks on c-vol’s manager
with a DB locking mechanism using &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;workers&lt;/span&gt;&lt;/code&gt; DB table (introduced by Cleanup
changes).&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Specs: &lt;a class="reference external" href="https://review.openstack.org/237602"&gt;https://review.openstack.org/237602&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="id5"&gt;
&lt;h3&gt;Drivers’ Locks&lt;/h3&gt;
&lt;p&gt;We will be using a DLM solution with TooZ as the abstraction layer:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Specs: &lt;a class="reference external" href="https://review.openstack.org/202615"&gt;https://review.openstack.org/202615&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;There are quite a number of alternatives to not only each of the issues we need
to fix, and they are discussed in the respective specs except for the Drivers’
lock alternative that creates a generic locking mechanism extending the locking
mechanism implemented to remove &lt;a class="reference internal" href="#manager-local-locks"&gt;Manager Local Locks&lt;/a&gt;.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Specs: &lt;a class="reference external" href="https://review.openstack.org/237604"&gt;https://review.openstack.org/237604&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;Discussed in the respective specs.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;Discussed in the respective specs.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Discussed in the respective specs.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;Discussed in the respective specs.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Discussed in the respective specs.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;API Races&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Job distribution&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cleanup&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Data Corruption Prevention&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Manager Local Locks&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Drivers’ Locks&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Discussed in the respective specs.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Discussed in the respective specs.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 16 Nov 2017 00:00:00 </pubDate></item><item><title>Use Tooz to replace local file locks</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/mitaka/ha-aa-tooz-locks.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/cinder-volume-active-active-support"&gt;https://blueprints.launchpad.net/cinder/+spec/cinder-volume-active-active-support&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Right now cinder-volume service can run only in Active/Passive HA fashion.
Some of the resons are:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Local file locks in manager that are protecting resources. For
example when creating a volume A from volume B a lock on B is created to
protect B from getting deleted during creation of A.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Local file locks in drivers like RemoteFS (and others). These locks are used
to block operations that cannot run concurrently (like taking a snapshot in
case of RemoteFS-based drivers).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This blueprint proposes a switch to use &lt;a class="reference external" href="http://docs.openstack.org/developer/tooz/"&gt;Tooz&lt;/a&gt; library for distributed locking.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently there can be only one active cinder-volume service per volume
backend. This means that to achieve high availability of it we need an external
service (like Pacemaker) that’s monitoring state of the c-vol and makes a new
instance active in case of a failure of a previous one. Also this makes c-vol
completely unscalable, because operator cannot just spin up additional services
if load is high and needs to rely on having just one instance.&lt;/p&gt;
&lt;p&gt;Local file locks that are used in c-vol’s manager and some drivers are
preventing that, because the lock won’t be shared between different c-vol
services running on different hosts. This may cause multiple issues, resulting
even in data loss.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;Operator would want to deploy multiple cinder-volume services. The motivation
may be to run multiple cinder-volume attached to a single storage backend to
increase throughput of requests and therefore performance. Another advantage is
increased resiliency to hardware failure when running multiple instances of the
service.&lt;/p&gt;
&lt;p&gt;Cloud user will get a better cloud.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;At Mitaka Design Summit there was a &lt;a class="reference external" href="https://etherpad.openstack.org/p/mitaka-cross-project-dlm"&gt;session about allowing projects to have a
hard requirement on DLM software&lt;/a&gt;. Main conclusions from the session are:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Projects can hard-depend on having a DLM.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/developer/tooz/"&gt;Tooz&lt;/a&gt; will be the abstraction layer.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That’s why proposed solution is to convert current locks that are local to use
&lt;a class="reference external" href="http://docs.openstack.org/developer/tooz/"&gt;Tooz&lt;/a&gt; abstraction layer.&lt;/p&gt;
&lt;p&gt;This would require unification of current approaches (as some locks are done
through cinder.utils.synchronized method and some are using
oslo.concurrency.lockutils directly). By default Tooz would be configured to
use file locks, so everything will work as today. If operator would want to run
multiple cinder-volume services he would need to configure Tooz backend service
and set it in cinder.conf. Currently most reliable Tooz backends are ZooKeeper
and Redis.&lt;/p&gt;
&lt;p&gt;Redis backend in Tooz requires sending periodical heartbeats, so cinder-volume
manager will start a new thread that will take care of that. This will be a
regular thread (non-eventlet) to be safe from situations when eventlet
greenthreads are blocked. It is intended to spawn this thread only when Tooz
needs it, so this won’t be done if FileDriver or ZooKeeper is used as backend.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;To solve the problem with locks in RemoteFS-based volume drivers we may simply
deprecate them and make operators switch to use lock-free drivers. This may be
very hard to achieve because according to &lt;a class="reference external" href="http://www.openstack.org/assets/survey/Public-User-Survey-Report.pdf"&gt;OpenStack Users Survey&lt;/a&gt; 19% of
Cinder deployments use these drivers. Also some non-RemoteFS-based drivers are
using local locks too.&lt;/p&gt;
&lt;p&gt;We could also replace current locks with some DB-based locking. This was
proposed by gegulieo in specs to remove local locks from the &lt;a class="reference external" href="https://review.openstack.org/#/c/237602/"&gt;manager&lt;/a&gt; and from
&lt;a class="reference external" href="https://review.openstack.org/#/c/237604/"&gt;drivers&lt;/a&gt;, but increased the complexity of the solution and potentially required
more testing than relying on a broadly used DLM software.&lt;/p&gt;
&lt;p&gt;In the future we will probably want to try to remove locks from volume manager
using other means (for example state-based locking). This will make it possible
to run c-vol in A/A manner without DLM (when running a volume driver that
doesn’t do locking).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Using an external service for locking will affect the performance. There are
some &lt;a class="reference external" href="https://github.com/Akrog/test-cinder-atomic-states"&gt;performance tests done by geguileo&lt;/a&gt;. Also having a heartbeat thread may
add a tiny performance overhead.&lt;/p&gt;
&lt;p&gt;These will be non-existent if user would stick to file locks and decide to run
c-vol exactly as it works today.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;Deployer will have a new options in a section [coordination]:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;cite&gt;backend_url=file://$state_path&lt;/cite&gt; - Tooz backend connection string.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;cite&gt;heartbeat=1.0&lt;/cite&gt; - number of seconds between heartbeats for distributed
coordination.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;cite&gt;initial_reconnect_backoff=0.1&lt;/cite&gt; - number of seconds to wait after failed
reconnection to Tooz backend.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;cite&gt;max_reconnect_backoff=60.0&lt;/cite&gt; - Maximum number of seconds between sequential
reconnection retries to Tooz backend.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Deployment tools maintainers will need to decide if they want to use new
possibility. If so - they will need to setup a Tooz backend (ZooKeeper, Redis,
or less recommended memcached) in their environment.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Developer would need to use locks in cinder-volume service only through Tooz
library abstraction layer and be aware that there can run multiple instances of
the service.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Michal Dulko (dulek)&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Szymon Wroblewski (bluex-pl)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Tooz locking implementation in Cinder (done).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Switch current locks to use Tooz implementation.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;We have some &lt;a class="reference external" href="https://review.openstack.org/#/c/185646/"&gt;work already done&lt;/a&gt;. We should split it for each driver and
work with driver maintainers to get patches merged.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add DevStack patches to set up a CI testing Cinder with Redis or ZooKeeper as
Tooz backend.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit tests for Tooz code will be added and a CI configured to test Cinder
with Redis or ZooKeeper as lock backend will be set up. Possibly we can do that
with multinode Tempest.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Documentation and Openstack HA Guide will need to be updated to include
instructions on how to configure Tooz and deploy cinder-volume in A/A.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://etherpad.openstack.org/p/cinder-active-active-vol-service-issues"&gt;https://etherpad.openstack.org/p/cinder-active-active-vol-service-issues&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://lists.openstack.org/pipermail/openstack-dev/2015-June/068151.html"&gt;http://lists.openstack.org/pipermail/openstack-dev/2015-June/068151.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/183537/"&gt;https://review.openstack.org/#/c/183537/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://www.youtube.com/watch?v=Fs9LC_sjnRM"&gt;https://www.youtube.com/watch?v=Fs9LC_sjnRM&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Thu, 16 Nov 2017 00:00:00 </pubDate></item><item><title>Differentiate thick and thin provisioning logic in scheduler</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/newton/differentiate-thick-thin-in-scheduler.html</link><description>

&lt;p&gt;Include the URL of your launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/differentiate-thick-thin-in-scheduler"&gt;https://blueprints.launchpad.net/cinder/+spec/differentiate-thick-thin-in-scheduler&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Currently in the capacity filter and weigher of the scheduler, we use the
logic to evaluate whether there is enough capacity to thin provision a volume
on a backend if the driver reports &lt;cite&gt;thin_provisioning_support&lt;/cite&gt; to be True.
However, a driver may be able to support both thin and non-thin provisioning.
The logic does not check whether the user wants the volume to be provisioned
as thin or not. This blueprint proposes to fix the problem by checking
&lt;cite&gt;thick_provisioning_support&lt;/cite&gt; in extra specs of the volume type.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;If a driver reports both &lt;cite&gt;thin_provisioning_support&lt;/cite&gt; to True and
&lt;cite&gt;thick_provisioning_support&lt;/cite&gt; to True for a pool that can support both thin and
thick luns, and the user wants to create a thick lun, the logic in the
scheduler would wrongly use the logic for thin provisioning to make decisions.
It would make decisions based on &lt;cite&gt;provisioned_capacity_gb&lt;/cite&gt; and
&lt;cite&gt;max_over_subscription_ratio&lt;/cite&gt;. This could potentially lead to over
provisioning.&lt;/p&gt;
&lt;p&gt;In this spec, we are trying to address this problem by checking whether the
new volume is thin or thick and then use logic accordingly to make decisions.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;Currently a driver can report both &lt;cite&gt;thin_provisioning_support&lt;/cite&gt; to True
and &lt;cite&gt;thick_provisioning_support&lt;/cite&gt; to True if it has a pool that can
support both thin and thick. However the logic in the scheduler
checks capacity for thin provisioning if the driver reports
&lt;cite&gt;thin_provisioning_support&lt;/cite&gt; to True even if the volume type specifies
the volume to be thick. The proposed spec wants to fix this problem.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;The spec proposes to make the following change in the logic in the capacity
filter and the capacity weigher.&lt;/p&gt;
&lt;p&gt;The volume type of the volume to be provisioned will be checked. If
&lt;cite&gt;provisioning_type&lt;/cite&gt; is set to &lt;cite&gt;thick&lt;/cite&gt; in the extra specs of
the volume type, it will use the thick provisioning logic to evaluate.
Note that this only affects the logic if the driver reports both
&lt;cite&gt;thin_provisioning_support&lt;/cite&gt; and &lt;cite&gt;thick_provisioning_support&lt;/cite&gt; to True.&lt;/p&gt;
&lt;p&gt;Otherwise, the logic remains the same as before.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;When the admin sets up volume types, he/she needs to set
the following in the extra specs for a thick volume type:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'thick_provisioning_support'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="ow"&gt;is&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'capabilities:thick_provisioning_support'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="ow"&gt;is&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Driver developer should be aware of this extra spec
and handle it accordingly in volume creation.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&amp;lt;xing-yang&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&amp;lt;launchpad-id or None&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Modify capacity filter to check &lt;cite&gt;thick_provisioning_support&lt;/cite&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify capacity weigher to check &lt;cite&gt;thick_provisioning_support&lt;/cite&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit tests will be added for this change.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Documentation needs to be changed to include this information.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;A patch is proposed in Manila to solve a similar problem:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/315266/"&gt;https://review.openstack.org/#/c/315266/&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Note that capabilities reporting for thin and thick provisioning
in Manila is different from that in Cinder. In Manila, a driver reports
&lt;cite&gt;thin_provisioning = [True, False]&lt;/cite&gt; if it supports both thin and thick;
In Cinder, a driver reports &lt;cite&gt;thin_provisioning_support = True&lt;/cite&gt; and
&lt;cite&gt;thick_provisioning_support = True&lt;/cite&gt; if it supports both thin and thick.
Therefore the proposal in this spec is different from the solution in
the Manila patch.&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 16 Nov 2017 00:00:00 </pubDate></item><item><title>Generic Volume Group</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/newton/generic-volume-group.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/generic-volume-group"&gt;https://blueprints.launchpad.net/cinder/+spec/generic-volume-group&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In this spec, we are designing a generic volume group. A generic volume group
can be used by a driver for various purposes and it can be extended easily
in the future to add new features.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;In Cinder, the only group construct available today is Consistency Group.
Consistency Group only supports consistent group snapshot today. When we
started to look at extending this support for group replication, lots of
issues came up. Consistency Group implies data consistency. For some drivers,
a group replication can ensure data consistency across the volumes in the
group, but for other drivers, group replication does not imply data
consistency.&lt;/p&gt;
&lt;p&gt;In this spec, we are designing a generic volume group. This group construct
can form a base for adding group replication support which will be discussed
in a different spec. The reason for adding a generic volume group is that it
can be used by drivers for different purposes. In this spec, we will be
providing basic functions including create, delete, and update a volume group.
Once the basic generic volume group is added, we can easily extend it to
support more new features without adding complex new APIs.&lt;/p&gt;
&lt;p&gt;In the following section, use cases are added to explain why a group
construct is needed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Group volumes together for a common purpose
A tenant may want to put volumes used in the same application together in
a group so that it is easier to manage them together.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Group replication
It was advised during previous spec reviews that generic volume groups
should be split out from group replication and covered in separate specs.
As suggested, group replication is discussed in details in a separate spec
in [1].&lt;/p&gt;
&lt;p&gt;Once a volume group construct is available, it provides the base for adding
support for group replication. Proposed replication functions in [1]
only apply to a group that has group_replication_enabled or
consistent_group_replication_enabled spec set to True. This means if you
have created a group that does not have group_replication_enabled or
consistent_group_replication_enabled spec set to True, you cannot
enable replication on that group.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Group snapshot
Details on group snapshot are discussed in another spec [2]. Once a volume
group construct is available, it provides the base for adding support for
group snapshot. We also need to change the existing Consistency Group
snapshot API to adopt the new group construct and make sure it does not
break rolling upgrades.&lt;/p&gt;
&lt;p&gt;There is a difference between group snapshot propsed in [2] versus
cgsnapshot which is existing today. Group snapshot supports two
capabilities, that is consistent_group_snapshot_enabled and
group_snapshot_enabled. A group snapshot with
consistent_group_snapshot_enabled spec set to True is equivalent to
cgsnapshot that is existing today. A group snapshot with
group_snapshot_enabled spec set to True is a group of snapshots that does
not guarantee consistency at the storage level. More details are provided
in [2].&lt;/p&gt;
&lt;p&gt;Existing work flow:
1. consisgroup-create creates a CG which is a group of volumes. Some
drivers call array APIs to put volumes in a group on the array so that it
can take a consistent snapshot later, but other drivers do not really have
an array API at this step so it is just that Cinder puts the volumes in a
group in the db. The next command cgsnapshot-create is the one that
guarantees point-in-time consistency.
2. cgsnapshot-create creates a CG snapshot which is consistent group
snapshot.&lt;/p&gt;
&lt;p&gt;New work flow:
1. group-create
2. group-snapshot-create
Whether the group snapshot is consistent or not depends on group type and
capabilities reported by the driver.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Create a group&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add an API that allows a tenant to create a volume group.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a Volume Driver API accordingly.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete a group&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add an API that allows a tenant to delete a volume group.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a Volume Driver API accordingly.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;List groups&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add an API to list volume groups.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Show a group&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add an API to show a volume group.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update a group&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add an API that adds existing volumes to a group and removes volumes
from the group after it is created.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a Volume Driver API accordingly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Note: This is the ability to add an existing volume to a group or remove
a volume from a group without deleting it. Some driver maintainers have
reported that update group cannot be supported by their drivers. For
example, HNAS iSCSI driver cannot support update group while implementing
the existing CG features because it means moving files between filesystems
and it does not have API to do that yet [3]. When implementing update
group, the driver maintainer should evaluate backend capabilities and also
check the group type specs to decide whether it can be supported or not.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Group type&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add a group type for a group just like a volume type for a volume.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;One group can support only one group type.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Group type specs&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add group type specs to describe a group’s characteristics just like
volume type extra specs to a volume type.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Group type specs will be reported as “capabilities” similar to extra
specs of a volume type.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Changes in the scheduler.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Make changes in the scheduler so that an appropriate backend will be
chosen to create a group.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DB Schema Changes&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;A new group_type table will be created and will contain the following:
* uuid of the group_type
* name
* description&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A new group_type_specs table will be created.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;uuid of the spec&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;key&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;value&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;uuid of group_type as a foreign key&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A new group table will be created and will contain the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;uuid of the group&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;uuid of a group_type as a foreign key&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;name&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;description&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A new volume_group_mapping table will be created and will contain the
following columns. This is needed because one volume could be in
multiple groups.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;uuid of the mapping entry&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;uuid of a volume&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;uuid of a group&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Note: Restricting a volume to only one group will limit what we
can do with the generic group contruct in the future.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A new group_volumetypes_mapping table will be created and will contain
3 columns:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;uuid of a group_volumetype entry&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;uuid of a group&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;uuid of a volume type&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A group quota mechanism will be added, similar to what we have for
CG.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Changes will be made to make sure new group contruct can support CG.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;In the Newton release, we should be able to create a CG using the
new API and preserve the existing behavior of the CG API.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the Ocata release, a group will be created in both the new and old
tables and we will read from the old table.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the “P” release, we will write to both new and old tables and read
from the new table.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the “Q” release, the old table will be removed. Both write and read
will be from the new table.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Driver needs to report group capabilities. Examples are as follows:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;consistent_group_replication_enabled&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;group_replication_enabled&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;consistent_group_snapshot_enabled&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;group_snapshot_enabled&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Group type spec needs to specify capabilities, i.e.,
{‘group_snapshot_enabled’: &amp;lt;is&amp;gt; True}&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Without these proposed changes, we can add replication support to the existing
consistency group but won’t have a generic volume group that can serve more
purposes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;DB Schema Changes&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A new group_type table will be created and will contain the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;uuid of the group_type&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;name&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;description&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A new group table will be created and will contain the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;uuid of the group&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;uuid of a group_type as a foreign key&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;name&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;description&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A new group_specs table will be created and will contain the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;uuid of the group_spec&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;key&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;value&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;uuid of the group_type as a foreign key&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A new group_volumetypes table will be created and will contain 3 columns:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;uuid of a group_volumetype entry&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;uuid of a group&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;uuid of a volume type&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The volumes table will have a new column:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;uuid of the group as a foreign key&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;New Group Type APIs&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Create Group Type&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;V3/&amp;lt;tenant id of admin&amp;gt;/group_types&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Method: POST&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;JSON schema definition for V3:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"group_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"my_group_type"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"My group type"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"group_type_specs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"key1"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"value1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"key2"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"value2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete Group Type&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;V3/&amp;lt;tenant id of admin&amp;gt;/group_types/&amp;lt;group_type_uuid&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Method: DELETE&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This API has no body.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;New Group Type Specs APIs&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Create Group Type Spec&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;V3/&amp;lt;tenant id of admin&amp;gt;/group_types/&amp;lt;group_type_uuid&amp;gt;/group_type_specs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Method: POST&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;JSON schema definition for V3:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"group_type_specs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"value"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete Group Type Spec&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;V3/&amp;lt;tenant id of admin&amp;gt;/group_types/&amp;lt;group_type_uuid&amp;gt;/group_type_specs/
&amp;lt;spec_uuid&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Method: DELETE&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This API has no body.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;List Group Type Specs&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;V3/&amp;lt;tenant id of admin&amp;gt;/group_types/&amp;lt;group_type_uuid&amp;gt;/group_type_specs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Method: GET&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This API has no body.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Show Group Type Spec&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;V3/&amp;lt;tenant id of admin&amp;gt;/group_types/&amp;lt;group_type_uuid&amp;gt;/group_type_specs/
&amp;lt;spec_uuid&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Method: GET&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This API has no body.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;New Group APIs&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Create a Group&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;V3/&amp;lt;tenant id&amp;gt;/groups&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Method: POST&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;JSON schema definition for V3:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"group"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"my_group"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"My group"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"group_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;group_type_uuid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"volume_types"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;volume_type1_uuid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;volume_type2_uuid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s2"&gt;"availability_zone"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"az1"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cinder scheduler will find a backend that supports the group type and
volume types. One group will be hosted on one backend, similar to CG.
An empty group will be created first with the above API. After the
group is created, a tenant can create a volume providing the group
uuid and volume type and the volume will be provisioned and placed
in the group and on the backend where the group resides.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The reason to include volume types when creating a group is to make sure
that the backend selected to place the group will be able to host a volume
of the specified volume type at a later time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;One group can support one group type and multiple volume types.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cinder API will be responsible for creating the group entry in the
database. Cinder driver may or may not need to do anything special when
the empty group is first created. This depends on the backend. Most
drivers just need to return success.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update Group&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;V3/&amp;lt;tenant id&amp;gt;/groups/&amp;lt;group uuid&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Method: PUT&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;JSON schema definition for V3:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"group"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"my_group"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"My group"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"add_volumes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;volume&lt;/span&gt; &lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;volume&lt;/span&gt; &lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="s2"&gt;"remove_volumes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;volume&lt;/span&gt; &lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;volume&lt;/span&gt; &lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This method can update name, description, as well as volumes in the group.
The list after “add_volumes” will contain UUIDs of volumes to be added to
the group and the list after “remove_volumes” will contain UUIDs of volumes
to be removed from the group. The API will validate the input name,
description, UUIDs in add_volumes and remove_volumes fields against the
information in Cinder db and send the request to the volume manager.
Manager will call driver to do the update on the backend. The API will
update Cinder db.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete Group&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;V3/&amp;lt;tenant id&amp;gt;/groups/&amp;lt;group uuid&amp;gt;/action&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Method: POST (We need to use “POST” not “DELETE” here because the request
body has a flag and therefore is not empty.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;JSON schema definition for V3:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"delete"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"delete-volumes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set delete-volumes flag to True to delete a group with volumes in it.
This will delete the group and all the volumes. Deleting an empty
group does not need the flag to be True.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;List Groups&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;V3/&amp;lt;tenant id&amp;gt;/groups&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This API lists summary information for all groups.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Method: GET&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This API has no body.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;List Groups (detailed)&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;V3/&amp;lt;tenant id&amp;gt;/groups/detail&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This API lists detailed information for all groups.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Method: GET&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This API has no body.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Show Group&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;V3/&amp;lt;tenant id&amp;gt;/groups/&amp;lt;group uuid&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Method: GET&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This API has no body.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Changes to Create Volume API&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;A new field “group_id” (uuid of the group)  will be added to the
request body.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cinder Volume Driver API&lt;/p&gt;
&lt;p&gt;The following new volume driver APIs will be added:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;def create_group(self, context, group)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;def update_group(self, context, group, add_volumes=None,
remove_volumes=None)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;def delete_group(self, context, group, volumes)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;Notifications will be added for create, delete, and update groups.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;python-cinderclient needs to be changed to support the new APIs.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Create Group Type&lt;/p&gt;
&lt;p&gt;cinder group-type-create –description &amp;lt;description&amp;gt; &amp;lt;name&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete Group Type&lt;/p&gt;
&lt;p&gt;cinder group-type-delete &amp;lt;group type uuid&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Show Group Type&lt;/p&gt;
&lt;p&gt;cinder group-type-show &amp;lt;group type uuid&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;List Group Types&lt;/p&gt;
&lt;p&gt;cinder group-type-list&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set/unset Group Type Spec&lt;/p&gt;
&lt;p&gt;cinder group-type-key &amp;lt;group type name or uuid&amp;gt; &amp;lt;action&amp;gt; &amp;lt;key-value&amp;gt;
Valid action is “set” or “unset”.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;List Group Type Specs&lt;/p&gt;
&lt;p&gt;cinder group-type-specs-list&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create Group&lt;/p&gt;
&lt;p&gt;cinder group-create –name &amp;lt;name&amp;gt; –description &amp;lt;description&amp;gt;
–availability-zone &amp;lt;availability-zone&amp;gt;
–volume-types &amp;lt;volume type uuid&amp;gt; [&amp;lt;volume type uuid&amp;gt;…] group_type&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update Group&lt;/p&gt;
&lt;p&gt;cinder group-update –name &amp;lt;new name&amp;gt;
–description &amp;lt;new description&amp;gt; –add-volumes
&amp;lt;volume uuid&amp;gt; [&amp;lt;volume uuid&amp;gt; …] –remove-volumes
&amp;lt;volume uuid&amp;gt; [&amp;lt;volume uuid&amp;gt; …] &amp;lt;group uuid or name&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete Group&lt;/p&gt;
&lt;p&gt;cinder group-delete –delete-volumes &amp;lt;group uuid&amp;gt; [&amp;lt;group uuid&amp;gt; …]
The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;delete-volumes&lt;/span&gt;&lt;/code&gt; flag is needed when a group is not empty.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;List Group&lt;/p&gt;
&lt;p&gt;cinder group-list&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Show Group&lt;/p&gt;
&lt;p&gt;cinder group-show &amp;lt;group uuid&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Driver developers can implement the new driver APIs.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;xing-yang&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Other contributors:&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;New Group Type APIs:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create Group Type&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete Group Type&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;New Group Type Spec APIs:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create Group Type Spec&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete Group Type Spec&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;List Group Type Specs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Show Group Type Spec&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;New Group APIs:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create Group&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update Group&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete Group&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;List Groups&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Show Group&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;New Volume Driver API changes:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create Group&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update Group&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete Group&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DB schema changes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement group methods in the LVM driver.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make sure both new and old group APIs work.
See details in spec [2] on how to achieve this.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;New unit tests will be added to test the changed code.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Documentation changes are needed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;[1] The replication group spec:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/229722/"&gt;https://review.openstack.org/#/c/229722/&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;[2] The group snapshot spec:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/331397/"&gt;https://review.openstack.org/#/c/331397/&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;[3] HNAS iSCSI driver Consistency Group support code review:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/327043/4/cinder/volume/drivers/"&gt;https://review.openstack.org/#/c/327043/4/cinder/volume/drivers/&lt;/a&gt;
&lt;a class="reference external" href="mailto:hitachi/hnas_iscsi.py%40939"&gt;hitachi/hnas_iscsi&lt;span&gt;.&lt;/span&gt;py&lt;span&gt;@&lt;/span&gt;939&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
</description><pubDate>Thu, 16 Nov 2017 00:00:00 </pubDate></item><item><title>Group Snapshots</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/newton/group-snapshots.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/generic-volume-group"&gt;https://blueprints.launchpad.net/cinder/+spec/generic-volume-group&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This spec is dependent on the generic volume group spec [1]. The purpose of
proposing this spec is to migrate the existing consistency groups support
to use the generic volume group constructs and also provide a common API
for group snapshots that works for all storage backends.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;In Juno, we introduced consistency groups (CG) support into cinder. The
existing CG support in cinder only supports CG snapshot.&lt;/p&gt;
&lt;p&gt;The existing CG support includes the following tables only used for CG.
* consistencygroups
* cgsnapshot&lt;/p&gt;
&lt;p&gt;The existing CG support provides the following APIs.
* Create CG
* Delete CG
* Update CG
* Create CG from source (CG or CG snapshot)
* List CG
* Show CG
* Create CG snapshot
* Create CG snapshot
* List CG snapshot
* Show CG snapshot&lt;/p&gt;
&lt;p&gt;The generic volume group spec introduces a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;groups&lt;/span&gt;&lt;/code&gt; table which is
corresponding to the existing &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;consistencygroups&lt;/span&gt;&lt;/code&gt; table.&lt;/p&gt;
&lt;p&gt;The generic volume group spec introduces the following APIs that are
corresponding to some existing CG APIs.
* Create group
* Delete group
* Update group
* List group
* Show group&lt;/p&gt;
&lt;p&gt;The missing pieces to support the existing CG feature using the generic
volume contructs are as follows.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;A group_snapshots table (for cgsnapshots table)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create group snapshot API (for create cgsnapshot)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete group snapshot API (for delete cgsnapshot)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;List group snapshots API (for list cgsnapshots)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Show group snapshot API (for show cgsnapshot)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create group from source group or source group snapshot API (for
create CG from cgsnapshot or source CG)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Therefore we are proposing to add the missing pieces in this spec and
also provide a way to migrate data from the CG and CGSnapshot tables to
group and group snapshots tables while maintaining the support for
rolling upgrade.&lt;/p&gt;
&lt;p&gt;The existing CG and CG snapshot APIs can only be supported by a subset
of storage backends in cinder. In this spec, we propose to provide group
snapshot APIs that can be supported by all storage backends.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;Group snapshot supports two capabilities, that is
consistent_group_snapshot_enabled and group_snapshot_enabled. A group snapshot
with consistent_group_snapshot_enabled spec set to True is equivalent to
cgsnapshot that is existing today in Cinder and it can guarantee point-in-time
consistency at the storage level. A group snapshot with group_snapshot_enabled
spec set to True is a group of snapshots that does not guarantee consistency
at the storage level.&lt;/p&gt;
&lt;p&gt;Data protection products built on top of cinder, nova, neutron, glance, etc.
want to protect all OpenStack resources. They can use the group snapshot API
to take snapshots in their solution. Without the group snapshot API, the
data protection products will have to take snapshot for each volume
inidividually.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Create a group snapshot&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add an API that allows a tenant to create a group snapshot.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a Volume Driver API accordingly.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete a group snapshot&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add an API that allows a tenant to delete a group snapshot.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a Volume Driver API accordingly.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;List group snapshots&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add an API to list group snapshots.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Show a group snapshot&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add an API to show a group snapshot.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a group from a source group or a source group snapshot&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add an API that creats a group from a source group or a
source group snapshot.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a Volume Driver API accordingly.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DB Schema Changes&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;A new group_snapshots table will be created and will contain the following:
* uuid of the group_snapshot
* name
* description
* uuid of the original group as a foreign key&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A group_snapshot_id column will be added to the snapshots table.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Two new columns group_snapshot_id and source_group_id will be
added to the groups table.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Changes will be made to make sure generic volume group and group snapshots
can support CG and CG snapshots.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Create a default group type and use it only for the existing CGs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Write a migration script to copy data from consistencygroups to
groups and from cgsnapshots to group_snapshots tables. All existing
consistencygroups moved to groups will use the default group type.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the future (i.e., Ocata) we can provide a cinder manage command
to allow admin to change the group type.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In Newton, to support rolling upgrade, all existing CG and CG snapshot
APIs will continue to work, and they will write to both existing and new
tables. Read will be from the existing tables. So list and show will
retrieve data from the existing tables.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the Ocata release, using old CG APIs will still work and data will be
written in both the new and old tables. Read will be from the new tables.
So list and show will retrieve data from the new tables.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the “P” release, using old CG APIs will still work and both write and
read will be using the new tables. The old tables will be removed in the
“P” release.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Using new APIs will write to and read from the new tables only. This means
list groups will list all groups in the new tables including those created
using CG APIs. The same applies to group snapshots. By checking the group
type of a group, you can tell what kind of group it is.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When creating a group using the new API, if the following is in the group
type spec, the manager will call create_group in the driver first and will
call create_consistencygroup in the driver if create_group is not
implemented.&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'consistent_group_snapshot_enabled'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="ow"&gt;is&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Same applies to delete_group, update_group, create_group_snapshot,
delete_group_snapshot, and create_group_from_src. This way the new APIs
will work with existing driver implementation of CG functions.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;During the “P” release, we can make a decision on whether to keep the
CG and CG snapshots APIs or deprecate them in the “Q” release.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;We can continue to use the existing CG and CG snapshot APIs.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;DB Schema Changes&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A new group_snapshots table will be created and will contain the following.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;uuid of the group_snapshot&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;name&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;description&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;uuid of the original group as a foreign key&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A group_snapshot_id column will be added to the snapshots table.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Two new columns group_snapshot_id and source_group_id will be
added to the groups table.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;New Group Snapshot APIs&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Create a Group Snapshot&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;V3/&amp;lt;tenant id&amp;gt;/group_snapshots&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Method: POST&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;JSON schema definition for V3:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"group_snapshot"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"my_group_snapshot"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"My group snapshot"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;group_uuid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"user_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete Group Snapshot&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;V3/&amp;lt;tenant id&amp;gt;/group_snapshots/&amp;lt;group snapshot uuid&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Method: DELETE&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This API has no body&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;List Group Snapshots&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;V3/&amp;lt;tenant id&amp;gt;/group_snapshots&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This API lists summary information for all group snapshots.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Method: GET&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This API has no body.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;List Group Snapshots (detailed)&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;V3/&amp;lt;tenant id&amp;gt;/group_snapshots/detail&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This API lists detailed information for all group snapshots.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Method: GET&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This API has no body.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Show Group Snapshot&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;V3/&amp;lt;tenant id&amp;gt;/group_snapshots/&amp;lt;group snapshot uuid&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Method: GET&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This API has no body.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create Group from Source&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;V3/&amp;lt;tenant id&amp;gt;/groups/action&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Method: POST&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;JSON schema definition for V3:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"create-from-src"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"my_group"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"My group"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"group_snapshot_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;group_snapshot_uuid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"source_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;source_group_uuid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"user_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Changes to Create Snapshot API&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;A new field “group_snapshot_id” (uuid of the group snapshot)  will be
added to the request body.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cinder Volume Driver API&lt;/p&gt;
&lt;p&gt;The following new volume driver APIs will be added:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;def create_group_snapshot(self, context, group_snapshot, snapshots)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;def delete_group_snapshot(self, context, group_snapshot, snapshots)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;def create_group_from_src(self, context, group, volumes,&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;group_snapshot=None, snapshots=None,
source_group=None, source_vols=None)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;Notifications will be added for create and delete group snapshots and
create group from source.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;python-cinderclient needs to be changed to support the new APIs.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Create Group Snapshot&lt;/p&gt;
&lt;p&gt;cinder group-snapshot-create –name &amp;lt;name&amp;gt; –description &amp;lt;description&amp;gt;
&amp;lt;group uuid&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete Group Snapshot&lt;/p&gt;
&lt;p&gt;cinder group-snapshot-delete &amp;lt;group snapshot uuid&amp;gt;
[&amp;lt;group snapshot uuid&amp;gt; …]&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;List Group Snapshot&lt;/p&gt;
&lt;p&gt;cinder group-snapshot-list&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Show Group Snapshot&lt;/p&gt;
&lt;p&gt;cinder group-snapshot-show &amp;lt;group snapshot uuid&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create Group from Source
cinder group-create-from-src –group-snapshot &amp;lt;group snapshot uuid&amp;gt;
–source-group &amp;lt;source group uuid&amp;gt; –name &amp;lt;name&amp;gt;
–description &amp;lt;description&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Driver developers can implement the new driver APIs.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;xing-yang&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Other contributors:&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;New Group Snapshot APIs&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create Group Snapshot&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete Group Snapshot&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;List Group Snapshots&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Show Group Snapshot&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;New Clone Group API&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create Group from Source Snapshot or Source Group&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;New Volume Driver API changes&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create Group Snapshot&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete Group Snapshot&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create Group from Source&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;New DB schema changes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement methods in the LVM driver.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make sure both new and old APIs work. See details in the
Proposed Change section.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;New unit tests will be added to test the changed code.
Tempest tests should be added as well.
Functional tests could be added if needed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Documentation changes are needed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;[1] The generic volume group spec:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/303893/"&gt;https://review.openstack.org/#/c/303893/&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 16 Nov 2017 00:00:00 </pubDate></item><item><title>Cinder Volume Active/Active support - Manager Local Locks</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/newton/ha-aa-manager_locks.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/cinder-volume-active-active-support"&gt;https://blueprints.launchpad.net/cinder/+spec/cinder-volume-active-active-support&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Right now cinder-volume service can run only in Active/Passive HA fashion.&lt;/p&gt;
&lt;p&gt;One of the reasons for this is that we have multiple &lt;strong&gt;local locks&lt;/strong&gt; in the
Volume nodes for mutual exclusion of specific operations on the same resource.
These locks need to be shared between nodes of the same cluster, removed or
replaced with DB operations.&lt;/p&gt;
&lt;p&gt;This spec proposes a different mechanism to replace these local locks.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;We have locks in Volume nodes to prevent things like deleting a volume that is
being used to create another volume, or attaching a volume that is already
being attached.&lt;/p&gt;
&lt;p&gt;Unfortunately these locks are local to the nodes, which works if we only
support Active/Passive configurations, but doesn’t on Active/Active
configurations when we have more than one node, since locks will not guarantee
mutual exclusion of operations on other nodes.&lt;/p&gt;
&lt;p&gt;We have different locks for different purposes but we will be using the same
mechanism to allow them to handle an Active/Active clusters.&lt;/p&gt;
&lt;p&gt;List of locks are:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;${VOL_UUID}&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;${VOL_UUID}-delete_volume&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;${VOL_UUID}-detach_volume&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;${SNAPSHOT_UUID}-delete_snapshot&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We are adding an abstraction layer to our locking methods in Cinder -for the
manager and drivers- using &lt;a class="reference external" href="http://docs.openstack.org/developer/tooz/"&gt;Tooz&lt;/a&gt; as explained in &lt;a class="reference external" href="https://review.openstack.org/202615/"&gt;Tooz locks for A/A&lt;/a&gt; that
will use local file locks by default and will use a DLM for Active-Active
configurations.&lt;/p&gt;
&lt;p&gt;But there are cases where drivers don’t need distributed locks to work, they
may just need local locks and we would be forcing them to install a DLM just
for these few locks in the manager, which can be considered a bit extreme.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;Operators that have hard requirements, SLA or other reasons, to have their
cloud operational at all times or have higher throughput requirements will want
to have the possibility to configure their deployments with an Active/Active
configuration and have the same behavior they currently have.  But they don’t
want to have to install a DLM when they are using drivers that don’t require
distributed locks to operate in Active-Active mode just for 4 locks.&lt;/p&gt;
&lt;p&gt;Also in the context of the effort to make Cinder capable of working as an SDS
outside of OpenStack, where we no longer can make a hard requirement the
presence of a DLM as we can within OpenStack, it makes even more sense for
Cinder to be able to work without a DLM present for Active-Active
configurations if the storage backend drivers don’t require distributed locking
in Active-Active environments.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;This spec suggests modifying behavior introduced by &lt;a class="reference external" href="https://review.openstack.org/202615/"&gt;Tooz locks for A/A&lt;/a&gt;
for the case where the drivers don’t need distributed locks.  So we would use
local file locks in the drivers (if they use any) and for the locks in the
manager we would use a locking mechanism based on the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;workers&lt;/span&gt;&lt;/code&gt; table that
was introduced by the &lt;a class="reference external" href="https://review.openstack.org/236977"&gt;HA A/A Cleanup specs&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This new locking mechanism would be an hybrid between local and distributed
locks.&lt;/p&gt;
&lt;p&gt;By using a locking mechanism similar to the one that local file locks provide
we’ll be able to mimic the same behavior we have:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Assure mutual exclusion between different nodes of the same cluster and in
the node itself.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Request queuing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Lock release on node crash.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Require no additional software in the system.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Require no operator specific configuration.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To assure the mutual exclusion using the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;workers&lt;/span&gt;&lt;/code&gt; table we will need to add
a new field called &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;lock_name&lt;/span&gt;&lt;/code&gt; that will store the current operation (method
name in most cases since table already has the resource type and UUID) that is
being performed on the Volume’s manager and it will be used for locking.&lt;/p&gt;
&lt;p&gt;New locking mechanism will use added &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;lock_name&lt;/span&gt;&lt;/code&gt; field to check if
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;workers&lt;/span&gt;&lt;/code&gt; table already has an entry for that &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;lock_name&lt;/span&gt;&lt;/code&gt; on the specific
resource and cluster of the node, in which case the lock is &lt;em&gt;acquired&lt;/em&gt; and we
have to wait and retry later until the lock has been &lt;em&gt;released&lt;/em&gt; -row has been
deleted- and we can insert the row ourselves to &lt;em&gt;acquire&lt;/em&gt; the lock. This means
that in the case of attaching a volume we will only proceed with the attach if
there is no DB entry for our cluster for the volume ID with operation
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volume_attach&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To assure mutual exclusion, this lock checking and acquisition needs to be
atomic, so we’ll be using a conditional insert of the “lock” in the same way we
are doing conditional updates (compare-and-swap) to remove &lt;a class="reference external" href="https://review.openstack.org/207101/"&gt;API races&lt;/a&gt;.
Insert query will be conditioned to the absence of a row with some specific
restrictions, in this case conditions will be the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;lock_name&lt;/span&gt;&lt;/code&gt;, the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cluster&lt;/span&gt;&lt;/code&gt; and the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;type&lt;/span&gt;&lt;/code&gt;.  If we couldn’t insert the row acquiring the lock
failed and we have to wait, if we inserted the row successfully we have
acquired the lock and can proceed with the operation.&lt;/p&gt;
&lt;p&gt;This process of trying to acquire, fail, wait and retry, is the exact same
mechanism we have today with the local file locks.  &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;synchronize&lt;/span&gt;&lt;/code&gt; method when
using external synchronization will try to acquire the file lock with a
relatively small timeout and if it fails it will try again until lock is
acquired.&lt;/p&gt;
&lt;p&gt;So by mimicking the same behavior as the file locks we are preserving the
queuing of operations we currently have, and not altering our API’s behavior
and “implicit API contract” that some external scripts may be relying on.&lt;/p&gt;
&lt;p&gt;Since we will be using the DB for the locking operators will not need to add
any software to their systems or carry out specific system configurations.&lt;/p&gt;
&lt;p&gt;It is important to notice that timeouts for these new locks will be handled by
the cleanup process itself, as rows are removed from the DB when heartbeats are
no longer being received, thus releasing the locks and preventing a resource
from being stuck.&lt;/p&gt;
&lt;p&gt;On a closer look at these 4 locks mentioned before we can classify them in 2
categories:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Locks for the resource of the operation.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;${VOL_UUID}-detach_volume&lt;/em&gt;  -  Used in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;detach_volume&lt;/span&gt;&lt;/code&gt; to prevent
multiple simultaneous detaches&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;${VOL_UUID}&lt;/em&gt;  -  Used in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;attach_volume&lt;/span&gt;&lt;/code&gt; to prevent multiple
simultaneous attaches&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Locks that prevent deletion of the source of a volume creation (they are
created by &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;create_volume&lt;/span&gt;&lt;/code&gt; method):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;${VOL_UUID}-delete_volume&lt;/em&gt;  -  Used in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;delete_volume&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;${SNAPSHOT_UUID}-delete_snapshot&lt;/em&gt;  -  Used in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;delete_snapshot&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For locks on the resource of the operation -attach and detach- the row in the
DB is already been inserted by the cleanup method, so we’ll reuse that same row
and condition the writing of the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;lock_name&lt;/span&gt;&lt;/code&gt; field to the lock being
available.&lt;/p&gt;
&lt;p&gt;As for locks preventing deletion we will need to add the row ourselves since
cleanup was not adding a row in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;workers&lt;/span&gt;&lt;/code&gt; table for those resources as
they didn’t require any cleanup.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;We could use a DLM, which is a stand-in replacement for local locks, but there
have been operator that have expressed their concern on adding this burden -to
their systems and duties- because they are using drivers that don’t require
locks for Active-Active and would prefer to avoid adding a DLM to their
systems.&lt;/p&gt;
&lt;p&gt;Instead of using the new locking mechanism for locks that prevent deletion of
resources we could add a filter to the conditional update -the one being used
to prevent &lt;a class="reference external" href="https://review.openstack.org/207101/"&gt;API Races&lt;/a&gt;- that will prevent us from deleting a volume or a
snapshot that is being used as the source for a volume adding also the
appropriate response error when we try to delete such a volume/snapshot.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;Adds a new string field called &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;lock_name&lt;/span&gt;&lt;/code&gt; to the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;workers&lt;/span&gt;&lt;/code&gt; table.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Small, but necessary, performance impact from changing local file locks to DB
calls.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Gorka Eguileor (geguileo)&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Anyone is welcome to help&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;lock_name&lt;/span&gt;&lt;/code&gt; field to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;workers&lt;/span&gt;&lt;/code&gt; table.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify Cinder’s new locking methods/decorators to handle hybrid behavior.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Cleanup for HA A/A: &lt;a class="reference external" href="https://review.openstack.org/236977"&gt;https://review.openstack.org/236977&lt;/a&gt;&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;We need the new &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;workers&lt;/span&gt;&lt;/code&gt; table and the cleanup mechanism.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;Removing API Races: &lt;a class="reference external" href="https://review.openstack.org/207101/"&gt;https://review.openstack.org/207101/&lt;/a&gt;&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;We need compare-and-swap mechanism on volume and snapshot deletion to be in
place so we can add required filters.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unittests for new locking mechanism.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;This needs to be properly documented, as this locking mechanism will &lt;em&gt;not&lt;/em&gt; be
appropriate for all drivers.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;General Description for HA A/A: &lt;a class="reference external" href="https://review.openstack.org/#/c/232599/"&gt;https://review.openstack.org/#/c/232599/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Cleanup for HA A/A: &lt;a class="reference external" href="https://review.openstack.org/236977"&gt;https://review.openstack.org/236977&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Removal of API Races: &lt;a class="reference external" href="https://review.openstack.org/207101/"&gt;https://review.openstack.org/207101/&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 16 Nov 2017 00:00:00 </pubDate></item><item><title>Reset generic volume group and group snapshot statuses</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/ocata/support-reset-generic-group-and-group-snapshot-status.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/reset-cg-and-cgs-status"&gt;https://blueprints.launchpad.net/cinder/+spec/reset-cg-and-cgs-status&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently we support the administrator to reset the status of volume,
snapshot, backup and so on, but both of the generic volume group and group
snapshot could also run into error status, the administrator could only
modify the status in database. This is inconvenient for administrator.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;The primary use case is for the manual recovery of some sort of issue with
generic volume group’s status(snapshot’s inclusive). This is helpful for
recovering the two resources from a bad status due to real issues with the
system or crashed from bugs.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Take the generic volume group for example, The change can add a new admin
generic group action on the resource. The logic could be the same as
volume’s action &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;reset_status&lt;/span&gt;&lt;/code&gt; which already exists, for example,
to reset the status of generic group to error, it would be:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v3&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tenant_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;groups&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;group_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'reset_status'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="s1"&gt;'status'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'error'&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The ‘status’ should be one of the generic group status,the api will validate
the input status and then update the status in database.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;We could just leave it as a manual db operation, but that leaves it up to an
admin to go manually update the db to achieve the same goal.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;The API microversion will have to be bumped for the new APIs below.&lt;/p&gt;
&lt;p&gt;New GroupAdminController:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v3&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tenant_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;groups&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;group_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;And new admin action for it:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;reset_status&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;New GroupSnapshotAdminController:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v3&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tenant_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;group_snapshots&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;group_snapshot_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;And new admin action for it:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;reset_status&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;They both required the identical request body, and ‘status’ should be
passed in as a string:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'reset_status'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="s1"&gt;'status'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'error'&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;For the return codes if the status is not valid we will return a 400 Bad
Request, if the resource is not found it will be a 404 Not Found, and will
otherwise return a 202.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="cinder-client-impact"&gt;
&lt;h3&gt;Cinder-client impact&lt;/h3&gt;
&lt;p&gt;The cinder-client will add commands to expose these new APIs(use ‘state’
instead of ‘status’ to keep consistency with existed reset commands):&lt;/p&gt;
&lt;p&gt;New command to reset generic group status:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;group-reset-state &amp;lt;group&amp;gt; –state &amp;lt;state&amp;gt;&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;the ‘group’ should be name or ID of the specified group.&lt;/p&gt;
&lt;p&gt;New command to reset group snapshot status:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;group-snapshot-reset-state &amp;lt;group-snapshot&amp;gt; –state &amp;lt;state&amp;gt;&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;the ‘group-snapshot’ should be name or ID of the specified group snapshot.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;We will add &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;reset_group_status&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;reset_group_snapshot_status&lt;/span&gt;&lt;/code&gt;
notifications that will behave the same way as the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;reset_status&lt;/span&gt;&lt;/code&gt;
notifications. There will be a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;start&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;end&lt;/span&gt;&lt;/code&gt; notification.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;The new API will be exposed to users via the python-cinderclient.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;While it is doing a db operation it should be a very low impact.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;tommylikehu(&lt;a class="reference external" href="mailto:TommyLikeHu%40gmail.com"&gt;TommyLikeHu&lt;span&gt;@&lt;/span&gt;gmail&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Implement new admin action and tests in Cinder.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add support in python-cinderclient.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit tests in Cinder.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tempest tests in Cinder.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Functional tests in Cinder.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unit tests in python-cinderclient.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;New admin docs to explain how to use the API.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 16 Nov 2017 00:00:00 </pubDate></item><item><title>Replication with More Granularity (Tiramisu)</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/pike/replication-group.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/replication-cg"&gt;https://blueprints.launchpad.net/cinder/+spec/replication-cg&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In Mitaka, replication v2.1 (Cheesecake) [1][2] was implemented to support
a disaster recovery scenario when an entire host can be failed over to
a secondary site. The Cheesecake API was admin facing.&lt;/p&gt;
&lt;p&gt;At the Mitaka mid-cycle meetup, Cinder team decided that after Cheesecake
is implemented, Tiramisu will be the next step. Tiramisu is the code name
for tenant facing replication APIs with more granularity. It gives tenant
more control of what should be replicated together.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Replication v2.1, which was implemented in Mitaka as an admin API, was
designed to solve a true DR scenario when the entire backend has to be
failed over to the backend on the secondary site. This is definitely a
very important use case.&lt;/p&gt;
&lt;p&gt;There are other cases where the customers also want to have more control
over the granularity of replication. The ability to replicate a group
of volumes and test failover without affecting the entire backend is
also a desired feature. A tenant facing API is needed to meet this
requirement because only a tenant knows what volumes should be grouped
together for his/her application.&lt;/p&gt;
&lt;p&gt;It is true that you can do group based replication with Cheesecake by
creating a volume type with replication information and creating volumes
of that volume type so all volumes created with that type belongs to
the same group. So what can Tiramisu do that Cheesecake cannot?&lt;/p&gt;
&lt;p&gt;In Tiramisu, a group construct will be used to manage the group of
volumes to be replicated together for the ease of management.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The group constuct designed in the Generic Volume Group spec [3] will
provide tenant facing group APIs to allow a tenant to decide what
volumes should be grouped together and when and what volumes
should be added to or removed from the group.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enable replication function will be added to allow the tenant to
decide when all volumes needed for a particular application have
been added to the group and signal the start of the replication
process.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Disable replication function will be added to allow the tenant to
decide when to stop the replication process and make adjustments
to the group.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Failover replication function will be added for the tenant to
test a failover of a group and make sure that data for the
application will not be compromised after a failover.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A tenant can test a failover without affecting the entire backend.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A tenant can decide when and whether to failover when the disaster
strikes.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If a tenant has already failed over a group using the Tiramisu API
and then a true DR situation happens, the Cheesecake API can still
be used to failover the entire backend. The group of volumes already
been failed over should not be failed over again. Tiramisu will be
using the config options such as &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;replication_device&lt;/span&gt;&lt;/code&gt; designed for
Cheesecake.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;An application may have a database stored on one volume and logs stored on
another and other related files on other volumes. The ability to replicate
all the volumes used by the application together is important for some
applications. So the concept to have a group of volumes replicated
together is valuable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A tenant wants to control what volumes should be grouped together during
a failover and only the tenant has knowledge on what volumes belonging to
the same application and should be put into the same group.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A tenant can determine when to start the replication process of a group
by doing enable replication after all volumes used by an application
have been added to the group.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A tenant can determine when to stop the replication process of a group
by doing disable replication when he/she needs to make adjustments to
the group.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A tenant wants the ability to verify that the data will not be compromised
after a failover before a true DR strikes. He/she is only concerned about
his/her own application and wants to be able to test the failover of
his/her own group of volumes without affecting the entire backend.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A tenant wants to decide when and whether to failover when the disaster
happens.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;The Generic Volume Group design is in a separate spec [3] and this spec
depends on it. The URL for the group action API is from the Generic Volume
Group spec:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;‘/v3/&amp;lt;tenant_id&amp;gt;/groups/&amp;lt;group_uuid&amp;gt;/action’&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;The following actions will be added to support replication for a group of
volumes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;enable_replication&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;disable_replication&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;failover_replication&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;list_replication_targets&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If a volume is “in-use”, a “allow-attached-volume” flag needs to set to
True for failover_replication to work. This is to prevent the tenant
from abusing the failover API and causing problems when forcefully
failing over an attached volume. Either the tenant or the admin should
detach the volume before failing over, or it will be handled by a higher
layer project such as Karbor.&lt;/p&gt;
&lt;p&gt;Group type needs to have the following group_spec to support
replication:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="s1"&gt;'group_replication_enabled'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="ow"&gt;is&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;
&lt;span class="ow"&gt;or&lt;/span&gt;
&lt;span class="s1"&gt;'consistent_group_replication_enabled'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="ow"&gt;is&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Driver also needs to report &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;group_replication_enabled&lt;/span&gt;&lt;/code&gt; or
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;consistent_group_replication_enabled&lt;/span&gt;&lt;/code&gt; as capabilities.&lt;/p&gt;
&lt;p&gt;Karbor or another data protection solution can be the consumer of the
replication API in Cinder. The flow is like this:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Admin configures cinder.conf.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Admin sets up group type and volume types in Cinder.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tenant creates a group that supports replication in Cinder.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tenant creates volumes and puts into the group in Cinder.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In Karbor, a tenant chooses what resources to put in a protection group.
For Cinder volume, Karbor can detect whether a selected volume belongs
to a replication group and automatically selects all volumes in that
group. For example, Karbor can check whether a Cinder volume group has
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;group_replication_enabled&lt;/span&gt;&lt;/code&gt; or &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;consistent_group_replication_enabled&lt;/span&gt;&lt;/code&gt;
in its group specs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There are APIs to create/delete/update/list/show a group in the Generic
Volume Group spec [3]. Karbor or another data protection solution can use
those APIs to manage the groups for the tenant.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In Karbor, a protection action can be executed depending on the
protection policies. If the protection action triggers a fail over,
Karbor can call Cinder’s replication API to failover the replication
group.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;As discussed during the Cinder Newton midcycle meetup [4], driver can
report &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;replication_status&lt;/span&gt;&lt;/code&gt; as part of volume_stats. The volume manager
will check the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;replication_status&lt;/span&gt;&lt;/code&gt; in volume_stats and update database
if &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;replication_status&lt;/span&gt;&lt;/code&gt; is &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;error&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Do not add a generic volume group construct. Instead, just use the existing
consistency group to implement group replication.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;Group actions will be added:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;enable_replication&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;disable_replication&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;failover_replication&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;list_replication_targets&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;URL for the group action API from the Generic Volume Group design::&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;‘/v2/&amp;lt;tenant_id&amp;gt;/groups/&amp;lt;group_uuid&amp;gt;/action’&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Enable replication&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Method: POST&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;JSON schema definition for V3:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'enable_replication'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Normal response codes: 202&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Error response codes: 400, 403, 404&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Disable replication&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Method: POST&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;JSON schema definition for V3:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'disable_replication'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Normal response codes: 202&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Error response codes: 400, 403, 404&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Failover replication&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Method: POST&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;JSON schema definition for V3:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'failover_replication'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s1"&gt;'allow_attached_volume'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'secondary_backend_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'vendor-id-1'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Normal response codes: 202&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Error response codes: 400, 403, 404&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;List replication targets&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Method: POST&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;JSON schema definition for V3:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'list_replication_targets'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Response example:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'replication_targets'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s1"&gt;'backend_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'vendor-id-1'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'unique_key'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'val1'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="o"&gt;......&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s1"&gt;'backend_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'vendor-id-2'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'unique_key'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'val2'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="o"&gt;......&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
     &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Response example for non-admin:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'replication_targets'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s1"&gt;'backend_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'vendor-id-1'&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s1"&gt;'backend_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'vendor-id-2'&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
     &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;Notifications will be added for enable, disable, and failover replication.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;python-cinderclient needs to support the following actions.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;enable_replication&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;disable_replication&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;failover_replication&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;list_replication_targets&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Driver developers need to modify drivers to support Tiramisu.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;xing-yang&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;jgriffith&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Change capability reporting. Driver needs to report
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;group_replication_enabled&lt;/span&gt;&lt;/code&gt; or
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;consistent_group_replication_enabled&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add group actions to support group replication.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;This is built upon the Generic Volume Group spec which is already
merged and implemented.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;New unit tests will be added to test the changed code.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Documentation changes are needed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;[1] Replication v2.1 Cheesecake Spec:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://specs.openstack.org/openstack/cinder-specs/specs/mitaka/cheesecake.html"&gt;https://specs.openstack.org/openstack/cinder-specs/specs/mitaka/cheesecake.html&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;[2] Replication v2.1 Cheesecake Devref:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/cinder/blob/master/doc/source/devref/replication.rst"&gt;https://github.com/openstack/cinder/blob/master/doc/source/devref/replication.rst&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;[3] Generic Volume Group:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/cinder-specs/blob/master/specs/newton/generic-volume-group.rst"&gt;https://github.com/openstack/cinder-specs/blob/master/specs/newton/generic-volume-group.rst&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;[4] Newton Midcycle Meetup:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://etherpad.openstack.org/p/newton-cinder-midcycle-day3"&gt;https://etherpad.openstack.org/p/newton-cinder-midcycle-day3&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
</description><pubDate>Thu, 16 Nov 2017 00:00:00 </pubDate></item><item><title>Shared backend config stanza</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/pike/shared-backend-config.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/shared-backend-config"&gt;https://blueprints.launchpad.net/cinder/+spec/shared-backend-config&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Add a new config section for shared backend configuration options.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Right now there isn’t a great way to share config options between backends
in a multi-backend cinder.conf. You can put things in DEFAULT, but drivers
self.configuration won’t be able to see it if they were defined in their own
stanza. You can just look directly at the DEFAULT section, but you then can’t
easily override it in the driver backend section if you &lt;em&gt;did&lt;/em&gt; want to have
something special. As an example consider the following cinder.conf:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;DEFAULT&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;enabled_backends&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;backend1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;backend2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;backend3&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="n"&gt;my_driver_param&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;backend1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="n"&gt;my_driver_param&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bar&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;backend2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;..&lt;/span&gt;
&lt;span class="c1"&gt;# not specifying the param&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;backend3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;also&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;specifying&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;maybe&lt;/span&gt; &lt;span class="n"&gt;even&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;different&lt;/span&gt; &lt;span class="n"&gt;volume&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;doesn&lt;/span&gt;&lt;span class="s1"&gt;'t matter)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;What we end up with is backend1 gets ‘bar’ and backend2/3 get whatever the
default was for ‘my_driver_param’. To get them to use ‘foo’ we need something
like:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;DEFAULT&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;enabled_backends&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;backend1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;backend2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;backend3&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;backend1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="n"&gt;my_driver_param&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bar&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;backend2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;..&lt;/span&gt;
&lt;span class="n"&gt;my_driver_param&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;backend3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="n"&gt;my_driver_param&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Part of the confusion is that if you don’t use the multi-backend format you
actually do want the options set in DEFAULT.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;The main use-case here is for shared configs relevant to multiple backends
in cinder.conf. Also to help lessen some of the confusion about shared config
options in DEFAULT.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;The new config section called ‘backend_defaults’ will contain config options
that each backend has access to. If any options are also in the backend stanza
that backend specific value will take precedence. It will be safe to assume
that config options in shared will be shared and available for all backends.
None of the guesswork from DEFAULT.&lt;/p&gt;
&lt;p&gt;A new config then might look something like:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;DEFAULT&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;enabled_backends&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;backend1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;backend2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;backend3&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;backend_defaults&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;my_driver_param&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;backend1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="n"&gt;my_driver_param&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bar&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;backend2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;..&lt;/span&gt;
&lt;span class="c1"&gt;# not defining the value, but it gets picked up&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;backend3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="c1"&gt;# same here..&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This is the same as the example above where all backends define the value. This
simplistic example doesn’t really show a ton of the benefits, so a slightly
more realistic example might be:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;DEFAULT&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;enabled_backends&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pure1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pure2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pure3&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;backend_defaults&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;volume_driver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cinder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;volume&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;drivers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pure&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PureISCSIDriver&lt;/span&gt;
&lt;span class="n"&gt;driver_ssl_verify&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;
&lt;span class="n"&gt;driver_ssl_cert&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;blah&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;my_cert&lt;/span&gt;
&lt;span class="n"&gt;use_multipath_for_image_xfer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;
&lt;span class="n"&gt;use_chap_auth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;
&lt;span class="n"&gt;image_volume_cache_enabled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;
&lt;span class="n"&gt;image_volume_cache_max_count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;
&lt;span class="n"&gt;image_volume_cache_max_size_gb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;
&lt;span class="n"&gt;max_over_subscription_ratio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
&lt;span class="n"&gt;pure_eradicate_on_delete&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;pure1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;san_ip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;1.2.3.4&lt;/span&gt;
&lt;span class="n"&gt;pure_api_token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;abcdef123456&lt;/span&gt;
&lt;span class="n"&gt;max_over_subscription_ratio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;pure2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;san_ip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;1.2.3.5&lt;/span&gt;
&lt;span class="n"&gt;pure_api_token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;abcdef1234567&lt;/span&gt;
&lt;span class="n"&gt;image_volume_cache_max_count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;pure3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;san_ip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;1.2.3.6&lt;/span&gt;
&lt;span class="n"&gt;pure_api_token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;abcdef12345678&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;So here we have a ton of shared config options, leaving only a few specific to
each backend.&lt;/p&gt;
&lt;p&gt;In addition to the shared config section we will deprecate setting backends
via the DEFAULT section. We will only allow multi-backend style configs using
the “enabled_backends” config option.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;We could change the behavior so that things in DEFAULT do this, but it not
be backwards compatible with older cinder.confs. Behavior would probably not
be what deployers would expect when upgrading.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;Would have a new config mechanism to learn, but older style configs would still
work the same way. They will eventually need to migrate to using the
“enabled_backends” config option, this process will follow the standard
deprecation process.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Nothing other than needing to be aware of how drivers can get their config
values.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;patrick-east&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add a warning when initializing c-vol without “enabled_backends”&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify the driver config utility to look for this section first, and override
values with backend specific ones if they are defined.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add some unit tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Incorporate into multi-backend tempest test configuration&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tempest test config with devstack (reach goal, depends on timing)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Updated driver config references&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Driver dev documentation to explain how this works&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/shared-backend-config"&gt;https://blueprints.launchpad.net/cinder/+spec/shared-backend-config&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Thu, 16 Nov 2017 00:00:00 </pubDate></item><item><title>Migrate ConfKeyManager encryption key ID into Barbican</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/queens/migrate-fixed-key-to-barbican.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/migrate-fixed-key-to-barbican"&gt;https://blueprints.launchpad.net/cinder/+spec/migrate-fixed-key-to-barbican&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Support the transition to Barbican by migrating existing keys associated with
the ConfKeyManager into Barbican. The ConfKeyManager key uses a key ID of all
zeros that’s associated with the fixed_key configuration parameter in the
key_manager section of cinder.conf.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;The legacy ConfKeyManager is insecure, and the prefered encryption key manager
is Barbican. Using Barbican in new deployments is easy, but switching
deployments from the ConfKeyManager to Barbican is difficult when there are
existing volumes encrypted using the ConfKeyManager.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;A user has a deployment based on the ConfKeyManager. They wish to to switch to
Barbican, but there are existing volumes encrypted using the ConfKeyManager.
These existing volumes must continue to function when Barbican is the key
manager. The user needs a migration path to Barbican that doesn’t break
existing encrypted volumes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;This spec proposes that all instances of the ConfKeyManager’s key (identifed
by an all-zeros key ID) be replaced with an identical key stored in Barbican.
This is possible because Barbican provides a mechanism for storing existing
encryption keys.&lt;/p&gt;
&lt;p&gt;A cinder-volume thread will be used to search for encryption key ID instances
in the database that match the ConfKeyManager’s all-zeros ID. This thread will
be refered to as the key migration thread.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The key migration thread will search the volume table for encryption_key_id
entries matching the all-zeros ConfKeyManager key ID. For each matching
entry in the volume table, a new Barbican key ID will be created with the
exact same secret derived from the fixed_key config value used by the
ConfKeyManager. The volume table is updated with the new Baribican key ID.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The thread will only migrate keys associated with volumes belonging to that
host. This will avoid contention when there are multiple cinder-volume hosts.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The key migration thread will also look for ConfKeyManager keys stored in
metadata tables. Where appropriate, these entries will be updated with the
Barbican key ID stored in the corresponding volume table. Otherwise, a new
Barbican key ID will be created.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The key migration thread will be spawned on start-up whenever both the
following conditions are true:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;The ConfKeyManager’s “fixed_key” is configured&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The key_manager’s “backend” (was “api_class”) is &lt;em&gt;not&lt;/em&gt; the ConfKeyManager&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The key migration thread will generate logs that indicate a key ID has
been migrated to Barbican. It will also generate a log that indicates the
thread has run to completion without finding any key IDs associated with
the ConfKeyManager.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The user is responsible for deciding when to remove the fixed_key from the
deployment. It is recommended the user use the logs messages described above
to determine when the key migration process has completed. Once the user
removes the fixed_key from the configuration, the key migration thread will
not be spawned on startup.&lt;/p&gt;
&lt;p&gt;The key migration thread will work in conjunction with an enhancement to
Castellan and/or Barbican. During the migration process, cinder services may
still encounter the ConfKeyManager’s key ID (all zeros) in the database. This
is not a valid Barbican key ID, and Barbican will throw an error if asked to
provide the key associated with that ID. The enhancement will essentially
intercept requests for the all-zeros key ID, and return the ConfKeyManager’s
response. All of this would be totally transparent to the rest of the Cinder
code. In short, the all-zeros key ID will continue to work even with Barbican
as the designated key manager.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Instead of using a separate migration thread, each piece of code that fetches
and uses the encryption key ID could be responsible for migrating the key into
Barbican. However, there are multiple places where the code needs to handle
the key ID, and each instance would need to be updated to perform the
migration. This approach would involve significantly more code change, and
would require more long-term maintenance.&lt;/p&gt;
&lt;p&gt;We could also not migrate keys to Barbican at all, and simply allow the
Castellan-Barbican enhancement to handle requests for the all-zeros key ID.
However, this would require the user retain the fixed_key value in the
configuration, which essentially misses the point of migrating to Barbican.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None. Existing database entries that contain the ConfKeyManager’s encryption
key ID will be updated with references to a Barbican key ID, but the database
structure will not change.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;This change should be considered a security enhancement in that it facilitates
transitioning existing ConfKeyManager deployments to Barbican.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Minimal. The key migration thread will not be CPU intensive, and other cinder
operations will not need to block until the migration thread completes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Alan Bishop&amp;lt;&lt;a class="reference external" href="mailto:abishop%40redhat.com"&gt;abishop&lt;span&gt;@&lt;/span&gt;redhat&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Develop code framework for scanning tables for encryption_key_id that needs
to be migrated to Barbican&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Develop utility code for generating new Barbican key ID with ConfKeyManager’s
secret&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add/update unit tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update documentation&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;Castellan and/or Barbican, will be enhanced to aid the migration process. The
enhancement will allow volumes encrypted with the ConfKeyManager’s key ID to
function properly during the migration process.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add and update the unit tests.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;The documentation will be updated to state that volumes encrypted using the
ConfKeyManager will continue to function correctly after switching to
Barbican. The user needs to feel comfortable knowing the migration to Barbican
is seamless and automatic.&lt;/p&gt;
&lt;p&gt;The changes will explain the user is responsible for removing the
ConfKeyManager’s fixed_key from the deployment, with the recommendation that
the decision to do so be guided by the log messages generated by the key
migration thread. Those message will indicate when keys are still being
migrated, and when the migration process has finished.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Fri, 13 Oct 2017 00:00:00 </pubDate></item><item><title>Add shared_targets column to volumes</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/queens/add-shared-targets-to-volume-ref.html</link><description>

&lt;p&gt;Include the URL of your launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/add-shared-targets-flag-to-volume"&gt;https://blueprints.launchpad.net/cinder/+spec/add-shared-targets-flag-to-volume&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;One problematic thing about dealing with device attachments is that some
devices share a single target for multiple volumes while others have a
single unique target for every volume.&lt;/p&gt;
&lt;p&gt;For example, a device utilizing shared targets, may have a single iSCSI
connection shared for multiple volumes attached to a Nova compute node.&lt;/p&gt;
&lt;p&gt;This can be troublesome because extra care needs to be taken by consumers to
make sure that the target it’s not being used by another volumes on a system
when a delete/detach call is made.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently when os-brick receives a detach operation it attempts to inspect the
system and determine if there are multiple volumes attached to the host sharing
the same target.  Most of the time this works, however it tends to be a bit
prone to races, additionally attempting bus scans is not only inefficient but
unreliable.&lt;/p&gt;
&lt;p&gt;The other problem is that currently there is no indication for os-brick to know
if it’s dealing with a device that utilizes shared targets or not, so we go
through this scanning routine even if we don’t necessarily need to.&lt;/p&gt;
&lt;p&gt;The process of removing targets would be much more robust if we actually knew
ahead of time if the volume was hosted on a device that utilizes shared
targets, in which case we could do things more efficiently including using
locks on a compute node around attach/detach operations for a specific backend.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;This improves the existing use case of detaching volumes correctly and
efficiently.  The basic condition is that you have a device that utilizes
shared-targets, and you have a single volume (V-A) from that device attached to
a compute node.  A user issues a detach call and at the same time another user
issues an attach of a different volume (V-B) from the same backend that will
land on the same compute node.&lt;/p&gt;
&lt;p&gt;It’s possible that the connection response for V-B is completed under the
assumption that the target exists (due to V-B) but then the V-A detach process
performs it’s checks prior to the attachment of V-B being finalized, and as
a result it removes the target and the connection of V-B will appear to have
been successful but the volume will not be accessible.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Add a column to the volume reference that indicates if the backend associated
with the volume utilizes shared-targets or not.  In addition add
a backend-name member to the volume detail view.  When shared-targets is True,
the consumer will know that they’re dealing with a device that uses
shared-targets and that it needs to take some extra precautions.&lt;/p&gt;
&lt;p&gt;In addition we need to provide a unique identifier for the backend, while at
the same time not leaking details of the abstraction to end users.  The
service UUID should work nicely for this.&lt;/p&gt;
&lt;p&gt;For the case of folks that use a single device to back multiple c-vol
services we’ll provide the ability to over-ride/set this identifier in the
config file.  That way an admin can choose to set multiple c-vol configurations
to use the same backend_id if needed.&lt;/p&gt;
&lt;p&gt;Note that by default we will set the shared_targets flag to True.  We use this
as the default because there’s no harm or functional issues with treating
unique targets as shared, it’s just going to introduce some unnecessary locking
but will not impact functionality.  Conversely if a device that actually uses
shared targets is False and not locked we have a race condition between attach
and detach calls that causes problems.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;The scan method we use today works most of the time and is reasonable.  We
could certainly just continue to use that by itself.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;This change adds a new boolean column to the Volumes table (shared_targets).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;What new data objects and/or database schema changes is this going to
require?&lt;/p&gt;
&lt;p&gt;This introduces a new column to the Volumes Table&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;What database migrations will accompany this change.&lt;/p&gt;
&lt;p&gt;We’ll perform a DB migration that adds the column and sets its value to
True.  Setting to True is safe for non-shared targets so while it’s not
necessarily the most efficient way to do things, it’s safe and reliable.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How will the initial set of new data objects be generated, for example if you
need to take into account existing volumes, or modify other existing data
describe how that will work.&lt;/p&gt;
&lt;p&gt;During init of the volume service, we’ll query the backend capabilities for
the setting “shared_targets”, if the value from the stats structure is False
we’ll check any volumes that are set as True and update them accordingly.
This way we migrated everything and set it to true, then on service init we
verify that the setting is actually correct.&lt;/p&gt;
&lt;p&gt;NOTE that we’re already iterating over the volumes of a backend on init, so
we’re not introducing any new overhead or lag here.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;This change does not impact the arguments or options for any of the existing
API calls, however it does add additional fields to the Volume Get response.&lt;/p&gt;
&lt;p&gt;When the appropriate micro-version is selected, we’ll add two additional fields
to the detailed volume response view:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;shared_targets
backend_name&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;This change mostly just provides the user with additional info.  It’s up to the
user/consumer to determine if they want to do anything with this extra info or
not, but it does not change their current use-cases or workflow.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Be default we’ll set the shared_targets flag for volumes to True, but driver
maintainers should add the appropriate stats field to their driver to change
this if they don’t use shared_targets.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;john-griffith&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;Add the changes to Cinder and bump the max support MV in cinderclient.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Add a functional test for the specific microversion and ensure the appropriate
response.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Documenting the new fields in the detailed volume response, and also recommend
how it can be used.  Or just reference this spec.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;/section&gt;
</description><pubDate>Wed, 04 Oct 2017 00:00:00 </pubDate></item><item><title>Use the enginefacade from oslo_db</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/queens/use-oslo_db-enginefacade.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/use-oslodb-enginefacade"&gt;https://blueprints.launchpad.net/cinder/+spec/use-oslodb-enginefacade&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Implement the new oslo.db enginefacade interface described here:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/oslo.db/+spec/make-enginefacade-a-facade"&gt;https://blueprints.launchpad.net/oslo.db/+spec/make-enginefacade-a-facade&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;The linked oslo.db spec contains the details of the proposal, including its
general advantages to all projects. In summary, we transparently track database
transactions using the cinder.RequestContext object. This means that if there
is already a transaction in progress we will use it by default, only creating a
separate transaction if explicitly requested.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;These changes will only affect developers.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Allow a class of database races to be fixed&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cinder currently only exposes db transactions in cinder/db/sqlalchemy/api.py,
which means that every db api call is in its own transaction. Although this
will remain the same initially, the new interface allows a caller to extend a
transaction across several db api calls if they wish. This will enable callers
who need these to be atomic to achieve this, which includes the save operation
on several Cinder objects.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Reduce connection load on the database&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Many database api calls currently create several separate database connections,
which increases load on the database. By reducing these to a single connection,
load on the db will be decreased.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Improve atomicity of API calls&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;By ensuring that database api calls use a single transaction, we fix a class of
bug where failure can leave a partial result.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Make greater use of slave databases for read-only transactions&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The new api marks sections of code as either readers or writers, and enforces
this separation. This allows us to automatically use a slave database
connection for all read-only transactions. It is currently only used when
explicitly requested in code.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Decorate the cinder.RequestContext class&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;cinder.RequestContext is annotated with the
@enginefacade.transaction_context_provider decorator. This adds several code
hooks which provide access to the transaction context via the
cinder.RequestContext object, including attributes ‘session’, ‘connection’,
‘transaction’.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Ensure that all database apis use context session&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Use context session in cinder.db.sqlalchemy.api.model_query().&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Update database apis incrementally&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Individual calls will be annotated as either readers or writers. Existing
transaction management will be replaced.&lt;/p&gt;
&lt;p&gt;Database apis will be updated in batches, by function. For example, Volume
apis, Snapshot apis, Quota apis. Calls into apis which have not been upgraded
yet will continue to explicitly pass the session or connection object.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Alternatives were examined during the design of the oslo.db code. The goal
of this change is to implement a solution which is common across OpenStack
projects.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;By reducing connection load on the database, the change is expected to provide
a small performance improvement. However, the primary purpose is correctness.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;The initial phase of this work will be to implement the new engine facade in
cinder/db/sqlalchemy/api.py only. Callers will not have to consider transaction
context if they do not currently do so, as it will be created and destroyed
automatically.&lt;/p&gt;
&lt;p&gt;This change will allow developers to explicitly extend database transaction
context to cover several database calls. This allows the caller to make
multiple database changes atomically.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Hanxi_Liu &amp;lt;&lt;a class="reference external" href="mailto:hanxi.liu%40easystack.cn"&gt;hanxi&lt;span&gt;.&lt;/span&gt;liu&lt;span&gt;@&lt;/span&gt;easystack&lt;span&gt;.&lt;/span&gt;cn&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Enable use of the new api in Cinder&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;Migrate api bundles along functional lines:&lt;/dt&gt;&lt;dd&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Backup, BackupMetadata&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cluster&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ConsistencyGroup, Cgsnapshot&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DriverInitiatorData&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Encryption&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Group, GroupSnapshot, GroupTypes, GroupTypeSpecs,
GroupTypeProjects, GroupVolumeTypeMapping&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ImageVolumeCacheEntry&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Message&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;QualityOfServiceSpecs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Quota, QuotaClass, QuotaUsage, Reservation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Service&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Snapshot, SnapshotMetadata&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Transfer&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;VolumeAttachment, AttachmentSpecs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Volume, VolumeMetadata, VolumeAdminMetadata, VolumeGlanceMetadata&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;VolumeTypes, VolumeTypeProjects, VolumeTypeExtraSpecs&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;A version of oslo.db including the new enginefacade api:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/138215/"&gt;https://review.openstack.org/#/c/138215/&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;This change is intended to have no immediate functional impact. The current
tests should continue to pass.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Implement the oslo.db enginefacade interface described here:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/oslo.db/+spec/make-enginefacade-a-facade"&gt;https://blueprints.launchpad.net/oslo.db/+spec/make-enginefacade-a-facade&lt;/a&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Use the new oslo_db enginefacade in Nova:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/nova/+spec/new-oslodb-enginefacade"&gt;https://blueprints.launchpad.net/nova/+spec/new-oslodb-enginefacade&lt;/a&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Use the new oslo_db enginefacade in Neutron:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/enginefacade-switch"&gt;https://blueprints.launchpad.net/neutron/+spec/enginefacade-switch&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Sat, 30 Sep 2017 00:00:00 </pubDate></item><item><title>Support get volume metadata summary</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/pike/support-get-volume-metadata-summary.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/metadata-for-volume-summary"&gt;https://blueprints.launchpad.net/cinder/+spec/metadata-for-volume-summary&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Support get volumes’ metadata through volume summary API.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently, Cinder supports filter volumes with metadata. But in some case,
users don’t know what metadata all the volumes contain or what metadata is
valid to filter volumes. Then users need to show the volumes one by one to get
the correct metadata, this is really a heavy and unfriendly way. Imaging that
if there are hundreds of volumes, admin users will take a very long time to
query all metadata.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;1. For users, they can get all the metadata easily just through one API
request.
2. For dashboard, such as Horizon, it can use this metadata information to show
end users a dropdown list.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;DB layer change:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;All the volumes’ metadata can be got by the sql query.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;li&gt;&lt;dl&gt;
&lt;dt&gt;API layer change:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Add a new micro version. Add “metadata” to volume-summary API response
body. The body will be like:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="s2"&gt;"metadata"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"key1"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"value1"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="s2"&gt;"key2"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"value2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"value3"&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Leave as it is. Let the operators get volumes metadata by themselves through
some peripheral ways. Such as, create a script to call volume-list-detail API
and then analyse the result one by one.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;A new microversion will be created.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="cinder-client-impact"&gt;
&lt;h3&gt;Cinder-client impact&lt;/h3&gt;
&lt;p&gt;Now both OpenStackClient and CinderClient don’t support volume-summary
command. We can add them as well.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;There is a little performance influence about volume-summary API since a new
sql query action will be added.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;wangxiyuan(&lt;a class="reference external" href="mailto:wangxiyuan%40huawei.com"&gt;wangxiyuan&lt;span&gt;@&lt;/span&gt;huawei&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add a new microversion.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add volumes’ metadata to the volume-summary API’s response body.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add client side support.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add unit tests.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Update API documentation.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 31 Aug 2017 00:00:00 </pubDate></item><item><title>cinder db purge utility</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/kilo/database-purge.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/database-purge"&gt;https://blueprints.launchpad.net/cinder/+spec/database-purge&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This spec adds the ability to sanely and safely purge deleted rows from
the cinder database for all relavent tables. Presently, we keep all deleted
rows, or archive them to a ‘shadow’ table. I believe this is unmaintainable
as we move towards more upgradable releases. Today, most users depend on
manual DB queries to delete this data, but this opens up to human errors.&lt;/p&gt;
&lt;p&gt;The goal is to have this be an extension to the &lt;cite&gt;cinder-manage db&lt;/cite&gt; command.
Similar specs are being submitted to all the various projects that touch
a database.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Very long lived Openstack installations will carry around database rows
for years and years. To date, there is no “mechanism” to programmatically
purge the deleted data. The archive rows feature doesn’t solve this.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;Operators should have the ability to purge deleted rows, possibily on a
schedule (cronjob) or as needed (Before an upgrade, prior to maintenance)
The intended use would be to specify a number of days prior to today for
deletion, e.g. “cinder-manage db purge 60” would purge deleted rows that
have the “deleted_at” column greater than 60 days ago&lt;/p&gt;
&lt;section id="project-priority"&gt;
&lt;h3&gt;Project Priority&lt;/h3&gt;
&lt;p&gt;Low&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;The proposal is to add a “purge” method to DbCommands in
cinder/cinder/cmd/manage.py
This will take a number of days argument, and use that for a data_sub match
Like:
delete from instances where deleted != 0 and deleted_at &amp;gt; data_sub(NOW()…)&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Today, this can be accomplished manually with SQL commands, or via script.
There is also the archive_deleted_rows method. However, this won’t satisfy
certain data destruction policies that may exist at some companies.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None, all tables presently include a “deleted_at” column.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None, this would be run from cinder-manage&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;Low, This only touches already deleted rows.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;This has the potential to improve performance for very large databases.
Very long-lived installations can suffer from inefficient operations on
large tables.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;primary author and contact.&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Abel Lopez &amp;lt;al592b&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&amp;lt;al592b&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&amp;lt;al592b&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;Add purge functionality to manage.py db/api.py db/sqlalchemy/api.py
Add tests to confirm functionality
Add documentation of feature&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;The test will be written as such. Three rows will be inserted into a test db.
Two will be “deleted=1”, one will be “deleted=0”
One of the deleted rows will have “deleted_at” be NOW(), the other will be
“deleted_at” a few days ago, lets say 10. The test will call the new
function with the argument of “7”, to verify that only the row that was
deleted at 10 days ago will be purged. The two other rows should remain.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;will need to add documentation of this feature&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;This was discussed on both the openstack-operators mailing list and the
openstack-developers mailing lists with positive feedback from the group.&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://lists.openstack.org/pipermail/openstack-dev/2014-October/049616.html"&gt;http://lists.openstack.org/pipermail/openstack-dev/2014-October/049616.html&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Wed, 16 Aug 2017 00:00:00 </pubDate></item><item><title>Add connector object to create_export call</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/liberty/create-export-connector.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/add-create-export-connector"&gt;https://blueprints.launchpad.net/cinder/+spec/add-create-export-connector&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;There are a good number of volume drivers in Cinder today, that are using
initialize_connection to do the work of exporting a volume as a target
to an initiator (nova compute host).  One of the reasons that those drivers
are doing that, is because the create_export method API doesn’t include
the connector object being passed in.  This spec outlines adding the
connector object to the standard volume driver API for create_export.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;There are many drivers in Cinder today that are doing volume target exports
inside of initialize_connection, instead of the create_export method.
One of the reasons for this is a documented understanding of what the
differences between these 2 methods is supposed to be.  The other problem
that prevents drivers from doing the work inside of create_export, is that
create_export is missing the connector object coming from the initiator.
Some backends require the connector object, which contains the initiator
information, in order to export a target from their array.  So, drivers
end up moving all of that exporting code into initialize_connection, because
that’s the only driver call that has the connector object.&lt;/p&gt;
&lt;p&gt;The other issue with Cinder drivers doing the exporting of volume targets
in initialize_connection, is that Nova calls initialize_connection repeatedly
during other processes not involved with attaching a volume, such as live
migration.  Nova will call a driver’s initialize_connection simply to fetch
the connection_information about an exported volume, not because it wants
to attach a volume.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;The main use case is attaching a volume.  When someone calls Cinder to attach
a volume, they eventually call the volume manager’s initialize_connection
method.  The volume manager’s initialize_connection method first calls
create_export, with the intention of asking the driver to create a target
that is exported from the array to an initiator.  Then the volume manager
calls the driver’s initialize_connection to fetch the target information to
pass back to the caller, to discover the volume showing up.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;The proposed change is simple.  Add the already existing connector object
in the call to create_export.  This makes the connector object universally
available to all drivers during create_export time.  Then each driver can
eventually be changed by each maintainer to do the target exporting, instead
of during initialize_connection time.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;We can do nothing, and ask that each driver maintainer be more careful about
doing any creating of exports inside of initialize_connection if they already
exist.  This basically makes create_export useless and a noop for all of those
drivers.  I’d rather see every driver use each method as they were intended, so
to make reviewing drivers more consistent across all of Cinder.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;If driver developers move the creating of the exports into create_export,
then any calls into initialize_connection should be faster, depending on the
driver of course.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Once the connector object is available inside of create_export, then it’s
possible for drivers to migrate their existing export creation code from
initialize_connection into create_export.  Reviewers should also be looking
for this in existing and future reviews, and not approving drivers that ignore
create_export.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;walter-boring&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;First is to update the base driver.py’s create_export method.
Then each other driver that defines create_export will have to accept the
new connector object.&lt;/p&gt;
&lt;p&gt;Then the volume manager call to create_export will need to pass the connector.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Any and all Unit tests will need to be updated to note the new connector
object parameter.  Driver’s unit tests will need to be updated as well.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;A lot of research has gone into this, due to the efforts of trying to
make Nova live migration with cinder volumes work.  There is an existing
etherpad that talks about the known issues of Nova, Cinder interaction.
That etherpad also lists out the Cinder drivers that have potential problems
with live migration due to creating exports inside of initialize_connection.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://etherpad.openstack.org/p/CinderNovaAPI"&gt;https://etherpad.openstack.org/p/CinderNovaAPI&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Wed, 16 Aug 2017 00:00:00 </pubDate></item><item><title>Cinder volume driver for Huawei SDSHypervisor</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/liberty/huawei-sdshypervisor-driver.html</link><description>

&lt;p&gt;Include the URL of your launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/huawei-sdshypervisor-driver"&gt;https://blueprints.launchpad.net/cinder/+spec/huawei-sdshypervisor-driver&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This proposal is to add Huawei SDSHypervisor driver to cinder.&lt;/p&gt;
&lt;p&gt;Huawei SDSHypervisor is a storage virtualization solution, is a software
running in host, just focus on the data plane, the goal is to facilitate
the reuse of customer’s existing old and low-end devices. SDSHypervisor does
not interact with the storage device in control plane, such as create volume,
create snapshot, do not need third-party device manufacturers to develop any
driver. Administrator just attaches Lun to the hypervisor node as hypervisor
storage entity and hypervisor will provide virtual volume based user’s QoS
and patch advance feature to these Lun such as snapshot, link clone, cache,
thin provision and so on.&lt;/p&gt;
&lt;p&gt;The purpose of this blue print is to add Huawei SDSHypervisor Driver to Cinder.&lt;/p&gt;
&lt;p&gt;Currently there are many heterogeneous storage devices in user product
environment which is low-level device without advance feature, e.g. snapshot,
clone, cache, thin provision, QoS. So adding the SDShypervisor driver will
bring the following advantages:
* Better I/O performance using SDSHypervisor cache feature when there is
SSD in host.
* Facilitate the reuse of customer’s existing old and low-end devices, patch
advance feature to these device via SDSHypervisor, e.g. snapshot, clone,
cache, thin provision, QoS
* Help customer use Openstack build his cloud OS. For Cinder, we can’t allow
driver to unlimited expand. For manufacturers, they may not want to spend more
time to develop cinder driver for these obsolete and not be maintained
devices. But in the customer’s environment there are such devices which need
to be accessed to openstack, in this situation customers can access these
devices to hypervisor, indirect access to Cinder, use Openstack build his
cloud OS.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently, user can’t access Huawei SDShypervisor by Openstack Cinder.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;We will add a new Cinder driver that uses socket API interact with Huawei
SDShypervisor storage. SDShypervisor data panel using private Key value
protocol, so we also add a new connector to realize attach/detach volume.&lt;/p&gt;
&lt;p&gt;The following diagram shows the command and data paths.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;                &lt;span class="o"&gt;+------------------+&lt;/span&gt;
                &lt;span class="o"&gt;|&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt;
                &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;Cinder&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;
                &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;Cinder&lt;/span&gt; &lt;span class="n"&gt;Volume&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;
                &lt;span class="o"&gt;|&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt;
                &lt;span class="o"&gt;|&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt;
                &lt;span class="o"&gt;+------------------+&lt;/span&gt;
                &lt;span class="o"&gt;|&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt;
                &lt;span class="o"&gt;|&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt;
                &lt;span class="o"&gt;|&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt;
                &lt;span class="o"&gt;|&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+---------------+-------+&lt;/span&gt;     &lt;span class="o"&gt;+----+------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                       &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;                       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt;                       &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;                       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="n"&gt;SDShypervisor&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;SDShypervisor&lt;/span&gt; &lt;span class="n"&gt;Driver&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="n"&gt;connector&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;                       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                       &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;                       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+-----------------------+&lt;/span&gt;     &lt;span class="o"&gt;+-----------------------+&lt;/span&gt;
                   &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;
                   &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;
                   &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;
                  &lt;span class="n"&gt;CLI&lt;/span&gt;     &lt;span class="n"&gt;Socket&lt;/span&gt; &lt;span class="n"&gt;API&lt;/span&gt;
                   &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;
                   &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;
                   &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;
                &lt;span class="o"&gt;+--+-----------+---+&lt;/span&gt;
                &lt;span class="o"&gt;|&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt;
                &lt;span class="o"&gt;|&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt;
                &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;SDShypervisor&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;
                &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="n"&gt;storeage&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;
                &lt;span class="o"&gt;|&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt;
                &lt;span class="o"&gt;+------------------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Add new driver in /cinder/volume/drivers path, and realize cinder driver
minimum features:
* Volume Create/Delete
* Volume Attach/Detach
* Snapshot Create/Delete
* Create Volume from Snapshot
* Get Volume Stats
* Copy Image to Volume
* Copy Volume to Image
* Clone Volume
* Extend Volume&lt;/p&gt;
&lt;p&gt;Add new connector in cinder/brick/initiator path, and realize abstract
connector methods:
* connect_volume
* disconnect_volume&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;User will be able to use Huawei SDSHypervisor with Cinder.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;zhangni &amp;lt;&lt;a class="reference external" href="mailto:zhangni%40huawei.com"&gt;zhangni&lt;span&gt;@&lt;/span&gt;huawei&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;None&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;Realize Cinder driver minimum features using socket API.
Realize new connector using CLI.
Add unit test code for Huawei SDShypervisor cinder driver and connector.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;Because Huawei SDShypervisor data panel using private Key-Value protocol,
we will create a new libvirt volume driver in Nova to realize
attach/detach volume to instance. Nova BP page is
&lt;a class="reference external" href="https://blueprints.launchpad.net/nova/+spec/huawei-sdshypervisor-volume-driver"&gt;https://blueprints.launchpad.net/nova/+spec/huawei-sdshypervisor-volume-driver&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;3rd party continuous integration will be done for Huawei SDSHypervisor Driver.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;The CinderSupportMatrix table and Block storage manual should be updated to
add Huawei SDShypervisor.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="https://wiki.openstack.org/wiki/Cinder/HuaweiSDSHypervisorDriver"&gt;https://wiki.openstack.org/wiki/Cinder/HuaweiSDSHypervisorDriver&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Wed, 16 Aug 2017 00:00:00 </pubDate></item><item><title>Add QoS capability to the IBM Storwize driver</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/juno/cinder-storwize-driver-qos.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/cinder-storwize-driver-qos"&gt;https://blueprints.launchpad.net/cinder/+spec/cinder-storwize-driver-qos&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Storwize driver can provide the QoS capability with the parameter of
IO throttling, which caps the amount of I/O that is accepted. This
blueprints proposes to add the QoS support for Storwize driver.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Storwize backend storage can be enabled with the QoS support by limiting
the amount of I/O for a specific volume. QoS has been implemented for
some cinder storage drivers, and it is feasible for the storwize driver
to add this feature as well.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;To enable the QoS for storwize driver, an extra spec with IOThrottling as the
key needs to bind to a volume type. All the following changes apply to the
Storwize driver code.&lt;/p&gt;
&lt;p&gt;Create volume:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;If QoS is enabled and IOThrottling is available as the QoS key, set the I/O
throttling of the volume into the specified IOThrottling value.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Create clone volume:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;If the QoS is set for the original volume, the target volume needs to set
to the same QoS.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Create snapshot:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The QoS attributes will be copied to the snapshot.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Create volume from snapshot:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;If QoS is enabled and IOThrottling is available as the QoS key, set the IO
throttling of the volume into the specified IOThrottling value.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Re-type volume:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;If a volume type is changed, a different IOThrottling value will apply to
the volume and the I/O of the volume needs to be set to the new IO
throttling.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;The proposed change follows the pattern, in which other drivers implement the
QoS feature.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;The QoS for Storwize driver can be configurable with a configuration option
in cinder.conf. An extra spec with the key of IOThrottling can bind to a
volume type, so that the volumes with this volume type are guaranteed with
an I/O throttling rate.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Vincent Hou&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;TBD&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add a configuration option to allow the user the use the QoS for Storwize
driver.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the QoS enablement check and set the I/O throttling in create volume.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the QoS enablement check and set the I/O throttling in create volume
from snapshot.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set the I/O throttling to the new volume according to the original volume
in create clone volume.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Copy the QoS attributes to the snapshot in create snapshot.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Change the I/O throttling of the volume if the volume type is changed.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit tests need to be added to test the QoS for Storwize driver.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add how to configure the QoS for the Storwize driver in the document.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add QoS capability to the IBM storwize driver
&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/cinder-storwize-driver-qos"&gt;https://blueprints.launchpad.net/cinder/+spec/cinder-storwize-driver-qos&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Sun, 13 Aug 2017 00:00:00 </pubDate></item><item><title>Oracle ZFS Storage Appliance iSCSI Driver</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/juno/oracle-zfssa-cinder-driver.html</link><description>

&lt;p&gt;Include the URL of your launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/oracle-zfssa-cinder-driver"&gt;https://blueprints.launchpad.net/cinder/+spec/oracle-zfssa-cinder-driver&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;ZFSSA ISCSI Driver is designed for ZFS Storage Appliance product
line (ZS3-2, ZS3-4, ZS3-ES, 7420 and 7320). The driver provides the ability
to create iSCSI volumes which are exposed from the ZFS Storage Appliance
for use by VM instantiated by Openstack’s Nova module.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently there is no support for ZFS Storage Appliance product line from
Openstack Cinder.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;iSCSI driver uses REST API to communicate out of band with the storage
controller.
The new driver would be located under cinder/volume/drivers/zfssa, and
it would be able to perform the following:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create/Delete Volume&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Extend Volume&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create/Delete Snaphost&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create Volume from Snapshot&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete Volume Snapshot&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Attach/Detach Volume&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Get Volume Stats&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Additionally a ZFS Storage Appliance workflow (cinder.akwf) is provided
to help the admin to setup a user and role in the appliance with enought
privileges to do cinder operations.
Also, cinder.conf has to be configured properly with zfssa specific
properties for the driver to work.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;User will be able to use ZFS Storage Appliance product line with
Openstack Cinder.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;juan-c-zuluaga &amp;lt;&lt;a class="reference external" href="mailto:juan.c.zuluaga%40oracle.com"&gt;juan&lt;span&gt;.&lt;/span&gt;c&lt;span&gt;.&lt;/span&gt;zuluaga&lt;span&gt;@&lt;/span&gt;oracle&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;brian-ruff &amp;lt;&lt;a class="reference external" href="mailto:brian.ruff%40oracle.com"&gt;brian&lt;span&gt;.&lt;/span&gt;ruff&lt;span&gt;@&lt;/span&gt;oracle&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;All the features that ZFS Storage Appliance iSCSI does.
Add CI unit test for ZFS Storage Appliance iSCSI Cinder Driver&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;Minimum ZFS Storage Appliance with OS8.2&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;CI will be performed for ZFS Storage Appliance iSCSI Driver.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Cinder Support Matrix should be updated.
&lt;a class="reference external" href="https://wiki.openstack.org/wiki/CinderSupportMatrix"&gt;https://wiki.openstack.org/wiki/CinderSupportMatrix&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="http://www.oracle.com/us/products/servers-storage/storage/nas/overview/index.html"&gt;http://www.oracle.com/us/products/servers-storage/storage/nas/overview/index.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ZFS Storage Appliance Workflow.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://docs.oracle.com/cd/E26765_01/html/E26397/maintenance__workflows.html#maintenance__workflows__bui"&gt;http://docs.oracle.com/cd/E26765_01/html/E26397/maintenance__workflows.html#maintenance__workflows__bui&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Sun, 13 Aug 2017 00:00:00 </pubDate></item><item><title>Support Volume Num Weighter</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/juno/support-volume-num-weighter.html</link><description>

&lt;p&gt;Include the URL of your launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/support-volume-num-weighter"&gt;https://blueprints.launchpad.net/cinder/+spec/support-volume-num-weighter&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Provide a mean to help improve volume-backends’ IO balance and volumes’ IO
performance.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently cinder support choosing volume backend according to free_capacity
and allocated_capacity.
Volume Num Weighter is that scheduler could choose volume backend based on
volume number in volume backend, which could provide another mean to help
improve volume-backends’ IO balance and volumes’ IO performance.&lt;/p&gt;
&lt;p&gt;Explain the benefit from volume number weighter by this use case.&lt;/p&gt;
&lt;p&gt;Assume we have volume-backend-A with 300G and volume-backend-B with 100G.
Volume-backend-A’s IO capabilities is the same volume-backend-B IO
capabilities.
Each volume’s IO usage are almost the same.
Use CapacityWeigher as weighter class.&lt;/p&gt;
&lt;p&gt;Concrete Use Case:
If we create six 10G volumes, these volumes would placed in volume-backend A.
All the six volume IO stream has been push on volume-backend-A, which would
cause volume-backend-A does much IO scheduling work. At the same time,
volume-backend-B has no volume and its IO capabilites has been wasted.&lt;/p&gt;
&lt;p&gt;If we have volume number weighter, scheduler could do proper initial placement
for these volumes—-three on volume-backend A, three on volume-backend-B. So
that we can make full use of all volume-backends’ IO capabilities to help
improve volume-backends’ IO balance and volumes’ IO performance.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Implement a volume number weighter:VolumeNumberWeighter.&lt;/dt&gt;&lt;dd&gt;&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;_weigh_object function return volume-backend’s non-deleted volume number by
using db api volume_get_all_by_host.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a new config item volume_num_weight_multiplier and its default value is
-1, which means to spread volume among volume backend according to
volume-backend’s non-deleted volume number.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Since VolumeNumberWeighter is mutually exclusive with
CapacityWeigher/AllocatedCapacityWeigher and cinder’s
scheduler_default_weighers is CapacityWeigher, we could set
scheduler_default_weighers=VolumeNumberWeighter in
/etc/cinder/cinder.conf and restart cinder-scheduler to make
VolumeNumberWeighter effect.&lt;/p&gt;
&lt;p&gt;VolumeNumberWeighter, whichi provides a mean to help improve
volume-backends’ IO balance and volumes’ IO performance,
could not replace CapacityWeigher/AllocatedCapacityWeigher,
because CapacityWeigher/AllocatedCapacityWeigher could be used to provide
balance of volume-backends’ free storage space when user focus more on free
space balance between volume-bakends.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;ling-yun&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Implement Volume Number Weighter&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add weighter option of Volume Number Weighter to OPENSTACK CONFIGURATION
REFERENCE&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Set up volume-backend-A with 300G and volume-backend-B with 100G.
Create six 10G volumes, the expected result is 3 volumes in
volume-backend A and 3 volumes in volume-backend B.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Add weighter option of Volume Number Weighter to OPENSTACK CONFIGURATION
REFERENCE.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Sun, 13 Aug 2017 00:00:00 </pubDate></item><item><title>XtremIO storage Cinder volume driver</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/juno/xtremio_cinder_volume_driver.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/xtremio-cinder-volume-driver"&gt;https://blueprints.launchpad.net/cinder/+spec/xtremio-cinder-volume-driver&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This is to enable OpenStack to work on top of XtremIO storage.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;This is a new Cinder driver that would enable Open Stack to work on top of
XtremIO storage.
The following diagram shows the command and data paths.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;+----------------+&lt;/span&gt;                 &lt;span class="o"&gt;+--------+---------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;Command&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;Path&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;Cinder&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;Nova&lt;/span&gt;          &lt;span class="o"&gt;+---------------&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;Cinder&lt;/span&gt; &lt;span class="n"&gt;Volume&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+-----+----------+&lt;/span&gt;                 &lt;span class="o"&gt;+--------+---------+&lt;/span&gt;
      &lt;span class="o"&gt;|&lt;/span&gt;                                     &lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="o"&gt;|&lt;/span&gt;                                     &lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="o"&gt;|&lt;/span&gt;                                     &lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="o"&gt;|&lt;/span&gt;                                     &lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="o"&gt;|&lt;/span&gt;                                     &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;+------------------+&lt;/span&gt;
      &lt;span class="o"&gt;|&lt;/span&gt;                                     &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt;
 &lt;span class="n"&gt;Command&lt;/span&gt;                                    &lt;span class="o"&gt;+--+&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt;
 &lt;span class="n"&gt;Path&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;                                        &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;XtremIO&lt;/span&gt; &lt;span class="n"&gt;Driver&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="o"&gt;|&lt;/span&gt;                                        &lt;span class="o"&gt;|&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="o"&gt;|&lt;/span&gt;                                        &lt;span class="o"&gt;|&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="o"&gt;|&lt;/span&gt;                                        &lt;span class="o"&gt;+------+-----------+&lt;/span&gt;
      &lt;span class="o"&gt;|&lt;/span&gt;                                               &lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="o"&gt;|&lt;/span&gt;                                               &lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="o"&gt;|&lt;/span&gt;                                               &lt;span class="o"&gt;+&lt;/span&gt;
      &lt;span class="o"&gt;|&lt;/span&gt;                                        &lt;span class="n"&gt;XtremIO&lt;/span&gt; &lt;span class="n"&gt;Rest&lt;/span&gt; &lt;span class="n"&gt;API&lt;/span&gt;
      &lt;span class="o"&gt;|&lt;/span&gt;                                               &lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;v&lt;/span&gt;                                               &lt;span class="o"&gt;|&lt;/span&gt;
                                                      &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+----------------+&lt;/span&gt;                                    &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;+-----------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;                                    &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;Compute&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;                                    &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;                                    &lt;span class="o"&gt;+----&amp;gt;&lt;/span&gt;    &lt;span class="n"&gt;XtremIO&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="n"&gt;Data&lt;/span&gt; &lt;span class="n"&gt;Link&lt;/span&gt;                     &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="n"&gt;storeage&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                &lt;span class="o"&gt;+-----------------------------------------+&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+----------------+&lt;/span&gt;                                         &lt;span class="o"&gt;+-----------------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;2 new volume drivers for iSCSI and FC should be developed, bridging Open stack
commands to XtremIO management system (XMS) using XMS Rest API.
The drivers should support the following Open stack actions:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Volume Create/Delete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Volume Attach/Detach&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Snapshot Create/Delete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create Volume from Snapshot&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Get Volume Stats&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Copy Image to Volume&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Copy Volume to Image&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Clone Volume&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Extend Volume&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;This feature will use native snapshot so the user can expect great speed up to
all snapshot/clone related actions.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;shay-halsband&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;None&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;Implement REST API client to XMS
Implement Logic for each functionality to support both iSCSI and FC&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Continuous integration as required for all drivers in the Juno timeframe&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Add documntation on how to install and use the drivers.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/developer/cinder/api/cinder.volume.driver.html?highlight=volume%20driver#module-cinder.volume.driver"&gt;http://docs.openstack.org/developer/cinder/api/cinder.volume.driver.html?highlight=volume%20driver#module-cinder.volume.driver&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;XtremIO REST API&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Sun, 13 Aug 2017 00:00:00 </pubDate></item><item><title>Add DB table for driver private data</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/kilo/driver-private-data.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/driver-private-data"&gt;https://blueprints.launchpad.net/cinder/+spec/driver-private-data&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As discussed at the mid-cycle meetup (&lt;a class="reference external" href="https://etherpad.openstack.org/p/cinder"&gt;https://etherpad.openstack.org/p/cinder&lt;/a&gt;-
meetup-winter-2015) we want to add a DB table where drivers can store info they
need to operate. A specific use case is for iSCSI CHAP credentials for
initiators, but it should be generic enough for other drivers to store data
they depend on too.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently there is not a standard solution for drivers to store information
they need to operate. For things volume related we have some “provider”
fields on the volume table that can be used, but for things not associated
with the volume’s life-cycle they are insufficient. This has lead to some
drivers storing information on the backend which works for some but not all
backends have this capability.&lt;/p&gt;
&lt;p&gt;A use case for this is storing target CHAP secrets so iSCSI initiators can
do CHAP authentication against targets.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;A solution for this problem is to have a new table in the Cinder database which
can hold initiator information for drivers. The model would look like:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;+--------------+--------------+--------------------------------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="n"&gt;Field&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="n"&gt;Type&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="n"&gt;Description&lt;/span&gt;                     &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+--------------+--------------+--------------------------------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;created_at&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;                                            &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;updated_at&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;                                            &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Auto&lt;/span&gt; &lt;span class="n"&gt;incremented&lt;/span&gt; &lt;span class="n"&gt;ID&lt;/span&gt;                        &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;initiator&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;varchar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Unique&lt;/span&gt; &lt;span class="n"&gt;constraint&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="s2"&gt;"key"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="s2"&gt;"namespace"&lt;/span&gt;                                &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;namespace&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;varchar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Unique&lt;/span&gt; &lt;span class="n"&gt;constraint&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="s2"&gt;"key"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;"initiator"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;This&lt;/span&gt; &lt;span class="n"&gt;comes&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;cinder.conf&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="n"&gt;back&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt; &lt;span class="n"&gt;configuration&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;                         &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;varchar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Unique&lt;/span&gt; &lt;span class="n"&gt;constraint&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="s2"&gt;"initiator"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="s2"&gt;"namespace"&lt;/span&gt;                                &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;varchar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;This&lt;/span&gt; &lt;span class="n"&gt;could&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;anything&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt; &lt;span class="n"&gt;wants&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;keep&lt;/span&gt; &lt;span class="n"&gt;track&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;this&lt;/span&gt; &lt;span class="n"&gt;initiator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;CHAP&lt;/span&gt; &lt;span class="n"&gt;credential&lt;/span&gt; &lt;span class="n"&gt;usecase&lt;/span&gt; &lt;span class="n"&gt;this&lt;/span&gt; &lt;span class="n"&gt;could&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;barbican&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;                         &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+--------------+--------------+--------------------------------------------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;In initialize_connection for VolumeManager if there is an initiator (in the
case of iSCSI) we can look up the rows for it filtering by the namespace
and pass them in to the driver as a new optional parameter for
initialize_connection.&lt;/p&gt;
&lt;p&gt;The namespace field will come from a new configuration option on the driver
base class called driver_data_namespace. This config option will default to
None. If this option is not set, we will check the backend_name config option,
and finally if that is not set, we fall back to the driver class name. This
will allow for being able to share data between multiple different backends
and a single backend in HA configuration.&lt;/p&gt;
&lt;p&gt;The driver then can return a model update dictionary as an “initiator_update”
field on the connection info. These changes will then be applied to the
initiator table.&lt;/p&gt;
&lt;p&gt;The initiator_update dictionary can contain “set_values” dictionary and/or
“remove_values” list. The set_values are key value pairs which are to
be set or updated in the database. The remove_values is a list of keys to be
deleted from the database. They will be “hard” deleted so the data will not
remain in the database once specified in remove_values.&lt;/p&gt;
&lt;p&gt;The return value from initialize_connection might look somthing like:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"driver_volume_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"iscsi"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"target_iqn"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"iqn.2010-06.com.purestorage:flasharray.12345abc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"target_portal"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;1.2.3.4&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;5678&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"target_lun"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"target_discovered"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"access_mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"rw"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"auth_method"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"CHAP"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"auth_username"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"someUserName"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"auth_password"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"somePassword"&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="s2"&gt;"initiator_updates"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"set_values"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s2"&gt;"purearray1ChapSecretId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"someUUID"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"someOtherThing"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"someOtherValue"&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="s2"&gt;"remove_values"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="s2"&gt;"myOldKey"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"anotherKey"&lt;/span&gt;
            &lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The manager’s initialize_connection method can then pull the updates
out of the return object, do the database operations (as needed) and
pass on the connection info with the field stripped out so it does not
propagate through the system.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;These key values pairs are scoped for the initiator, so there is a chance
for two different backends to get access to the values. This is helpful for
backends that are configured in active/active HA, but there is a risk of two
different vendors being used by the same initiator and having key
collisions. We could introduce a vendor-prefix field to use as part of the
key as well to avoid that.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;We could also use the cinder host to scope these instead of a vendor
prefix&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We could make drivers keep track of this outside of Cinder. This could be
left up to a driver backend to store data, or with another external database
somewhere. Some drawbacks to this approach include having different
databases to maintain, update, and keep in sync which would be a less than
desirable user experience for a cloud admin, having multiple ways of doing
synchronization/locking in drivers can and will introduce bugs and
maintenance problems, and makes it more difficult for new driver developers
to make a good choice on where to store data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We could allow the drivers direct(ish) access to the database through some
get/set api’s to store arbitrary key-value pairs. Some alternatives for the
database table in that model include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Have a column for the host name and using it as part of the unique
constraint for the “key”. The benefit being that it is much less likely to
have naming collisions between drivers using this. The downside is that two
hosts using the same driver may not be able to easily share data, which
makes active/active HA for the same backend difficult.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Have a column for the driver class name and using it as part of the unique
constraint for the “key”. Again the benefit being to help avoid collisions
with key fields. This one is better for sharing between hosts that are
using the same driver type, but the issue then is where does the name come
from? If it is reported by the driver as a string it might as well be any
generic prefix as there is nothing to stop someone from just making up
their name. If it is automatically gathered from the driver class via
python internal variables on the object then there are issues with any
driver that changes their class name later on.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Have a column that is just a provider/vendor namespace and is part of the
unique constraint for the “key”. Yet again the goal is to avoid collisions
with key fields. Similar to the last one the only downside is where it
comes from and that there isn’t really anything that would prevent drivers
from using the same one, but it would be one more layer of protection.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Have no restriction and let the keys be more like a global scope, this
allows drivers to share data easily, but has issues with collisions.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Return a tuple instead of adding the data to the return object of
initialize_connection. This requires having an optional second return
value and conditional calling/return values for methods, or modifying
every usage of driver.initialize_connection(…).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;The proposed solution will be adding in a new database table named
driver_initiator_data and associated model DriverInitiatorData. There will be
a migration to add and remove the table but will not seed or modify any data.&lt;/p&gt;
&lt;p&gt;Access to the database will be used through api’s outlined in the Proposed
Change.&lt;/p&gt;
&lt;p&gt;Table rows will be hard deleted, so we don’t keep around potentially sensitive
credentials/information.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Potential impact for drivers that heavily utilize this table with extra
database queries.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;New config option to potentially set for each backend.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Drivers that store data on their backend may want to utilize this feature.&lt;/p&gt;
&lt;p&gt;This change will require modifying the signature for all drivers
initialize_connection method implementations.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;patrick-east&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;None&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Interested parties:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;walter-boring&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add new Model&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add new db API’s&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add new db Migration scripts&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify the volume manager’s initialize_connection method to query/save data&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;DB migration tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DB API tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;BaseDriver unit tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No new tempest tests&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://etherpad.openstack.org/p/cinder-meetup-winter-2015"&gt;https://etherpad.openstack.org/p/cinder-meetup-winter-2015&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/151837/"&gt;https://review.openstack.org/#/c/151837/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Sun, 13 Aug 2017 00:00:00 </pubDate></item><item><title>Support for incremental backup in Cinder</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/kilo/incremental-backup.html</link><description>

&lt;dl class="simple"&gt;
&lt;dt&gt;Launchpad Blueprint:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/incremental-backup"&gt;https://blueprints.launchpad.net/cinder/+spec/incremental-backup&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;The current implementation of Cinder Backup functionality only supports full
backup and restore of a given volume. There is no provision to backup changes
only that happened since last backup. As the volumes grow bigger and over,
all changes to volumes between backups stay relatively small, copying
entire volumes during backups will be resource intensive and do not scale well
for larger deployments. This specification discusses implementation of
incremental backup feature in detail.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Cinder backup API, by default uses Swift as its backend. When a volume is
backed up to Swift, Swift creates a manifest file that describes the contents
of the backup volume. The manifest file contains header (metadata) and array
of pointers to the volume backup files. Since Swift has an upper limit on the
object size, Cinder backup API splits the volume data into individual chunks
of Swift object size and uploads these individual chunks to Swift. Cinder
volume backup manifest file includes these list of objects, their corresponding
objects, the logical offset of each object within the volume and a message
digest of each chunk to detect any unwarranted changes to objects. During
restore operation, Cinder reconstructs the volume based on the manifest and
individual chunks referenced in the manifest.&lt;/p&gt;
&lt;p&gt;To support incremental backup functionality, we introduce another object called
shafile to the list of backup files. shafile file helps track changes to the
volume since last backup. This new object holds SHA256s of the
volume. A brief description of SHA-2 or SHA256 can be found at
&lt;a class="reference external" href="http://en.wikipedia.org/wiki/SHA-2"&gt;http://en.wikipedia.org/wiki/SHA-2&lt;/a&gt;. The backup manifest file will have a
reference to this object. During a full backup operation, Cinder divides up the
volume into fixed blocks of user configurable block size. It calculates SHA256
of each block and compiles a list of SHAs and uploads the shafile to the backup
container.&lt;/p&gt;
&lt;p&gt;To keep the incremental backup implementation simple, an incremental operation
is only performed with respect to a full backup. During incremental backup,
cinder reads the shafile of the full backup. It creates a new shafile from
the current volume data and compares the new shafile with full backup shafile
to calculate the blocks that are changed since last full backup.&lt;/p&gt;
&lt;p&gt;We will use existing manifest mechanism to capture the delta. Since
full backups do not contain any holes, offset+lengths of each chunk of
the volume describe the full length of the volume logical address. However
with incremental backup, this model is challenged and the offset/chunk of
individual files become sparse. The absence of offset/length in a manifest
represents the data that is not modified since last backup. One potential
drawback of this approach is if changes to volume are fragmented, incremental
backup may result in too many objects in Swift. However object stores
like Swift are built to handle many small objects effectively.&lt;/p&gt;
&lt;p&gt;The new shafile is uploaded as part of the incremental backup.&lt;/p&gt;
&lt;p&gt;The manifest header identifies this backup as incremental backup and hence
contains a reference to the full backup container.&lt;/p&gt;
&lt;p&gt;Following changes are made to the manifest header of the backup&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'version'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DRIVER_VERSION&lt;/span&gt;
&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'backup_id'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;backup&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'volume_id'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;volume_id&lt;/span&gt;
&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'backup_name'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;backup&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'display_name'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'backup_description'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;backup&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'display_description'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'created_at'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;backup&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'created_at'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="c1"&gt;# Changes to metadata section of manifest&lt;/span&gt;
&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'shafile'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;shafilename&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;  &lt;span class="c1"&gt;# Path to shafile name. Or&lt;/span&gt;
                                     &lt;span class="c1"&gt;# can be hardcoded to "shafile"&lt;/span&gt;
                                     &lt;span class="c1"&gt;# in the container&lt;/span&gt;

&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'backup_type'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"incrementa/full"&lt;/span&gt; &lt;span class="c1"&gt;# backup type&lt;/span&gt;
&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'full_container'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;object&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="c1"&gt;# path of full backup&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Restore API is not expected to change, however restore implementation will be
changed to handle incremental backup. To keep the restore from incremental
backup simple and easy to test, the restore operation first performs restore
of the full volume from the full backup copy and then apply incremental
changes at offset and length as described in the incremental backup manifest.&lt;/p&gt;
&lt;p&gt;Snapshot based backups:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Since&lt;/span&gt; &lt;span class="n"&gt;existing&lt;/span&gt; &lt;span class="n"&gt;backup&lt;/span&gt; &lt;span class="n"&gt;implementation&lt;/span&gt; &lt;span class="n"&gt;copies&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="n"&gt;directly&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;the&lt;/span&gt; &lt;span class="n"&gt;volume&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="n"&gt;requires&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;volume&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;detached&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;the&lt;/span&gt; &lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;For&lt;/span&gt; &lt;span class="n"&gt;most&lt;/span&gt; &lt;span class="n"&gt;cloud&lt;/span&gt;
&lt;span class="n"&gt;workloads&lt;/span&gt; &lt;span class="n"&gt;this&lt;/span&gt; &lt;span class="n"&gt;may&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;sufficient&lt;/span&gt; &lt;span class="n"&gt;but&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt; &lt;span class="n"&gt;workloads&lt;/span&gt; &lt;span class="n"&gt;that&lt;/span&gt; &lt;span class="n"&gt;cannot&lt;/span&gt; &lt;span class="n"&gt;tolerate&lt;/span&gt;
&lt;span class="n"&gt;prolonged&lt;/span&gt; &lt;span class="n"&gt;downtimes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;snapshot&lt;/span&gt; &lt;span class="n"&gt;based&lt;/span&gt; &lt;span class="n"&gt;backup&lt;/span&gt; &lt;span class="n"&gt;solution&lt;/span&gt; &lt;span class="n"&gt;can&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;viable&lt;/span&gt;
&lt;span class="n"&gt;alternative&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;Snapshot&lt;/span&gt; &lt;span class="n"&gt;based&lt;/span&gt; &lt;span class="n"&gt;backup&lt;/span&gt; &lt;span class="n"&gt;will&lt;/span&gt; &lt;span class="n"&gt;perform&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt; &lt;span class="n"&gt;copy&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt;
&lt;span class="n"&gt;volume&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;backup&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;point&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt; &lt;span class="n"&gt;copy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;This&lt;/span&gt; &lt;span class="n"&gt;approach&lt;/span&gt; &lt;span class="n"&gt;does&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt;
&lt;span class="n"&gt;require&lt;/span&gt; &lt;span class="n"&gt;volume&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;detached&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;the&lt;/span&gt; &lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;Rest&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;backup&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt;
&lt;span class="n"&gt;restore&lt;/span&gt; &lt;span class="n"&gt;functionality&lt;/span&gt; &lt;span class="n"&gt;remain&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;same&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;

&lt;span class="n"&gt;As&lt;/span&gt; &lt;span class="n"&gt;an&lt;/span&gt; &lt;span class="n"&gt;alternative&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;snapshot&lt;/span&gt; &lt;span class="n"&gt;based&lt;/span&gt; &lt;span class="n"&gt;backup&lt;/span&gt; &lt;span class="n"&gt;can&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;implemented&lt;/span&gt; &lt;span class="n"&gt;by&lt;/span&gt; &lt;span class="n"&gt;extending&lt;/span&gt;
&lt;span class="n"&gt;existing&lt;/span&gt; &lt;span class="n"&gt;backup&lt;/span&gt; &lt;span class="n"&gt;functionality&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;snapshot&lt;/span&gt; &lt;span class="n"&gt;volumes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;This&lt;/span&gt; &lt;span class="n"&gt;approach&lt;/span&gt; &lt;span class="n"&gt;can&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;lot&lt;/span&gt;
&lt;span class="n"&gt;more&lt;/span&gt; &lt;span class="n"&gt;simpler&lt;/span&gt; &lt;span class="n"&gt;than&lt;/span&gt; &lt;span class="n"&gt;backup&lt;/span&gt; &lt;span class="n"&gt;API&lt;/span&gt; &lt;span class="n"&gt;taking&lt;/span&gt; &lt;span class="n"&gt;snapshot&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;volume&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;then&lt;/span&gt; &lt;span class="n"&gt;managing&lt;/span&gt;
&lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;snapshots&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Incremental backup offers two important benefits:&lt;/dt&gt;&lt;dd&gt;&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Use less storage when storing backup images&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use less network bandwidth and improve overall efficiency of backup process
in terms of CPU and time utilization&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;The first benefit can be achieved as a post processing of the backup images to
remove duplication or by using dedupe enabled backup storage. However the
second benefit cannot be achieved unless Cinder backup supports incremental
backup.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;No perceived data model changes&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;No new APIs are proposed. Instead existing backup API will be enhanced to
accept additional option called “–incr” with &amp;lt;path to full backup container&amp;gt;”
as its argument.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;cinder&lt;/span&gt; &lt;span class="n"&gt;backup&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;volumeid&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;incr&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;full&lt;/span&gt; &lt;span class="n"&gt;backup&lt;/span&gt; &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="n"&gt;Performs&lt;/span&gt; &lt;span class="n"&gt;incremental&lt;/span&gt; &lt;span class="n"&gt;backup&lt;/span&gt;

&lt;span class="n"&gt;cinder&lt;/span&gt; &lt;span class="n"&gt;backup&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;volumeid&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;snapshot&lt;/span&gt;
  &lt;span class="n"&gt;Optionally&lt;/span&gt; &lt;span class="n"&gt;backup&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;will&lt;/span&gt; &lt;span class="n"&gt;backup&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;snapshot&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;volume&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;Snapshot&lt;/span&gt;
  &lt;span class="n"&gt;based&lt;/span&gt; &lt;span class="n"&gt;backups&lt;/span&gt; &lt;span class="n"&gt;can&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;performed&lt;/span&gt; &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;volume&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="n"&gt;still&lt;/span&gt; &lt;span class="n"&gt;attached&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt;
  &lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;

&lt;span class="n"&gt;cinder&lt;/span&gt; &lt;span class="n"&gt;backup&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;volumeid&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;snapshot&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;incr&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;full&lt;/span&gt; &lt;span class="n"&gt;backup&lt;/span&gt; &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="n"&gt;Optionally&lt;/span&gt; &lt;span class="n"&gt;backup&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;will&lt;/span&gt; &lt;span class="n"&gt;perform&lt;/span&gt; &lt;span class="n"&gt;incremental&lt;/span&gt; &lt;span class="n"&gt;backup&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;volume&lt;/span&gt;
  &lt;span class="n"&gt;snapshot&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;No anticipated changes to restore api&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;python-cinderclient will be modified to accept “–incr” option. It may
include some validation code to validate if the full backup container path
is valid&lt;/p&gt;
&lt;p&gt;Currently backup functionality is not integrated with OpenStack dashboard. When
it happens, the dashboard will provide an option for user to choose incremental
backup&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Except for calculating SHAs during full backup operation, there is no other
performance impact on existing API. The performance penalty can be easily
offset by the efficiency gained by incremental backup. Also new hardware
support CPU instructions to calculate SHAs which alleviates some stress on
the CPU cycles.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Primary assignee:
muralibalcha(&lt;a class="reference external" href="mailto:murali.balcha%40triliodata.com"&gt;murali&lt;span&gt;.&lt;/span&gt;balcha&lt;span&gt;@&lt;/span&gt;triliodata&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;Other contributors:
giribasava(&lt;a class="reference external" href="mailto:giri.basava%40triliodata.com"&gt;giri&lt;span&gt;.&lt;/span&gt;basava&lt;span&gt;@&lt;/span&gt;triliodata&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;)&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;python-cinderclient
That accepts “–incr” option and some validation code&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;cinder/api
Which parses the “–incr” option&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;cinder/backup/api.py
backup api signature is modified&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;cinder/backup/manager.py&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;cinder/backup/driver/swift.py
Heavy lifting is done here.
Both backup and restore apis will be modified.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit tests will be added for incremental backup.&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;Testing will primarily focus on the following:&lt;/dt&gt;&lt;dd&gt;&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;SHA file generation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Creating various changes to the original volume. These include&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Changes to first block&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Changes to last block&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Changes to odd number of successive blocks&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Changes to even number of successive blocks&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Changes spread across multiple sections of the volume&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;ol class="arabic simple" start="3"&gt;
&lt;li&gt;&lt;p&gt;Perform 1 incremental&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Peform multiple incremental backups&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Restore series of incremental backups and compare the contents&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Perform full backup, then incremental, then full and then incremenal
restore the volume from various backups.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Need to document new option in the block storage manual.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Sun, 13 Aug 2017 00:00:00 </pubDate></item><item><title>Over Subscription in Thin Provisioning</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/kilo/over-subscription-in-thin-provisioning.html</link><description>

&lt;p&gt;Include the URL of your launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/over-subscription-in-thin-provisioning"&gt;https://blueprints.launchpad.net/cinder/+spec/over-subscription-in-thin-provisioning&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This proposal is to introduce a mechanism to allow over subscription in thin
provisioning and also use reserved percentage to prevent over provisioning.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;There are a couple of problems in capacity reporting in thin provisioning:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Some drivers are still using ‘infinite’ and ‘unknown’ to report capacity.
This could lead to over provisioning.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There’s no mechanism to allow over subscription in thin provisioning.
Over subscription allows flexibility in storage allocation and usage and
it is an important concept in providing thin provisioning support.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="terminologies"&gt;
&lt;h3&gt;Terminologies&lt;/h3&gt;
&lt;p&gt;The following terminologies will be used in this spec:&lt;/p&gt;
&lt;p&gt;total_capacity: This is an existing parameter already reported by the driver.
It is the total physical capacity.
Example: Assume backend A has a total physical capacity of 100G.&lt;/p&gt;
&lt;p&gt;free_capacity: This is an existing parameter already reported by the
driver. It is the real physical capacity available to be used.
Example: Assume backend A has a total physical capacity of 100G.
There are 10G thick luns and 20G thin luns (10G out of the 20G thin luns
are written). In this case, free_capacity = 100 - 10 -10 = 80G.&lt;/p&gt;
&lt;p&gt;free: This is calculated in the scheduler by subtracting reserved space
from free_capacity.&lt;/p&gt;
&lt;p&gt;volume_size: This is an existing parameter. It is the size of the volume to
be provisioned.&lt;/p&gt;
&lt;p&gt;provisioned_capacity: This is a new parameter. It is the apparent allocated
space indicating how much capacity has been provisioned.
Example: User A created 2x10G volumes in Cinder from backend A, and
user B created 3x10G volumes from backend A directly, without using Cinder.
Assume those are all the volumes provisioned on backend A. The total
provisioned_capacity will be 50G and that is what the driver should be
reporting.&lt;/p&gt;
&lt;p&gt;allocated_capacity: This is an existing parameter. Cinder uses this to
keep track of how much capacity has been allocated through Cinder.
Example: Using the same example above for provisioned_capacity, the
allocated_capacity will be 20G because that is what has been provisioned
through Cinder. allocated_capacity is documented here to differentiate
from the new parameter provisioned_capacity. If a driver can guarantee
that the backend is used solely for a specific Cinder installation,
then provisioned_capacity could be the same as allocated_capacity.
Only driver has knowledge of this and therefore driver can make a
decision on how to report provisioned_capacity.&lt;/p&gt;
&lt;p&gt;max_over_subscription_ratio: This is a new parameter. It is the
float representation of the over subscription ratio when thin provisioning
is involved. It is a ratio of provisioned capacity over total capacity.
Default ratio is 1.0, meaning provisioned capacity cannot exceed the
total capacity. Note that this ratio is per backend or per pool depending
on driver implementation.&lt;/p&gt;
&lt;p&gt;reserved_percentage: This is an existing parameter. It represents the
percentage of backend capacity that is reserved. It ranges from 0 to 100.
Default is 0. Note this refers to the real capacity. This is per backend
or per pool depending on driver implementation.&lt;/p&gt;
&lt;p&gt;reserved: This is a ratio of reserved_percentage over 100 calculated by the
scheduler.&lt;/p&gt;
&lt;p&gt;virtual_free_capacity: This is a parameter calculated based on other
parameters. It refers to how much space a user can still provision apparently.
Note that this is different from free_capacity. free_capacity is
about the real available physical capacity. virtual_free_capacity is
about apparent available virtual capacity.
Example: Assume the total capacity of backend A is 100G. The max over
subscription ratio is 2.0. If no volumes have been provisioned yet,
the virtual_free_capacity is 100 x 2.0 = 200. If 50G volumes have
already been provisioned, the virtual_free_capacity is 200 - 50 = 150.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;section id="new-parameters-in-get-volume-stats"&gt;
&lt;h3&gt;New parameters in get_volume_stats&lt;/h3&gt;
&lt;p&gt;One new configuration options “max_over_subscription_ratio” will be added
to cinder/volume/driver.py. This configuration option will be added to
cinder.conf. It can be configured for each backend when multiple-backend
is enabled.&lt;/p&gt;
&lt;p&gt;Note: This configuration option is provided as a reference implementation
and will be used by the LVM driver. However, it is not a requirement for a
driver to use this option from cinder.conf. Driver can choose its own way
if that makes more sense.&lt;/p&gt;
&lt;p&gt;In scheduler/host_manager.py, the following additional information sent by
each backend will be saved and will be used later by the scheduler to make
decisions. Note these are reported for a backend or a pool, depending on
driver implementation. In the LVM driver, these will be reported for a
backend (which is treated as one pool).&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;provisioned_capacity&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;max_over_subscription_ratio&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There is a change on how reserved_percentage is used. It was measured
against free capacity in the past. Now it will be measured against
total capacity.&lt;/p&gt;
&lt;p&gt;Note: The configuration option max_over_subscription_ratio added in
cinder.conf is for configuring a backend.
For a driver that supports multiple pools per backend, it can report
these ratios for each pool in get_volume_stats.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Driver can get this option in cinder.conf and report the same ratio
for the pools that belonging to the same backend.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Alternatively driver can choose to report different ratio for each pool
in get_volume_stats, without using this option in cinder.conf.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="capabilities"&gt;
&lt;h3&gt;Capabilities&lt;/h3&gt;
&lt;p&gt;Driver can report the following capabilities for a backend or a pool:&lt;/p&gt;
&lt;p&gt;thin_provisioning_support = True (or False)
thick_provisioning_support = True (or False)&lt;/p&gt;
&lt;p&gt;Two capabilities are added here to allow a backend or pool to claim support
for thin provisioning, or thick provisioning, or both.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="volume-type-extra-specs"&gt;
&lt;h3&gt;Volume type extra specs&lt;/h3&gt;
&lt;p&gt;If volume type is provided as part of the volume creation request, it can
have the following extra specs defined:&lt;/p&gt;
&lt;p&gt;‘capabilities:thin_provisioning_support’: ‘&amp;lt;is&amp;gt; True’ or ‘&amp;lt;is&amp;gt; False’
‘capabilities:thick_provisioning_support’: ‘&amp;lt;is&amp;gt; True’ or ‘&amp;lt;is&amp;gt; False’&lt;/p&gt;
&lt;p&gt;Note: ‘capabilities’ scope key before ‘thin_provisioning_support’ and
‘thick_provisioning_support’ is not required. So the following works too:&lt;/p&gt;
&lt;p&gt;‘thin_provisioning_support’: ‘&amp;lt;is&amp;gt; True’ or ‘&amp;lt;is&amp;gt; False’
‘thick_provisioning_support’: ‘&amp;lt;is&amp;gt; True’ or ‘&amp;lt;is&amp;gt; False’&lt;/p&gt;
&lt;p&gt;The above extra specs are used by the scheduler to find a backend that
supports thin provisioning, thick provisioning, or both to match the needs
of a specific volume type.&lt;/p&gt;
&lt;p&gt;If an extra spec scope key “provisioning:type” is defined, it can be used
by the driver to detemine whether the lun to be provisioned is thin or thick.
The value of this extra spec is either “thin” or “thick”. Note this extra
spec is not used by the scheduler to find a backend.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="capacity-filter"&gt;
&lt;h3&gt;Capacity filter&lt;/h3&gt;
&lt;p&gt;In the capacity filter, the following will be evaluated in the decision making
when choosing a backend that fits the criteria:&lt;/p&gt;
&lt;p&gt;If (provisioned_capacity + volume_size) / total_capacity &amp;gt;=
max_over_subscription_ratio, the backend will not be chosen to provision
the volume.
Note: This formula will be executed only if “thin_provisioning_support”
is True and max_over_subscription_ratio &amp;gt;= 1.&lt;/p&gt;
&lt;p&gt;If ((free_capacity - total_capacity * reserved) * max_over_subscription_ratio)
&amp;lt; volume_size, the backend will not be chosen to provision the volume.
Note: This formula will be executed only if “thin_provisioning_support”
is True and max_over_subscription_ratio &amp;gt;= 1.&lt;/p&gt;
&lt;p&gt;If (free_capacity - total_capacity * reserved) &amp;lt; volume_size, the backend will
not be chosen to provision the volume. Note this check was already in the
capacity filter, but the formula is changed to use total_capacity * reserved
instead of free_capacity * reserved.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="capacity-weigher"&gt;
&lt;h3&gt;Capacity weigher&lt;/h3&gt;
&lt;p&gt;In the capacity weigher, virtual_free_capacity should be used for ranking
if “thin_provisioning_support” is True. Otherwise, real free_capacity
will be used as before. A change is made to measured reserved space
against the total_capacity.
virtual_free_capacity = total_capacity * max_over_subscription_ratio -
provisioned_capacity - total_capacity * reserved&lt;/p&gt;
&lt;/section&gt;
&lt;section id="lvm-driver"&gt;
&lt;h3&gt;LVM driver&lt;/h3&gt;
&lt;p&gt;In the default LVM driver, changes will be made in get_volume_stats which
periodically reports capabilities and the information will be received by the
scheduler.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Changes will be made in the LVM driver to report provisioned_capacity.
It makes calls to the LVM class in brick to retrieve volume information
including capacities.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The LVM driver will also report max_over_subscription_ratio. This will be
from the configuration parameters set in cinder.conf.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;While other drivers need to report max_over_subscription_ratio, they are
not required to read those ratios from cinder.conf.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Changes will also be made in the following LVM driver functions to make sure
over provisioning will not happen even when a request didn’t go through the
scheduler:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;create_volume&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;extend_volume&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The following will be evaluated in the above LVM driver functions:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;If the ratio of the apparent provisioned capacity over real total capacity
has exceeded the over subscription ratio, the operation will fail.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If the free space is smaller than the volume size, the operation will fail.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="id1"&gt;
&lt;h3&gt;Use cases&lt;/h3&gt;
&lt;p&gt;The design of this feature will support the following use cases.&lt;/p&gt;
&lt;p&gt;Use case 1:
Each volume type has a separate backend or pool. For example, Gold volume
type uses pool gold, Silver volume type uses pool silver, and Bronze
volume type uses pool bronze. Each pool can have a different max over
subscription ratio.&lt;/p&gt;
&lt;p&gt;Use case 2:
One volume type is associated with multiple backends or pools. For example,
Silver volume type uses pool 1 and pool 2. Both pools can have the same
max over subscription ratio. Note that capacities for each pool can be
different at any given time.&lt;/p&gt;
&lt;p&gt;Use case 3:
One backend or pool is used by multiple volume types. For example, pool 3
is used by volume types Gold, Silver, and Bronze. Assume Gold volume type
uses thick luns only, Silver volume type can have either thick or thin
luns, and Bronze volume type has thin luns only. Because the over subscription
ratio is calculated by the ratio of provisioned_capacity over total_capacity
and all three volume types are sharing the same pool, the ratio will be
the same for all volume types. Gold volume type can guarantee its space
reservation by creating thick luns. The apparent size and the used size
of a Gold volume will always be the same. For a thin lun created as
Silver or Bronze volume type, the apparent size can be bigger than
the real size. Some detailed examples are shown at this etherpad:
&lt;a class="reference external" href="https://etherpad.openstack.org/p/cinder-over-subscription-white-board"&gt;https://etherpad.openstack.org/p/cinder-over-subscription-white-board&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Without this, we cannot support over subscription in thin provisioning and
there’s also no upper limit that prevents over provisioning from happening.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;If the capacity usage has exceeded the used ratio or if the provisioned
capacity has exceeded the over subscription ratio, a notification should be
sent. The notification should report the name of the backend or pool and the
capacity information from the backend or pool.  The purpose of the
notification is for the storage administrator to take notice and take actions
to fix the problem.&lt;/p&gt;
&lt;p&gt;Notification will also be sent periodically whenever the scheduler receives
an update of capacities from the backend. This will be consumed by Ceilometer.
This was discussed for the Capacity Headroom topic at the summit. The
Ceilometer team will be responsible for the changes required on the Ceilometer
side for this.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;There is a new parameter in cinder.conf that end user needs to be aware of.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;New parameters over_subscription_ratio will be added to cinder.conf.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Drivers should report provisioning capabilities (thin_provisioning_support
and thick_provisioning_support).&lt;/p&gt;
&lt;p&gt;Drivers supporting thin provisioning should report provisioned capacity
in addition to free capacity in get_volume_stats.&lt;/p&gt;
&lt;p&gt;For drivers supporting thick provisioning only, free capacity will be
used just as before.&lt;/p&gt;
&lt;p&gt;For drivers supporting both thin and thick provisioning, provisioned capacity
and free capacity should both be reported.&lt;/p&gt;
&lt;p&gt;If there is a range regarding capacity and you are not sure how to report,
please be conservative. For example, if the available capacity is in the
range of 80 to 100 GB, be conservative and report the lower bound 80 GB.&lt;/p&gt;
&lt;p&gt;Driver developers can take a look of _update_volume_stats in the LVM driver
as a reference implementation.&lt;/p&gt;
&lt;p&gt;Note: This work is also needed for Cinder to use ThinLVM as the default driver
in Kilo.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;xing-yang&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Other contributors:&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Add max_over_subscription_ratio in driver.py.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify host_manager.py to update provisioned capacity, over
subscription ratio by the backends.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify capacity filter to check whether over subscription ratio
has been exceeded in a backend.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;New parameters max_over_subscription_ratio will be added to cinder.conf.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;LVM driver will be changed to report virtual capacity and over
subscrption ratio.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;LVM class in brick will be updated to calculate provisioned capacity.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;LVM driver functions will be changed to check whether over
subscription ratio has been exceeded.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;New unit tests will be added to test the changed code.
Testing will be done using the LVM driver for thin provisioning.
Testing will be done to cover the 3 use cases described above.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Documentation changes are needed for the following:
New parameter max_over_subscription_ratio will be added to cinder.conf.
Driver needs to add provisioning capabilities (thick_provisioning_suppot,
thin_provisioning_support) and report provisioned_capacity.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;Examples:
&lt;a class="reference external" href="https://etherpad.openstack.org/p/cinder-over-subscription-white-board"&gt;https://etherpad.openstack.org/p/cinder-over-subscription-white-board&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Virtual capacity “provisioned_capacity_gb” was discussed in Winston’s spec
&lt;a class="reference external" href="https://review.openstack.org/#/c/105190/6/specs/juno/volume-statistics-reporting.rst"&gt;https://review.openstack.org/#/c/105190/6/specs/juno/volume-statistics-reporting.rst&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Kilo design summit session on this topic:
&lt;a class="reference external" href="https://etherpad.openstack.org/p/kilo-cinder-over-subscription"&gt;https://etherpad.openstack.org/p/kilo-cinder-over-subscription&lt;/a&gt;
&lt;a class="reference external" href="https://etherpad.openstack.org/p/kilo-cinder-capacity-headroom"&gt;https://etherpad.openstack.org/p/kilo-cinder-capacity-headroom&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Documentation on the filter scheduler:
&lt;a class="reference external" href="http://docs.openstack.org/developer/nova/devref/filter_scheduler.html"&gt;http://docs.openstack.org/developer/nova/devref/filter_scheduler.html&lt;/a&gt;
Note: This is a document on Nova filter scheduler, but it is very similar to
the Cinder filter scheduler.&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Sun, 13 Aug 2017 00:00:00 </pubDate></item><item><title>RemoteFS Config Improvements</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/kilo/remotefs-cfg-improvements.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/remotefs-share-cfg-improvements"&gt;https://blueprints.launchpad.net/cinder/+spec/remotefs-share-cfg-improvements&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;RemoteFS drivers (NFS, GlusterFS, etc.) are currently configured by adding
a list of shares to a text config file which is referenced by cinder.conf.
This means that one driver instance manages a handful of storage locations
for the driver.  This work will a) have these drivers configured like most
other Cinder drivers are, and b) leverage the Cinder scheduler for selection
between different storage backends rather than having the driver act as a
pseudo-scheduler.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;The configuration system for NFS/GlusterFS/etc drivers:&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;is different from other drivers&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;is more complex than necessary&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;limits functionality such as migration&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Replace the &amp;lt;x&amp;gt;_shares_config setting with settings that can be used to login
to the storage platforms.  This means that an nfs_shares_config file such as:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="mf"&gt;192.168.1.10&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;export1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="n"&gt;sync&lt;/span&gt;
&lt;span class="mf"&gt;192.168.1.11&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;export2&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="n"&gt;vers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;nfs4&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;would become, in cinder.conf:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;nfs1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;address&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;192.168.1.10&lt;/span&gt;
&lt;span class="n"&gt;export_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;export1&lt;/span&gt;
&lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="n"&gt;sync&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;nfs2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;address&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;192.168.1.11&lt;/span&gt;
&lt;span class="n"&gt;export_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;export2&lt;/span&gt;
&lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="n"&gt;vers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;nfs4&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Each Cinder backend will then only manage one export rather than a handful of
exports.  This brings the RemoteFS drivers closer to how other Cinder
drivers operate.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Leave things as they are today.  (Not desirable.)&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;It will be possible to use Cinder volume migration to move volumes between
all NFS exports when previously this was not always possible (since the
different exports were managed by the same driver instance).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;nfs_shares_config, glusterfs_shares_config, etc., will be deprecated
(but still functional for Kilo).   Setting the new options will cause
these settings to be ignored.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;eharney&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Other interested parties?&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create new options for address, export, mount options&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Mark options and code to be removed in L as deprecated in Kilo&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;The NFS driver and GlusterFS drivers will be gaining CI during the Kilo
cycle which will cover this.&lt;/p&gt;
&lt;p&gt;Manual testing should cover both the current and new configuration paths.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;New configuration options and possibly guide changes for configuring the NFS
driver.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Sun, 13 Aug 2017 00:00:00 </pubDate></item><item><title>Backup Snapshots</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/mitaka/backup-snapshots.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/backup-snapshots"&gt;https://blueprints.launchpad.net/cinder/+spec/backup-snapshots&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Currently we can backup a volume, but not a snapshot. This spec proposes to
provide a way to backup snapshots.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Today we can backup a volume, but we cannot directly backup a snapshot. The
ability to backup a volume directly is valuable because it allows a volume to
be backed up in one step. Also volume backup has been available ever since
backup was introduced in Cinder. Users also take snapshots from the volumes as
a way to protect their data. These snapshots reside on the storage backend
itself. Providing a way to backup snapshots directly will allow the user to
protect the snapshots taken from the volumes on a backup device, separately
from the storage backend.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;There are users who have taken many snapshots and would like a way to protect
these snapshots. This proposal to backup snapshots provides another layer of
data protection.&lt;/p&gt;
&lt;p&gt;There are other projects in OpenStack focusing on data protection such as
Freezer, Smaug, Raksha, etc. They are all in different stages of design,
development, or adoption. The backup API in Cinder is not a replacement of
those projects which are doing a full blown orchestration of data protection
for all resources in OpenStack (not just block storage). Instead, Cinder APIs
can be consumed by those higher level projects for data protection and can
also be used directly by users who do not need those higher level projects.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;In summary, the following changes will happen:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;A field &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;snapshot_id&lt;/span&gt;&lt;/code&gt; will be added to the request body of the existing
backup API.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A new column &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;snapshot_id&lt;/span&gt;&lt;/code&gt; will be added to the backups table.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The backup_volume logic in driver.py and lvm.py will be changed to use the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;snapshot_id&lt;/span&gt;&lt;/code&gt; if it is not None.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The logic to find the latest parent during the incremental backup will be
adjusted to take into account backups from snapshots.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Note: No new driver API will be introduced in this proposal.&lt;/p&gt;
&lt;p&gt;Steps to create a backup from snapshot are as follows by default using the
internal tenant:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create a temporary volume from the snapshot&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Attach the temporary volume&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Do backup from the temporary volume&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Detach the temporary volume&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cleanup temporary volume&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If the driver has implemented the attach snapshot interface introduced in the
Liberty release (see the developer impact section), backing up a snapshot will
be done using the following steps:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Attach the snapshot&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Do backup from the snapshot&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Detach the snapshot&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For incremental backups, because the latest parent is calculated automatically
by looking at the timestamps, the logic has to be changed to accommodate
backups from snapshots. For backups from snapshots, we need to look at the
timestamps of the snapshots; for backups from volumes, we still look at the
timestamps of the backups as before. The parent of an incremental backup of a
snapshot could be a backup from a previous snapshot or a backup from the
volume, depending on the timestamps when the previous snapshot was taken vs
when the volume backup was taken. The backup with the latest timestamp will be
chosen as the parent. A new column will be created to record the timestamp of
the data in the backups table. For a backup from volume, the data timestamp
field will be the same as the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;created_at&lt;/span&gt;&lt;/code&gt; field in the backups table. For a
backup from snapshot, the data timestamp field will be the same as the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;created_at&lt;/span&gt;&lt;/code&gt; field of the snapshot.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Here is a manual alternative:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create a volume from the snapshot&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Backup the volume&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete the volume&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;Add the following new column to the backups table for snapshot id. This field
will be null if the backup is from a volume:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;snapshot_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Add the following new column to the backups table to record the timestamp of
the data:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;data_timestamp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Note that the following column will still be required for a backup from
snapshot:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;volume_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;Change the existing create backup API to take a snapshot id. Either
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volume_id&lt;/span&gt;&lt;/code&gt; or &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;snapshot_id&lt;/span&gt;&lt;/code&gt; has to be provided for the create backup API,
but not both. The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;snapshot_id&lt;/span&gt;&lt;/code&gt; is required for backing up a snapshot.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Create backup&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;V2/&amp;lt;tenant id&amp;gt;/backups&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Method: POST&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;JSON schema definition for V2:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"backup"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"display_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"nightly001"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# existing&lt;/span&gt;
        &lt;span class="s2"&gt;"display_description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Nightly backup"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# existing&lt;/span&gt;
        &lt;span class="s2"&gt;"volume_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"xxxxxxxx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# existing&lt;/span&gt;
        &lt;span class="s2"&gt;"snapshot_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"xxxxxxxx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# new&lt;/span&gt;
        &lt;span class="s2"&gt;"container"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"nightlybackups"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="o"&gt;......&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;Currently notifications are sent out when a backup is created, restored, and
deleted. The notification data needs to be updated with the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;snapshot_id&lt;/span&gt;&lt;/code&gt; if
necessary.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;End user will be able to create a backup from a snapshot.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;No obvious performance impact.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;The deployer will be able to backup a snapshot.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;All volume drivers will get the backup from snapshot feature with this
proposal. No additional changes are required.&lt;/p&gt;
&lt;p&gt;If a driver wants to use a more optimal way by attaching the snapshot, it can
implement the following interfaces that were added in the Liberty release to
support non-disruptive backups:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;initialize_connection_snapshot&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;terminate_connection_snapshot&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;create_export_snapshot&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;remove_export_snapshot&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The following function can also be overridden by the driver which returns
False by default:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;backup_use_temp_snapshot&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Note: All of the driver APIs specified above were added in the Liberty
release. No new driver APIs are introduced by this spec.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&amp;lt;xing-yang&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&amp;lt;None&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Make changes to the backup API to support backup snapshot.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make changes to the backups db table to add a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;snapshot_id&lt;/span&gt;&lt;/code&gt; column.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make changes to the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;backup_volume&lt;/span&gt;&lt;/code&gt; function in driver.py and lvm.py to
support backing up a snapshot.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make changes to the incremental backups to take into account backups created
from snapshots.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make sure the code has good comments to explain different code paths.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit tests and tempest tests will be provided.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Documentation will be modified to describe how to use this feature. We will
make sure both the existing use cases and the new use cases are clearly
documented to avoid any confusion. The following should be covered:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Do a full backup of a volume with status being ‘available’ or ‘in-use’.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Do an incremental backup of a volume with status being ‘available’ or
‘in-use’.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Do a full backup of a snapshot.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Do an incremental backup of a snapshot.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Developer documentation should also be created to explain how the different
backup cases are handled and how it would impact the developers working on
drivers.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;Code is submitted here:
&lt;a class="reference external" href="https://review.openstack.org/#/c/243406/"&gt;https://review.openstack.org/#/c/243406/&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Sun, 13 Aug 2017 00:00:00 </pubDate></item><item><title>Add API to os-brick to allow extending an attached volume</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/mitaka/brick-extend-attached-volume.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/brick-extend-attached-volume"&gt;https://blueprints.launchpad.net/cinder/+spec/brick-extend-attached-volume&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Add extend_volume API to os-brick connector objects to allow
updating the host kernel size information for an attached volume.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently, Cinder has the ability to extend volumes that aren’t attached.
Unfortunately, this doens’t work for attached volumes, due to the host
kernel that the volume is attached to, won’t see the new size unless actions
are taken on the host.  The linux kernel doesn’t automatically see the size
changing on the remote storage server.  This spec outlines the idea of adding
those required actions on the host server when an attached volume is extended
in size.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;An OpenStack user has a Cinder volume attached to a host/VM and they want to
extend/grow the volume while it’s attached.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Add a new os-brick Connector api called “extend_volume” that does the work
on the host to get the volume size updated.  This will also have to take into
account the raw device and the multipath device, if available.  It will return
the size of the volume after the resize is complete or None if it failed.&lt;/p&gt;
&lt;p&gt;This spec doesn’t cover the work needed by Cinder and Nova to make the solution
complete.   This spec simply covers the work needed by os-brick, to ensure the
volume that’s attached to the nova compute host can update it’s host kernel
to see the volume’s new size.  Cinder will have to change, to allow attached
volumes to be extended, and when complete call a new Nova API to initiate the
work on the compute host.  Then Nova will have to issue a blockresize in virt
to get the VM’s virtual device resized.  For the volume types such as RBD,
where Nova doesn’t use os-brick as the library for managing the volume, Nova
will have to do the work of issuing the commands to extend the volume itself.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Unfortunately, if a volume is attached to a VM, there is nothing an end user
can do, because the Nova compute host kernel has to see the changes before the
VM can see the new size.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;The end user, that owns the VM will may have to issue a filesystem resize to
get the native filesystem on the volume to recognize the new volume size.  For
ext* style filesystems, users can use resize2fs.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;walter-boring&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;Add the new API to the base Connector class and then add the common required
code to the linuxscsi.py to do the real work.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;In order for this to be used by the OpenStack end user, Cinder will have to
optionally allow for attached volumes to be extended.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There will also need to be some Nova work done to initiate the call into
os-brick’s new API to do the work, and then notify the VM after it’s
successful.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Until the end to end Cinder -&amp;gt; Nova capability is in place, there isn’t a way
to automate the testing of this.  For now, it’s a manual process.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;What is the impact on the docs team of this change? Some changes might require
donating resources to the docs team to have the documentation updated. Don’t
repeat details discussed above, but please reference them here.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;A related cinder-spec that has been up for a while here:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/200627/"&gt;https://review.openstack.org/#/c/200627/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Related information on how to manually do the work of notifying the host
kernel:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://help.ubuntu.com/lts/serverguide/multipath-admin-and-troubleshooting.html"&gt;https://help.ubuntu.com/lts/serverguide/multipath-admin-and-troubleshooting.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Sun, 13 Aug 2017 00:00:00 </pubDate></item><item><title>Scalable Backup Service</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/mitaka/scalable-backup-service.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/scalable-backup-service"&gt;https://blueprints.launchpad.net/cinder/+spec/scalable-backup-service&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Because cinder backup workloads run as a dedicated service, they have
potential to be run independently of other cinder volume services.
Ideally, backup services would be fired up on demand in the cloud as
backup workloads are generated, and elastically de-commissioned as
workloads go away.  Ideally, backup tasks would farmed out to the
least busy of the available backup services.&lt;/p&gt;
&lt;p&gt;Pursuit of this ideal is blocked today by a tight coupling of cinder
backup service to cinder volume service.&lt;/p&gt;
&lt;p&gt;This spec is dedicated to breaking this tight coupling of the cinder
backup and volume services.&lt;/p&gt;
&lt;p&gt;That is the first step in working towards a truly elastic,
horizontally scalable backup service.  When this coupling is loosened,
multiple backup services can be fired up concurrently and run without
any requirement that they they be colocated with the volume services
or with one another for that matter.&lt;/p&gt;
&lt;p&gt;We expect that there will be followup work to address subsequent steps
such as scheduler support for backup tasks and for dynamic generation
of backup service processes using VMs or containers rather than
dedicated physical nodes, but those subjects would be addressed by
followup specs and are not in scope here.&lt;/p&gt;
&lt;p&gt;One thing at a time.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;When the backup service backs up or restores a volume, it uses a
&lt;em&gt;backup driver&lt;/em&gt; specific to a chosen and configured backup repository
to interact with e.g. a swift or Ceph object store, an NFS, glusterfs,
or generic POSIX filesystem, or Tivoli Storage Manager. This backup
driver plugs in to the backup manager and provides functionality to
put data in the backup repository or to retrieve it from the
repository.  A particular backup service process has only one backup
driver and therefore only one backup repository.  It may, however,
perform backup and restore operations for volumes for &lt;em&gt;any&lt;/em&gt; of the
&lt;em&gt;enabled backends&lt;/em&gt; handled by the volume service.&lt;/p&gt;
&lt;p&gt;The backup service requires backend-specific functionality to attach
to any particular volume in order to read it for backup or to write to
it for restore.&lt;/p&gt;
&lt;p&gt;Today, this backend-specific information is provided as follows.  When
the backup service process starts up, the backup manager loads the
volume manager module for each enabled backend configured in
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cinder.conf&lt;/span&gt;&lt;/code&gt;.  When an OpenStack tenant or administrator makes a
request to create a backup from a cinder volume or to restore a backup
to a cinder volume, the backup api looks at the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;host&lt;/span&gt;&lt;/code&gt; field for the
&lt;em&gt;volume&lt;/em&gt; in question and directs the rpc for the backup or restore
operation to the backup manager on that node.  There, the backup
manager selects the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volume&lt;/span&gt;&lt;/code&gt; manager for the relevant volume backend
and invokes its &lt;em&gt;driver’s&lt;/em&gt; &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;backup_volume&lt;/span&gt;&lt;/code&gt; or &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;restore_volume&lt;/span&gt;&lt;/code&gt;
method, passing that method the backup &lt;em&gt;object&lt;/em&gt; and the backup
&lt;em&gt;driver&lt;/em&gt; (swift, ceph, NFS, etc.) for the configured backup
repository.  Then the &lt;em&gt;volume driver&lt;/em&gt; attaches to the volume in
question, opens it, and invokes the backup driver’s &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;backup&lt;/span&gt;&lt;/code&gt; or
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;restore&lt;/span&gt;&lt;/code&gt; method using the file handle from the &lt;em&gt;volume driver’s&lt;/em&gt;
attach and open operation.&lt;/p&gt;
&lt;p&gt;Thus today the backup manager does not invoke its backup driver
methods directly; it finds an appropriate volume driver via the
appropriate volume manager, and the volume driver invokes the
appropriate backup driver.  The volume driver by definition runs on
the cinder node that runs the volume service for the relevant backend,
so since the backup manager, volume driver, and backup driver code all
run in the context of a single operating system process on a single
node, the backup service is necessarily tied to the node that also
runs the volume service.&lt;/p&gt;
&lt;p&gt;When multiple pools and backends run on the same node, this means that
concurrent backups end up running into the resource constraints of a
single node.  Since backup tasks do not flow through a scheduler, they
typically also run with the resource constraints of a single operating
system process.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;An OpenStack tenant or administrator needs to do backups on a
schedule or restores on demand such that to get the work done in a
timely manner many backups and restores need to run concurrently.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Resource requirements to handle peak backup and restore loads exceed
the capabilities of a standard physical node.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Note that the need for concurrent backup and restore operations,
especially to the same backend, may be artificially suppressed
historically because of the lack of support for &lt;em&gt;live&lt;/em&gt; backups.  We
anticipate that now that backups of &lt;em&gt;in-use&lt;/em&gt; volumes are supported
([3] [5]) this need will significantly increase.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Leverage remote attach capability to move the functionality provided
by the &lt;em&gt;volume&lt;/em&gt; driver into the backup manager.  That way the backup
manager can invoke the backup driver directly rather than having to
load the volume manager at startup and run the relevant volume
manager’s driver.&lt;/p&gt;
&lt;p&gt;Nowadays attaching a volume is done using a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;brick&lt;/span&gt;&lt;/code&gt; library that
builds an appropriate &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;connector&lt;/span&gt;&lt;/code&gt; for the attachment given
information about the backend (iSCSI, FibreChannel, NFS, whatever)
obtained by running a volume driver &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;initialize_connection&lt;/span&gt;&lt;/code&gt; method
– either directly or via an rpc to the appropriate volume service.
In the case of a &lt;em&gt;remote&lt;/em&gt; attachment, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;initialize_connection&lt;/span&gt;&lt;/code&gt; is
invoked by rpc.  This is the only part of the workflow that actually
requires the volume service, and since it can be an rpc invocation,
this means that the direct load of volume manager and volume driver
can be eliminated in the backup service itself and the backup service
can therefore run on a different node than the node for the backend’s
volume service.&lt;/p&gt;
&lt;p&gt;Now that backups of &lt;em&gt;in-use&lt;/em&gt; volumes are supported, volume drivers
can supply an &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;attach_snapshot&lt;/span&gt;&lt;/code&gt; method, which is then used as
optimization instead of attaching a temporary volume copy of the
source volume.  In the initial implementation [6], an &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;attach_snapshot&lt;/span&gt;&lt;/code&gt;
method was added that only allows for local attaches and the reference
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;lvm&lt;/span&gt; &lt;span class="pre"&gt;driver&lt;/span&gt;&lt;/code&gt; explicitly uses &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;local_path&lt;/span&gt;&lt;/code&gt; when getting volumes
for backup operations [5].  As part of the work implementing this
blueprint spec, we will need to revisit snapshot attachment to allow
for remote attaches.  Drivers like &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;lvm&lt;/span&gt; &lt;span class="pre"&gt;driver&lt;/span&gt;&lt;/code&gt; that cannot support
remote attach for snapshots will need to fall back to using temporary
volumes instead [5].
* Create a temporary volume from the original volume.
* Backup the temporary volume.
* Clean up the temporary volume.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Keep the existing scheme.  Backup service continues to work but
cannot scale out.&lt;/p&gt;
&lt;p&gt;The node running backup service has to be scaled up to handle
projected peak backup workload and is likely to be either
underutilized or underpowered for most actual backup workloads.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Instead of loading the volume manager directly from the backup
manager, expose &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;backup_volume&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;restore_volume&lt;/span&gt;&lt;/code&gt; methods in
the volume manager, have these invoke the corresponding volume
driver’s methods by the same name, and have the backup manager use
rpc to the volume service to trigger the volume manager’s
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;backup_volume&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;restore_volume&lt;/span&gt;&lt;/code&gt; methods.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;This approach would reduce memory requirements for the backup
service process since it would no longer load the volume managers
for all enabled backends. And the linkage between backup manager and
volume service is now loosely coupled.  However, the bulk of the
work - data transfer, encryption, compression - is done by the
backup driver, which still remains tightly coupled to the volume
service.&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section id="what-this-specification-does-not-solve"&gt;
&lt;h3&gt;What this specification does not solve&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A backup task scheduler.&lt;/p&gt;
&lt;p&gt;The backup api process can get a list of active backup services from
the database and choose as an rpc destination e.g. the first
service, make a random choice, or round-robin among the choices.
This is where a call to a scheduler could go in the future, but a
scheduler is not itself in scope for this spec.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Elastic backup service placement.&lt;/p&gt;
&lt;p&gt;Backup services will be started more or less manually by an
administrator or configured to start on boot of a node.  One can
imagine a dynamic mechanism for starting service VMs or containers
triggered by the backup api as workloads arrive.  The decoupling of
backup and volume services addressed by this spec is a pre-condition
for such an elastic backup service placement capability but it is
only a small step towards enabling such a capability.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="service-init-host-cleanup"&gt;
&lt;h3&gt;Service &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;init_host&lt;/span&gt;&lt;/code&gt; cleanup&lt;/h3&gt;
&lt;p&gt;At startup, the current backup service code makes an attempt to
discover and cleanup orphaned, incomplete backup and restore
operations (e.g., they were in process when the backup process itself
was terminated).  The backup service assumes that it is the &lt;em&gt;only&lt;/em&gt;
backup process, so that if it finds backups in creating or restoring
state at startup it can safely reset their state and detach the
volumes that were being backed up or restored.&lt;/p&gt;
&lt;p&gt;This assumption is not safe if multiple backup processes can run
concurrently, and on separate nodes.  At startup, a backup service
needs to distinguish between in-flight operations that are owned by
another backup-service instance and orphaned operations.&lt;/p&gt;
&lt;p&gt;Eventually, it will make sense for a backup service process to
cleanup stuff left behind either by earlier incarnations of itself
or by other abnormally terminated backup processes.  A solution to
this general problem, however, requires a reliable capability
to auto-fence oneself on connection loss as being developed as
part of the solution for Active-Active HA for the cinder volume
service [7].&lt;/p&gt;
&lt;p&gt;Here we will align with the community decision at the Mitaka design
summit to defer the auto-fencing capability and start on Active-Active
HA for the cinder volume service without automatic cleanup, by
restricting backup service initialization cleanup to leftovers from
the same backup service.&lt;/p&gt;
&lt;p&gt;The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;host&lt;/span&gt;&lt;/code&gt; field for a backup object will be set to the host for the
backup service to which the backup operation is cast. The status update
of the backup and host update will be handled in an transaction. Cleanup
at initialization can then be restricted to leftover objects that
chain through their corresponding backup object to a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;host&lt;/span&gt;&lt;/code&gt; field
matching oneself. Compare-and-swap DB operation will be used to prevent
race conditions.&lt;/p&gt;
&lt;p&gt;For an example of how the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;host&lt;/span&gt;&lt;/code&gt; field will be set, consider
a volume with a backend handled by volume service on node A where
backup service processes are running on node B and node C.  When
a backup is created using the service on node B, the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;host&lt;/span&gt;&lt;/code&gt; field
for the backup object will be set to B.  When restoring from that
backup using the backup service on node C, the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;host&lt;/span&gt;&lt;/code&gt; field for
the backup object will be set to C.&lt;/p&gt;
&lt;p&gt;Cleanup of associated volumes, temporary volumes, and temporary
snapshots will be done via rpc to the appropriate volume service host.&lt;/p&gt;
&lt;p&gt;Note that the backup object contains a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volume_id&lt;/span&gt;&lt;/code&gt; field for the
volume it backs up, as well as &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;temp_volume_id&lt;/span&gt;&lt;/code&gt; and
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;temp_snapshot_id&lt;/span&gt;&lt;/code&gt; fields for live backups, but it does not
currently keep the id of volumes to which it is restoring backups.  We
will need to add this field in order to determine orphaned
restore-operation volumes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="special-volume-driver-backup-restore-considerations"&gt;
&lt;h3&gt;Special Volume Driver Backup/Restore Considerations&lt;/h3&gt;
&lt;p&gt;Since the functionality of the current volume driver &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;backup_volume&lt;/span&gt;&lt;/code&gt;
and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;restore_backup&lt;/span&gt;&lt;/code&gt; methods will in this proposal move into the
backup manager, these methods will no longer be needed and can be
removed from the codebase.  That said, some volume drivers override
these with methods that apparently have a bit more “special sauce”
than just preparing their volume for presentation as a block device.&lt;/p&gt;
&lt;p&gt;We will need to analyze the codebase to root out any of these and
determine how to accommodate any special needs.&lt;/p&gt;
&lt;p&gt;An example is the vmware volume driver [4], where a “backing” and
temporary vmdk file are created for the cinder volume and the
temporary vmdk file is used as the backup source.  We will have to
determine whether all this can be done in the volume driver’s
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;initialize_connection&lt;/span&gt;&lt;/code&gt; method during &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;attach&lt;/span&gt;&lt;/code&gt;, or whether we will
require an additional rpc hook to a &lt;em&gt;prepare_backup_volume&lt;/em&gt; method or
some such for volume drivers of this sort.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;TBD.&lt;/p&gt;
&lt;p&gt;We need to understand exactly where it is necessary to elevate
privileges in running backup and restore operations and ensure that
there is no unnecessary elevation above the normal privileges for the
admin or tentant requesting the these operations.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;We should be able to do exactly the same backup service notifications
as those done now.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;No change in function or client interaction.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Backup process will be lighter weight since volume manager and
drivers are no longer loaded.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The proposed change enables running multiple backup processes as
required.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;Backup service can now run on multiple nodes and no longer has to run
on the same node as the volume service handling a volume’s backend.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Enables potentially valuable future features such as backup scheduler
or elastic backup service placement.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Primary assignee:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Tom Barron (tbarron, &lt;a class="reference external" href="mailto:tpb%40dyncloud.net"&gt;tpb&lt;span&gt;@&lt;/span&gt;dyncloud&lt;span&gt;.&lt;/span&gt;net&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Other contributors:
* LisaLi (lixiaoy11, &lt;a class="reference external" href="mailto:xiaoyan.li%40intel.com"&gt;xiaoyan&lt;span&gt;.&lt;/span&gt;li&lt;span&gt;@&lt;/span&gt;intel&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;)
* Huang Zhiteng (winston-d, &lt;a class="reference external" href="mailto:winston.d%40gmail.com"&gt;winston&lt;span&gt;.&lt;/span&gt;d&lt;span&gt;@&lt;/span&gt;gmail&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;)&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Write the code.  A POC is available now [1].&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Determine and address any impact on existing volume drivers that
have their own backup or restore methods.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Run/test the new code with multiple backup processes running on
multiple nodes, other than the node or nodes where the volume
services run for enabled backends.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit tests will be extended to cover new backup code for
functionality formerly provided by volume driver.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unit tests for backup manager and volume drivers will be modified to
reflect code removed from the backup service to load volume manager,
run volume drivers, etc. and from the volume driver to run backup
and restore operations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Existing tempest tests should provide sufficient coverage to ensure
that current functionality does not regress.  Potentially new
multi-node tempest tests could be added to verify distributed
interactions.  We should take advantage of opportunities to extend
current tempest coverage for backup and add functional tests for
backup when this is feasible.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Update with new deployment options.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;[1]: &lt;a class="reference external" href="https://review.openstack.org/#/c/203291"&gt;https://review.openstack.org/#/c/203291&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[2]: &lt;a class="reference external" href="https://etherpad.openstack.org/p/cinder-scaling-backup-service"&gt;https://etherpad.openstack.org/p/cinder-scaling-backup-service&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[3]: &lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/non-disruptive-backup"&gt;https://blueprints.launchpad.net/cinder/+spec/non-disruptive-backup&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[4]: &lt;a class="reference external" href="https://github.com/openstack/cinder/blob/master/cinder/volume/drivers/vmware/vmdk.py#L1573"&gt;https://github.com/openstack/cinder/blob/master/cinder/volume/drivers/vmware/vmdk.py#L1573&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[5]: &lt;a class="reference external" href="https://review.openstack.org/#/c/193937"&gt;https://review.openstack.org/#/c/193937&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[6]: &lt;a class="reference external" href="https://review.openstack.org/#/c/201249"&gt;https://review.openstack.org/#/c/201249&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[7]: &lt;a class="reference external" href="https://review.openstack.org/#/c/237076"&gt;https://review.openstack.org/#/c/237076&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Sun, 13 Aug 2017 00:00:00 </pubDate></item><item><title>User facing “Failure” Message and Event Viewer</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/newton/summarymessage.html</link><description>

&lt;p&gt;For quite some time, OpenStack services have wanted to be able to send
messages, especially error messages, to API end users (by user I do not mean
the operator, but the user that is interacting with the API).&lt;/p&gt;
&lt;p&gt;If user performs some operation and operation fails or goes in
hang state, then there must be some interface for user to see reason
for this behavior.&lt;/p&gt;
&lt;p&gt;So, this is basically regarding facilitating user to see error messages
for asynchronous operations either directly through APIs or through new
“Event Viewer” tab in horizon or horizon pluggin.&lt;/p&gt;
&lt;p&gt;This is more specific to failed operations and cause of their failure.&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/summarymessage"&gt;https://blueprints.launchpad.net/cinder/+spec/summarymessage&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;If operations like create volume, create snapshot etc fails, user gets
no detailed information in case operation fails.
Sometime only operation status is updated to error, failed etc without
any update to user.&lt;/p&gt;
&lt;p&gt;In some case it is worse than this.
For ex,
1. In case rabbitmq is inactive and user tries to create volume,
horizon hangs on waiting response from API forever.
2. In case rabbitmq is active but recipient service is not running
and user tries to create volume, API hangs on waiting response
from rabbitMQ forever.&lt;/p&gt;
&lt;p&gt;A few resources among all the OpenStack projects handle reporting errors
to end users for asynchronous operations and those that do are inconsistent
with each other.
In addition to a mechanism to enable error reporting in a
consistent way across OpenStack, the solution must also be able to
accommodate a deployment of Cinder that contains no other OpenStack service.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;Motivation for this Blue Print:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;To help admin in debugging failed operations with
less log filtering.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To notify admin to start services which failed due to
some abnormal conditions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To inform user about failure in case operation fails.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To provide enough information to user about failure.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;General Use Cases:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Cinder volume/snapshot creation goes to ERROR status due
to lack of capacity. (Scheduling error)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cinder add volume to CG fails, how to tell user the volume
and group are not on the same backend?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cinder volume goes from attaching to available. why?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Volume retype fails.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Volume extend fails, I’d like to know why and be able to
still use my volume instead of it being in error_extending.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ETC..&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;User can fetch operation failure details through direct API calls or
through new horizon tab “Event Viewer”.
From CLI, cli client could be used to display same kind of information.&lt;/p&gt;
&lt;p&gt;Suggested implementation is based on 2 way approach&lt;/p&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;p&gt;Push Information:
During user operations, messages will be pushed to database
using component specific notifications.&lt;/p&gt;
&lt;p&gt;These messages will be generated and pushed to database by
component for operation start, operation completion or operation
failure.&lt;/p&gt;
&lt;p&gt;Message generation will be based on eventID to eventMessage
mapping using message constant files which keeps different
notification messages mapping in it.
This way deployer can easily modify notification messages as per
requirement.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pull Information:
In case user needs to check operation status, user can pull details
using CLI client or Horizon tab.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Results may be shown in tabular way as shown below&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Tenant&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;EventID&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;NodeName&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;ReqID&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Level&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Resource&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Time&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Summary&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Sheel&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;UKN_ERR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;BS-cind1&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;{…}&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Error&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Volume&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;{..}&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;{….}&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Every ‘operation’ initiated by the user has a request ID returned as
an HTTP header in the context.
These notification messages will be tied to operation request ID.
(This request ID will be used for mapping a request to what happened in cinder
for that operation.)&lt;/p&gt;
&lt;p&gt;Summary message will contain operation specific failure message.
For ex,
“Volume create operation failed - {Reason of failure}”&lt;/p&gt;
&lt;p&gt;Filters:&lt;/p&gt;
&lt;p&gt;Results can be filtered depending upon TenantID, HostID, UserID,
Operation Outcome/Result(Fail/Pass) etc.&lt;/p&gt;
&lt;p&gt;Type of Messages:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;API Events : messages for failed operations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Service Logs: information for failed services either stopped by user
or stopped due to any abnormal conditions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;System Logs: any other logs than API and service logs.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Suggested Architecture&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;The proposed change is to add a new /v3/&amp;lt;tenant&amp;gt;/messages API
resource backed by a messages table in the Cinder DB.
This endpoint will return a list of error messages that are
intended for the end-user regarding failed asynchronous operations.&lt;/p&gt;
&lt;p&gt;In short:
* /v3/&amp;lt;tenant&amp;gt;/messages API resource, exposes notifications messages
depending upon filters
* message_ttl config option that dictates message minimum life in seconds
* messages DB table&lt;/p&gt;
&lt;section id="questions"&gt;
&lt;h3&gt;Questions&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;User facing notifications
Use the existing notification framework in combination with an AMQP
consumer to pull messages off and provide an endpoint for the user.
Faults with this approach are that we do not want to display the current
information in notifications to the user and it will require many more
services as dependencies.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Per resource faults
This alternative suggests adding a sub-resource to each resource, such as
volumes/&amp;lt;volume-id&amp;gt;/faults, similar to Nova’s instance faults. This
makes it difficult to poll for messages for more than a single resource
or resource type. It also adds significant complexity to the api as
every resource must add /faults in order to support messages.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Exposing user messages via a separate service (such as Zaqar)
This approach suggests storing user messages in another service that the
user could query for messages or the service could utilize webhooks to
notify the user. One major drawback to this approach is the complexity
in writing bindings for the separate service(s) and the need for a
separate service as a dependency.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="what-this-specification-does-not-solve"&gt;
&lt;h3&gt;What this specification does not solve&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;State change notifications.
This solution does not intend to solve the use-case of alerting users when
a volume or any other resource changes state. For example, when a volume
changes from &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;creating&lt;/span&gt;&lt;/code&gt; to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;available&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;New APIs:
* GET /v3/&amp;lt;tenant&amp;gt;/messages
With filters by attribute. Ex: GET /v3/&amp;lt;tenant&amp;gt;/messages?resource_type=volume
* GET /v3/&amp;lt;tenant&amp;gt;/messages/&amp;lt;message-id&amp;gt;
* DELETE /v3/&amp;lt;tenant&amp;gt;/messages/&amp;lt;message-id&amp;gt;&lt;/p&gt;
&lt;p&gt;Message schema&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;object&lt;/span&gt;
  &lt;span class="n"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;user_message&lt;/span&gt;
  &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;
  &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;project_id&lt;/span&gt;
  &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;request_id&lt;/span&gt;
  &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;event_id&lt;/span&gt;
  &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;created_at&lt;/span&gt;
  &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;message_level&lt;/span&gt;
  &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;expires_at&lt;/span&gt;
  &lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;
      &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;UUID&lt;/span&gt; &lt;span class="n"&gt;will&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;stored&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="s1"&gt;'id'&lt;/span&gt; &lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
    &lt;span class="n"&gt;message_level&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;
      &lt;span class="n"&gt;enum&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;ERROR&lt;/span&gt;
      &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="n"&gt;level&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;future&lt;/span&gt; &lt;span class="n"&gt;we&lt;/span&gt; &lt;span class="n"&gt;may&lt;/span&gt; &lt;span class="n"&gt;expand&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt;
      &lt;span class="n"&gt;sending&lt;/span&gt; &lt;span class="n"&gt;information&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="n"&gt;that&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;an&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
    &lt;span class="n"&gt;user_message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;event_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;
      &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Event&lt;/span&gt; &lt;span class="n"&gt;ID&lt;/span&gt; &lt;span class="n"&gt;can&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;used&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt;
      &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="n"&gt;deployer&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;some&lt;/span&gt; &lt;span class="n"&gt;specific&lt;/span&gt; &lt;span class="n"&gt;situation&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
      &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;report&lt;/span&gt; &lt;span class="n"&gt;errors&lt;/span&gt; &lt;span class="n"&gt;by&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
      &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;debug&lt;/span&gt; &lt;span class="n"&gt;fast&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="n"&gt;easy&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;search&lt;/span&gt; &lt;span class="n"&gt;where&lt;/span&gt; &lt;span class="n"&gt;specific&lt;/span&gt; &lt;span class="n"&gt;eventID&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt;
      &lt;span class="n"&gt;used&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;reporting&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
    &lt;span class="n"&gt;resource_uuid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;
      &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;offending&lt;/span&gt; &lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
    &lt;span class="n"&gt;resource_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;
      &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;resource&lt;/span&gt; &lt;span class="n"&gt;this&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="n"&gt;pertains&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
      &lt;span class="n"&gt;For&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;volume&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;snapshot&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;backup&lt;/span&gt; &lt;span class="n"&gt;etc&lt;/span&gt;
    &lt;span class="n"&gt;request_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;created_at&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;expires_at&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;
      &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;After&lt;/span&gt; &lt;span class="n"&gt;this&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="n"&gt;may&lt;/span&gt; &lt;span class="n"&gt;no&lt;/span&gt; &lt;span class="n"&gt;longer&lt;/span&gt; &lt;span class="n"&gt;exist&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;New messages table in the DB to store all messages. This table may prove to
grow large in a cloud with lots of errors. The admin will be able to utilize
the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;expires_at&lt;/span&gt;&lt;/code&gt; column to reap messages.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;Messages must be highly scrutinized before becoming visible to the user in
order to avoid any sensitive data from being shown. This will be mitigated by
having all user visible messages defined in a single module. The messaging
mechanism will assert that any message it will create comes from the sanctioned
location.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;New configuration option &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;message_ttl&lt;/span&gt;&lt;/code&gt; that will dictate the number of
seconds after the messages creation time to set the ‘guaranteed_until’
attribute on generated messages.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;New configuration option &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;message_reap_interval&lt;/span&gt;&lt;/code&gt; that will dictate the
number of seconds between calls to delete old messages. A value of -1
will never run. DocImpact: This option should not be set on a large number
of nodes, since too many nodes trying this delete at the same time will cause
transaction bouncing and degraded DB performance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;New configuration option &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;message_reap_batch_size&lt;/span&gt;&lt;/code&gt; that dictates the number
of expired messages to delete each interval. This allows a deployer to
limit DB performance impact by setting a ceiling for the number of
messages deleted at a time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The messages table will be potentially large and may be reaped based on
the ‘guaranteed_until’ column. Where all messages with a
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;expires_at&lt;/span&gt;&lt;/code&gt; date earlier than the current time can be safely
deleted.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Developers should be aware of use-cases where the user needs information
about an error. In these situations, an appropriate user message should be
written and creation of the message added in the specific code path(s).&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Sheel Rana
Alex Meade&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;This whole implementation depends upon message generation, transport,
collection, storage and analytics of different failure messages.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;cinder:
Implementation to generate notification messages at the time of
failure for all existing operations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;cinder:
notification listener is required which will serve as
basis for handling event messages from different components.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;cinder:
collector is required to collect, validate and store event
messages to database.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;cinder:
new API to fetch details form database depending upon filters.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;cinder:
Add pagination to messages&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;cinder-manage:
Add mechanism to automatically, and via a cinder-manage command,
reap expired messages in the db depending upon ttl value.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;cinder:
Documentation for new API details.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;cinder:
Update “Getting started Guide”.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;cinder:
Database schema preparation to store notification messages.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;cinder:
Need to implement “delete messages as per message life” from database after
message expiry time.
For ex, if user has set &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;message_ttl&lt;/span&gt;&lt;/code&gt; to 7 days, then all messages
older than 7 days will be purged from database.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;horizon:
Separate tab for cinder to display event messages.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;cinder-client:
cinder cli to communicate with API and fetch event messages.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;cinder-client:
Update to CLI reference Guide.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tempest tests&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="implementation-phases"&gt;
&lt;h3&gt;Implementation Phases:&lt;/h3&gt;
&lt;p&gt;This whole feature will be implemented in multiple phases:&lt;/p&gt;
&lt;p&gt;Phase 1. Basic implementation regarding notification generation and storage
into database with “/messages” exposed to view notification messages.
This spec targets Phase 1 first, other phases will be implemented after
acceptance of phase 1.&lt;/p&gt;
&lt;p&gt;Phase 2. Implementation for facilitating admin to configure notification
storage like db or zaqar or both.
If both RPC/DB are configured by admin, notification message would be
stored in zaqar along with storing information to database.&lt;/p&gt;
&lt;p&gt;Phase 3. Implementation for consuming information from zaqar directly.&lt;/p&gt;
&lt;p&gt;Phase 4. Horizon and CLI implementations to view notifications in more
formatted manner.&lt;/p&gt;
&lt;p&gt;Phase 5. Handling of some special cases where generation of notifications
requires separate handling like rabbitMQ related implementations for showing
notifications in case rabbitMQ is in failed state or rabbitMQ recipient is
in inactive state.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Tempest tests should be written and run in the gate. It may prove difficult
to implement complete functional testing of the feature as messages will not
be created unless there is an error, which may be difficult to trigger.
However, some operations are easy to trigger failure with unlimited quotas.
One example is creating a thick provisioned volume too big to be stored on the
backend.&lt;/p&gt;
&lt;section id="example-test-cases"&gt;
&lt;h3&gt;Example Test Cases&lt;/h3&gt;
&lt;p&gt;# List messages with no messages
# Attempt creation of a TOO LARGE volume and verify appropriate scheduling
error message is created
# List messages with filters, especially resource_type&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;REST API documentation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;New config option, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;message_ttl&lt;/span&gt;&lt;/code&gt; (time to live)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;New config option, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;message_reap_interval&lt;/span&gt;&lt;/code&gt;
(number of seconds between calls to delete old messages)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;New config option, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;message_reap_batch_size&lt;/span&gt;&lt;/code&gt;
(number of messages which could be deleted in one batch)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;New API policies for messages&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Mitaka Midcycle discussion&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://etherpad.openstack.org/p/mitaka-cinder-midcycle-user-notifications"&gt;https://etherpad.openstack.org/p/mitaka-cinder-midcycle-user-notifications&lt;/a&gt;
&lt;a class="reference external" href="https://etherpad.openstack.org/p/mitaka-cinder-midcycle-day-1"&gt;https://etherpad.openstack.org/p/mitaka-cinder-midcycle-day-1&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Kilo Summit Discussion&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://etherpad.openstack.org/p/kilo-cinder-async-reporting"&gt;https://etherpad.openstack.org/p/kilo-cinder-async-reporting&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Liberty Summit Discussion (in conjunction with HEAT) -&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://etherpad.openstack.org/p/liberty-cross-project-user-notifications"&gt;https://etherpad.openstack.org/p/liberty-cross-project-user-notifications&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
</description><pubDate>Sun, 13 Aug 2017 00:00:00 </pubDate></item><item><title>Backup driver initialization</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/pike/backup-init.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/backup-init"&gt;https://blueprints.launchpad.net/cinder/+spec/backup-init&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;We don’t initialize Cinder Backup driver during service startup. It means that
we’ve got cinder-backup service up and running even if it can’t connect to the
backup storage.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Cinder backup manager does not verify that backup driver is initialized
successfully. If cinder-backup is started successfully we can create a volume
backup. Such backups always will be in ‘error’ status and tenant user won’t be
able to delete them.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;Cinder backup service should be marked as ‘down’ if it can’t connect to the
backup storage.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;We should introduce for cinder backups the same mechanism as we’ve got for
volume manager and drivers:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Introduce ‘init_host’ method in backup manager which will be called on
service startup and verify that backup driver is initialized: verify driver’s
configuration is correct, depends on driver, we could check connection to
storage, list of available backups. etc.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If backup driver initialization fails, manager will mark backup service
as ‘down’.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In case of initialization failure, cinder will try to do it periodically
depends on ‘periodic_interval’ config option value.&lt;/p&gt;
&lt;p&gt;Backup service should be initialized in ‘service_down_time’ time
interval or will be marked as ‘down’.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Check for backup storage is available on backup create call. If storage is not
available, remove ‘host’ field from backup object. We could try to re-schedule
backup creation on the other host.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;New notifications for backup initialization failure and success will be added.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;User will be able to delete backup in error state if it was not created on
backend.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;New ‘backup_periodic_initialization’ and ‘backup_initialization_timeout’
config option will be added. Deployer have to enable
‘backup_periodic_initialization’ if needed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Backup driver developers should implement new APIs.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Ivan Kolodyazhny &amp;lt;&lt;a class="reference external" href="mailto:e0ne%40e0ne.info"&gt;e0ne&lt;span&gt;@&lt;/span&gt;e0ne&lt;span&gt;.&lt;/span&gt;info&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Backup drivers maintainers.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Implement ‘do_setup’ method in a base backup driver which won’t do anything&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement ‘do_setup’ in each backup driver.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Call driver’s ‘do_setup’ during backup-manager ‘init_host’ call.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Both unit and Tempest tests should be implemented to cover new feature.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/cinder/+bug/1598709"&gt;https://bugs.launchpad.net/cinder/+bug/1598709&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Sun, 13 Aug 2017 00:00:00 </pubDate></item><item><title>Support backup import on another Storage database</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/newton/support-backup-import-on-another-storage-database.html</link><description>

&lt;p&gt;URL of launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/support-backup-import-on-another-storage-database"&gt;https://blueprints.launchpad.net/cinder/+spec/support-backup-import-on-another-storage-database&lt;/a&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;This backup service can use a backup extra metadata in order
to import a backup on a different Block Storage.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Currently a volume backup can only be restored on the same Block Storage
service.
This is because restoring a volume from a backup requires metadata available
on the database used by the Block Storage service.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In order to import backup metadata on another Block Storage database
(i.e disaster recovery site), one has to save the metadata of a volume
backup available on the source database, and then replicate it together
with the data to the other Block Storage site.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Combination of the local backup service that exports and stores
this metadata, together with replication to another Block Storage site,
allows you to completely restore the backup even in the event of
a catastrophic database failure.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In addition, having a backup metadata together with a volume backup,
also provides volume portability.
Specifically, backing up a volume and exporting its metadata will allow you
to restore the volume on a completely different Block Storage database,
or even on a different cloud service.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;When a user wants to save backup metadata together with volume backup for
volume portability purpose, or for replication purpose to disaster
recovery site, and be able to restore a volume from a backup on the other
Block Storage site.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;In order to support backup import on a different Block Storage database,
we need to extend chunked backup driver:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Enabling to save backup metadata together with the data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a cinder client api command, that will parse backup metadata from
backup_metadata file, and import that metadata to the other
Block Storage database.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;User will be able to restore a volume backup on the other
Block Storage, using cinder backup restore api.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Support only storage on local storage.
Use slow manual backup and restore methods.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;ronen-mesonzhnik&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;None&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Implement get_extra_metadata that will return backup’s corresponding
database information as encoded string metadata.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement a cinder client api command that can take a backup metadata
file, and do the import from it.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;In addition to the existing command ‘cinder backup-import &amp;lt;METADATA&amp;gt;’,
there will be a command that can accept a file:
‘backup-import-record-from-backup-metadata-file &amp;lt;file_path&amp;gt;’&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Link to Export and import backup metadata documentation:
&lt;a class="reference external" href="http://docs.openstack.org/admin-guide-cloud/blockstorage_volume_backups_export_import.html"&gt;http://docs.openstack.org/admin-guide-cloud/blockstorage_volume_backups_export_import.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Fri, 28 Jul 2017 00:00:00 </pubDate></item><item><title>Support metadata for backup</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/pike/metadata-for-backup-resource.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/metadata-for-backup"&gt;https://blueprints.launchpad.net/cinder/+spec/metadata-for-backup&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Add a new “metadata” property for backup resource.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Backup resource lost the ability for getting/setting metadata property.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;The metadata here for backup is the descriptive metadata. It’s used for
discovery and identification. Users could add key-value pairs for the backups
to describe them. And users can also filter backups with specified metadata.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;The “metadata” property will be added to backup object.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;2. A new DB table “backup_metadata” will be created.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;-----------------------------------------------------------------------&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;updated_at&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;deleted_at&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;backup_id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;-----------------------------------------------------------------------&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;-----------------------------------------------------------------------&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The primary key is “id”.&lt;/p&gt;
&lt;p&gt;3. The backup create/update API will be updated to support “metadata”.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v3&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;backups&lt;/span&gt;
&lt;span class="n"&gt;PUT&lt;/span&gt;  &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v3&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;backups&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;backup_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="n"&gt;can&lt;/span&gt; &lt;span class="n"&gt;contain&lt;/span&gt; &lt;span class="s2"&gt;"metadata"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"metadata"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;
        &lt;span class="s2"&gt;"key1"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"value1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"key2"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"value2"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;4. A set of new APIs will be created. It’s used for backup metadata’s CRUD.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt;    &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v3&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;backups&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;backup_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;
&lt;span class="n"&gt;show&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;backup&lt;/span&gt;&lt;span class="s1"&gt;'s metadata&lt;/span&gt;

&lt;span class="n"&gt;POST&lt;/span&gt;   &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v3&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;backups&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;backup_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;
&lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;replaces&lt;/span&gt; &lt;span class="n"&gt;metadata&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;backup&lt;/span&gt;

&lt;span class="n"&gt;PUT&lt;/span&gt;    &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v3&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;backups&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;backup_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;
&lt;span class="n"&gt;replace&lt;/span&gt; &lt;span class="nb"&gt;all&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;backup&lt;/span&gt;&lt;span class="s1"&gt;'s metadata&lt;/span&gt;

&lt;span class="n"&gt;GET&lt;/span&gt;    &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v3&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;backups&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;backup_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;show&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;backup&lt;/span&gt;&lt;span class="s1"&gt;'s metadata for a specific key&lt;/span&gt;

&lt;span class="n"&gt;DELETE&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v3&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;backups&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;backup_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;delete&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;specified&lt;/span&gt; &lt;span class="n"&gt;metadata&lt;/span&gt;

&lt;span class="n"&gt;PUT&lt;/span&gt;    &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v3&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;backups&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;backup_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;specified&lt;/span&gt; &lt;span class="n"&gt;metadata&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Leave as it is.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;Backup model will be updated with new property “metadata”.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The backup create/update API’s request body will be updated.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A set of new APIs related to backup metadata will be created.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;The new APIs will send new notifications as well.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;A new “backup_metadata” table will be created so that the DB conjunction action
may let the search performance reduce a little.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;wangxiyuan(wxy)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add metadata property to backup object and bump its version.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a new DB table “backup_metadata” and add db upgrade script.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update backup create/update API.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a tuple of new APIs for backup metadata.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit tests&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Api-ref need update.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Wed, 12 Apr 2017 00:00:00 </pubDate></item><item><title>Capacity-based QoS</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/pike/capacity_based_qos.html</link><description>

&lt;p&gt;Include the URL of your launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/capacity-based-qos"&gt;https://blueprints.launchpad.net/cinder/+spec/capacity-based-qos&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;QoS values in Cinder currently are able to be set to static
values.  This work proposes a way to derive QoS limit values
based on volume capacities rather than static values.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;This proposes a mechanism to provision IOPS on a per-volume basis with
the IOPS values adjusted based on the volume’s size.  (IOPS per GB)&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;A deployer wishes to cap “usage” of this system to limits based
on space usage as well as throughput, in order to bill customers
and not exceed limits of the backend.&lt;/p&gt;
&lt;p&gt;Associating IOPS and size allows you to provide tiers such as&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;Gold:    1000 GB at 10000 IOPS per GB
Silver:  1000 GB at 5000 IOPS per GB
Bronze:   500 GB at 5000 IOPS per GB&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Allow creation of qos_keys:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;read_iops_sec_per_gb
write_iops_sec_per_gb
total_iops_sec_per_gb&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;These function the same as our current &amp;lt;x&amp;gt;_iops_sec keys,
except they are scaled by the volume size.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;New optional qos spec values.&lt;/p&gt;
&lt;p&gt;Off by default, opt-in.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;eharney&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/447127/"&gt;https://review.openstack.org/#/c/447127/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Document new fields available in qos types.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;Code: &lt;a class="reference external" href="https://review.openstack.org/#/c/447127/"&gt;https://review.openstack.org/#/c/447127/&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Wed, 29 Mar 2017 00:00:00 </pubDate></item><item><title>Client reset-state improvements</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/pike/client-reset-state.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/client-reset-state-improvements"&gt;https://blueprints.launchpad.net/cinder/+spec/client-reset-state-improvements&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Improve “reset-state” in the cinder client shell.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;The reset-state implementation in the client shell has a few issues
that merit cleaning up:&lt;/p&gt;
&lt;p&gt;We have and are adding an &amp;lt;x&amp;gt;-reset-state operation for many objects
in Cinder.  This results in numerous commands when we could consolidate
these into one command.  Consolidating things into a single command
makes more sense because this is intended to be a rarely-used admin
fix-up tool, and not a prominent feature of our client.&lt;/p&gt;
&lt;p&gt;The current reset-state model also defaults to unsafe behavior.  It
will reset an object to “available” if a user runs it on an object
without other parameters.  This is not a safe path to use as a default
because we have no way to know if the object is actually in an
“available” state and resetting it to “available” will result in odd
problems later.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;This functionality addresses admins who need to repair broken
things in Cinder to workaround bugs or failed operations.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add a new argument to “cinder reset-state” so that it can handle
all of the types of objects we would like to reset the state of.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;See &lt;a class="reference external" href="https://review.openstack.org/#/c/413156/"&gt;https://review.openstack.org/#/c/413156/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Require state to be specified rather than defaulting to “available”.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is trickier to keep from breaking compatibility, but worthwhile.
The defaulting is done in the client.  We could handle this by adding
a stricter check in the client using the microversion checks, so that
using microversion 3.30+ requires the user to specify the desired
state, but when using older API versions, the previous behavior
is kept.  This does not correspond with an actual API change
on the server, but should work as a way to handle compat here.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Decide that we will no longer add &amp;lt;x&amp;gt;-reset-state operations to
the client shell.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;dl&gt;
&lt;dt&gt;(Optional:) We should consider looking at attach-status and&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;migration-status resets as well.  These are required to be specified
manually but there may be cases where it would be more consistent
to handle this for the caller.&lt;/p&gt;
&lt;p&gt;i.e. does it ever make sense to reset a volume to “available” and not
clear its attach status?&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Leave things as they are and keep adding new reset operations to the client
which default to hazardous behavior.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Start fixing things in Cinder that require use of reset state in the first
place.  (We should do this, but it’s a long, hard, project, and out of scope
here.)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;The cinderclient CLI changes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;We should design Cinder to not require use of reset-state as a
“regular” thing.&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Currently there’s a model, for some operations, of:&lt;/dt&gt;&lt;dd&gt;&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Request operation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Operation fails&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;User is notified that the operation failed by the object
now being in “error” state.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For some operations, the admin is now expected to reset
the state back to “available” to keep things functioning.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/dd&gt;
&lt;dt&gt;This could be done as:&lt;/dt&gt;&lt;dd&gt;&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Request operation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Operation fails&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Object is put back into previous state instead of “error”&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Client polls for operation status via our async messaging&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;User now knows what happened and the admin doesn’t have to
perform a reset.  The object is left in its “true” state.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Should consider what the intersection of reset-state and force-detach
looks like.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;eharney&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;tommylikehu&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Continue on &lt;a class="reference external" href="https://review.openstack.org/#/c/413156/"&gt;https://review.openstack.org/#/c/413156/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Covered by unit tests in the cinder client.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Cinder shell client documentation will need updates.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;cinderclient change: &lt;a class="reference external" href="https://review.openstack.org/#/c/413156/"&gt;https://review.openstack.org/#/c/413156/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;reset-state in openstackclient: &lt;a class="reference external" href="https://review.openstack.org/#/c/268907/"&gt;https://review.openstack.org/#/c/268907/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Obsoletes some of
pike/support-reset-generic-group-and-group-snapshot-status.rst&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;IRC meeting discussion: &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;http://eavesdrop.openstack.org/meetings/cinder/2017/cinder.2017-01-04-16.02.log.html#l-153&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Wed, 15 Feb 2017 00:00:00 </pubDate></item><item><title>Generic Volume Migration</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/liberty/generic-volume-migration.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/generic-volume-migration"&gt;https://blueprints.launchpad.net/cinder/+spec/generic-volume-migration&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The intent is to allow volume drivers that do not support iSCSI and use other
means for data transport to also participate in volume migration operations.
At the moment, the existing code uses create_export to create and attach
a volume via iSCSI to perform I/O operations.  By making this more generic, we
can allow other drivers to take part in volume migration as well.&lt;/p&gt;
&lt;p&gt;This change is necessary to support volume migration for the Ceph driver.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;When migrating a volume between two backends, the copy_volume_data routine in
the source volume’s driver is executed to move the blocks from one volume to
another. This routine assumes that both source and destination volumes can be
attached locally via iSCSI and calls create_export to attach the volume to the
local cinder-volume instance.  This is technically not necessary for local
volumes and also prevents drivers such as Ceph from participating in volume
migration operations.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;By using a file-like object abstraction similar to the backup volume driver
approach, we can allow the volume driver to determine how best to attach its
volume locally.  For most drivers, this will continue to be iSCSI.  And for
Ceph, a RBD object that support file semantics is returned.  In both cases, the
copy_volume_data routine operates on these file objects as it does now, but
without explicit knowledge of the underlying transport mechanism.&lt;/p&gt;
&lt;p&gt;Specifically, I would like to add a routine to the volume driver
(cinder/volume/driver.py):&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;::&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;open_volume()
close_volume()&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;These routines are called when doing local volume attachment as in
copy_volume_data().  I think these routines are necessary because local file
I/O operations may require different transport than the standard
create_export/initialize_connection approach.  In the case of Ceph,
create_export does nothing and initialize_connection returns the necessary RBD
connection info for Nova to communicate with the Ceph volume directly.  We want
driver authors to retain this flexibility.&lt;/p&gt;
&lt;p&gt;The open_volume routine will return a volume file object that supports file
operations such as read, write, seek, etc.  The close_volume routine will
handle teardown and cleanup of the volume file object.&lt;/p&gt;
&lt;p&gt;This will allow Ceph to return a file-like object that communicates directly
with the volume.  Other backends, such as LVM, will continue to create an iSCSI
export, attach it, open the resulting block device, and return a handle to this
file.  Additionally, local LVM volumes could skip the iSCSI step and open the
local block device directly.  This change could be made later, this effort is
to make the minimum amount of changes necessary to support the feature.&lt;/p&gt;
&lt;p&gt;With these driver routines in place, copy_volume_data is modified to make use
of these calls instead of the using _attach_volume directly.  For non-Ceph
drivers the result is exactly the same as it was.  And the RBD driver can now
implement these routines to add support for volume migration.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;The most obvious alternative is to change the Ceph driver to implement the
export routines and allow volume attachment via iSCSI.  This would mean using
the rbd kernel driver which is not ideal, as it introduces code into the
running kernel on the cinder-volume node and lags a bit in features as compared
to librbd.  We would like to avoid this if at all possible.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;If everything works correctly, volume migration between Ceph and some other
backend should function as expected.  In both directions.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;The additional abstraction only enables alternatives to iSCSI attachment, no
impact on existing functionality is introduced.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;jbernard&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Introduce the file-object abstraction and change existing code to use iSCSI
for volume attachment - just as it does now.  Ceph migration will continue
to fail.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement the Ceph-specific attach logic, that should allow volume migration
to succeed between other backends.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add test(s) to tempest to verify code paths are executed correctly and yield
a block-for-block identicaly migration result.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;I don’t think volume migration is covered in the gate, but this could be tested
in tempest.  Ceph volume migration to a non-Ceph backend should be successful
in both directions.  If that test passes, this effort was a success.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;I’m don’t think anything is necessary here.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Tue, 20 Dec 2016 00:00:00 </pubDate></item><item><title>Dynamic Log Level control via REST API</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/pike/dynamic-log-levels.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/dynamic-log-levels"&gt;https://blueprints.launchpad.net/cinder/+spec/dynamic-log-levels&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Add REST API to control Cinder services’ log levels dynamically.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;To change log levels in a service the service’s configuration needs to be
changed and the service restarted.  The restart can be done by restarting the
service itself or by requesting an internal restart via &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;SIGHUP&lt;/span&gt;&lt;/code&gt; signal.&lt;/p&gt;
&lt;p&gt;In some services a restart is not a big deal, API and scheduler, because they
only operate in the control plane and they don’t perform long running
operations, but in other services, Volume and Backup, this is a bigger deal,
because they are in the data plane as well and restarting of a service may take
a long time.&lt;/p&gt;
&lt;p&gt;We should be able to change service log levels dynamically as needed, even if
they will revert back to the defaults on restart.&lt;/p&gt;
&lt;p&gt;A downside to being able to dynamically change log levels is that we’ll no
longer be sure of what log level a service is running at a given time, so we’ll
also need a mechanism to query current log levels of a service.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;Cloud users are encountering problems when using the cloud and they contact
support, so the system operator starts looking at the logs only to find out
that correct log levels are insufficient to determine the root cause of the
problem and the log levels need to be changed to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DEBUG&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Another use case that would be satisfied by the implementation of this spec as
a side product would be when a system administrator wants to confirm Message
Broker connectivity in a service, as the log level query mechanism can be used
as a ping to the service via the Message Broker.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;The proposal is to introduce 2 new service REST APIs actions, one to modify
debug levels at runtime and another to query them.  The life of the log level
changes will be the current service run, as they will revert to those defined
in the configuration file upon restart.&lt;/p&gt;
&lt;p&gt;Setting the log levels will be possible for all Volume, Scheduler, and Backup
services, but limited in the API service to only the service process that
receives the request since there is no mechanism in place right now to
propagate the request to other API nodes and adding such mechanism for this
feature would be an unnecessary complexity at this point.&lt;/p&gt;
&lt;p&gt;This is a reasonable limitation, since API services can be easily restarted
without impacting the cloud because they are only in the control plane and are
usually deployed in an Active/Active configuration.  And if they are not in an
Active/Active configuration then there’s only 1 API service running and not
being able to propagate the API log level change isn’t such a big deal.&lt;/p&gt;
&lt;p&gt;While some operators may prefer to restart the API services to change the log
levels, there may be others that prefer to directly make the dynamic log level
changes to the all the API nodes skipping the load balancer to avoid restarts,
and some others that will just change one API node dynamically skipping the
load balancer and make the test request to that one API node.&lt;/p&gt;
&lt;p&gt;The mechanism to set the log level should be versatile enough that no scripting
is necessary when we want to do multiple changes.  The way to achieve this will
be to allow changing log levels to all addressable services or limit by binary
and/or server.&lt;/p&gt;
&lt;p&gt;It’ll also be possible to decide which log levels to change in the service, so
we’ll be able to not only change the log levels of the cinder service itself,
but also those of its libraries (ie. SQLAlchemy library).&lt;/p&gt;
&lt;p&gt;Both mechanism will allow setting/querying multiple services but will only work
on services that are up as per DB heartbeats.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;An alternative would be to support Dynamic Reconfiguration after modifying
cinder.conf, but that is a considerably bigger problem that will require more
code changes, and while it’ll be more powerful it has also some drawbacks,
since it requires access to the nodes to change the configuration of each of
the services and also trigger the reload of each of them.&lt;/p&gt;
&lt;p&gt;The benefit of having an API for the log levels is that you don’t have to have
access to the infrastructure as you can request the change through the REST API
and then check the logs in the log monitoring service.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Set log level: This will be implemented as a service action like &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;enable&lt;/span&gt;&lt;/code&gt;
and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;disable&lt;/span&gt;&lt;/code&gt;, but will use the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;set-log&lt;/span&gt;&lt;/code&gt; identifier.  Effective URL
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/v3/{tenant_id}/os-services/set-log&lt;/span&gt;&lt;/code&gt; will take following parameters in the
body:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;binary&lt;/span&gt;&lt;/code&gt; (optional): A string parameter indicating the binary of the
service to change, it can take following values, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cinder-volume&lt;/span&gt;&lt;/code&gt;,
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cinder-scheduler&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cinder-backup&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cinder-api&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;*&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;null&lt;/span&gt;&lt;/code&gt;,
empty string or be missing.  The last four possibilities being equivalent
to all services.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;server&lt;/span&gt;&lt;/code&gt; (optional): A string parameter indicating the server to change,
Can be a host or cluster reference - &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;host@backend&lt;/span&gt;&lt;/code&gt; or
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cluster@backend&lt;/span&gt;&lt;/code&gt; -, or &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;null&lt;/span&gt;&lt;/code&gt;, empty string, or be missing for all
servers matching the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;binary&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;prefix&lt;/span&gt;&lt;/code&gt; (optional): A string indicating the prefix for the log path, for
example &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cinder.&lt;/span&gt;&lt;/code&gt; or &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;sqlalchemy.engine&lt;/span&gt;&lt;/code&gt;.  When not present all logs
will be changed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;level&lt;/span&gt;&lt;/code&gt; (required): A string with the log level to set, case insensitive,
accepted values are &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;INFO&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;WARNING&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ERROR&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DEBUG&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Get log level: Service action with &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;get-log&lt;/span&gt;&lt;/code&gt; identifier.  Effective URL
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/v3/{tenant_id}/os-services/get-log&lt;/span&gt;&lt;/code&gt; will accept the following parameters
in the body:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;binary&lt;/span&gt;&lt;/code&gt; (optional): A string parameter indicating the binary of the
service to query, it can take following values, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;*&lt;/span&gt;&lt;/code&gt;, empty string,
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;null&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cinder-volume&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cinder-scheduler&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cinder-backup&lt;/span&gt;&lt;/code&gt;, and
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cinder-api&lt;/span&gt;&lt;/code&gt;.  If missing or &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;*&lt;/span&gt;&lt;/code&gt; or the an empty string is passed then
all binaries will be used.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;server&lt;/span&gt;&lt;/code&gt; (optional): A string parameter indicating the server to query,
Can be a host or a cluster reference - &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;host@backend&lt;/span&gt;&lt;/code&gt; or
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cluster@backend&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;prefix&lt;/span&gt;&lt;/code&gt; (optional): A string indicating the prefix for the log path we
are querying, for example &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cinder.&lt;/span&gt;&lt;/code&gt; or &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;sqlalchemy.engine&lt;/span&gt;&lt;/code&gt;.  When not
present  or the empty string is passed all log levels will be retrieved.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Example response to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;get-log&lt;/span&gt;&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="s2"&gt;"log_levels"&lt;/span&gt;&lt;span class="p"&gt;:[&lt;/span&gt;
       &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="s2"&gt;"binary"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"cinder-api"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"host"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"hostname1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"levels"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;
             &lt;span class="s2"&gt;"cinder.api"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"DEBUG"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"cinder.api.common"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"DEBUG"&lt;/span&gt;
             &lt;span class="s2"&gt;"cinder.db.sqlalchemy.api"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"DEBUG"&lt;/span&gt;
       &lt;span class="p"&gt;},&lt;/span&gt;
       &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="s2"&gt;"binary"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"cinder-scheduler"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"host"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"hostname1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"levels"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;
             &lt;span class="s2"&gt;"cinder"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"DEBUG"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"cinder.scheduler.manager"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"DEBUG"&lt;/span&gt;
             &lt;span class="s2"&gt;"eventlet"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ERROR"&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
       &lt;span class="p"&gt;},&lt;/span&gt;
       &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="s2"&gt;"binary"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"cinder-volume"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"host"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"hostname2@backend#pool"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"levels"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;
             &lt;span class="s2"&gt;"cinder"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"DEBUG"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"cinder.volume.drivers.rbd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"DEBUG"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"sqlalchemy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"WARNING"&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
       &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None, since it will be using the service update Access Control policy used for
operations like enable, disable, and freeze…&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;For audit purposes a new notification will be emitted with every dynamic log
level change.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None besides the possible increase in log quantity when changed to a greater
log level, for example debug.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Gorka Eguileor (geguileo)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add the set API endpoint and mechanism on the services&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cinder client support for set action&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the get API endpoint and mechanism on the services&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cinder client support for get action&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unittests for new API behavior.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Only the changes to the API need to be documented.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="_design_meetup"&gt;Ocata Design Summit Contributor Meetup Etherpad&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/dynamic-reconfiguration/"&gt;Dynamic Reconfiguration&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Tue, 29 Nov 2016 00:00:00 </pubDate></item><item><title>Introduce new volume attach APIs</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/ocata/add-new-attach-apis.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/add-new-attach-apis"&gt;https://blueprints.launchpad.net/cinder/+spec/add-new-attach-apis&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;The current volume attach process for Cinder Volumes is somewhat inconsistent
and rather unclear in terms of exactly how it works.  Some of this has been
a result of growth and feature adds, things like optional parameters have made
the process a bit more complex than it needs to be.&lt;/p&gt;
&lt;p&gt;The interpretation of things like initialize_connection has sort of diverged a
bit, and due to some requirements for different backends things have become a
bit hacky.  We have the potential for race conditions during the attach/detach
process and most of all we seem to have a situation where adding things like
multi-attach support are extremely complex and difficult.&lt;/p&gt;
&lt;p&gt;Rather than continuing to add on to the monolith, it might be a good time to
step back and simplify the flow altogether.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;Attaching Cinder volumes to Nova Instances, Bare Metal or whatever.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Rather than using reserve, initialize and attach with numerous parameters to
chain together an attach, and try to modify things to make multi-attach work
this specs proposes that we instead introduce a new simplified and more robust
set of attach API’s.&lt;/p&gt;
&lt;p&gt;API Operations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;attachment_create&lt;/p&gt;
&lt;p&gt;This call is used to create a volume attachment.&lt;/p&gt;
&lt;p&gt;If the connector is not specified this call will only complete the volume
reservation step and create an empty volume attachment. This can be used
by Nova to call it from the API and start the volume attaching process by
checking that the volume is available and creates the empty attachment. To
finalize the operation Nova will call ‘attachment_update’.&lt;/p&gt;
&lt;p&gt;In case the connector is specified it will reserve the volume and create the
connection between the volume and the host and update the attachment record.
This can be used for instance for bare metal use cases, when the connector is
available immediately.&lt;/p&gt;
&lt;p&gt;In both cases the call returns the attachment_id to the caller.&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Args:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;volume_id
instance_uuid
connector (optional)&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Returns:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;attachment_id&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;attachment_update&lt;/p&gt;
&lt;p&gt;This call is used to update an existing volume attachment. For this call the
connector is mandatory.&lt;/p&gt;
&lt;p&gt;In case of an empty attachment it also finalizes attaching the volume and
updates the attachment record accordingly.&lt;/p&gt;
&lt;p&gt;As the attachment exists in every scenario this call is invoked the
attachment_id is mandatory.&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Args:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;attachment_id
connector&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Returns:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;connection_info&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;attachment_get&lt;/p&gt;
&lt;p&gt;This call will fetch the specified attachment object (by ID).  In addition
this call will go out to the Cinder backend driver and query it for any
shared connection info.  The purpose being that we return the attachment
object that was requested as well as a list of any shared attachment_id’s.&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;Args:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;attachment_id&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Returns:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Attachment info&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;{id: &amp;lt;uuid-of-the-attachment-object&amp;gt;,&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;project_id: &amp;lt;project-id-associated-with-attachment&amp;gt;,
volume_id: &amp;lt;uuid-of-volume-associated-with-this-attachment-record&amp;gt;,
instance_uuid: &amp;lt;uuid-of-instance-attachment-is-used-for&amp;gt;,
attached_host: &amp;lt;hostname-of-compute-node-attached-to&amp;gt;,
mountpoint: &amp;lt;mountpoint-inside-instance-that-is-expected-to-be-used&amp;gt;,
attach_time: &amp;lt;time-we-created-the-attachment&amp;gt;,
detach_time: &amp;lt;time-we-detached&amp;gt;,
attach_status: &amp;lt;status-of-the-attachment&amp;gt;,
attach_mode: &amp;lt;ro|rw&amp;gt;,
shared_connections_by_attachment: [&amp;lt;attachment_id&amp;gt;, …]}&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;attachment_remove&lt;/p&gt;
&lt;p&gt;Removes/Detaches an existing attachment, marks a volume as available if no
more attachments to it left.&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Args:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;attachment_id&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Returns:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;List of attachment_id’s for any shared connections&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Keep trying to hack our way around the existing attach/detach flows we have.
Deal with the split brain issue we have between Nova and Cinder.&lt;/p&gt;
&lt;p&gt;It is possible that we could rewrite the existing methods and enforce stricter
interface usage and we’d probably be ok, but the code has become pretty
convoluted and ugly to deal with and it might be easier to wrap the existing
calls up into a managing wrapper and then over time iterate over the internal
pieces.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;We need to store the connector when making attachments. As the connector can
vary based on the back end and can also easily exceed 255 chars in length
adding it to the ‘volume_attachment’ table is not a viable option. As opposed
to that we’ll add an ‘attachment_specs’ table that will slurp in the k/v
entries in the connector.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;This will introduce at least the 4 new calls mentioned in the proposal section,
these will be part of a new API object named &lt;cite&gt;attachment&lt;/cite&gt;.  We’ll treat the
attachment as a first class object in Cinder.&lt;/p&gt;
&lt;p&gt;The new API will be released under a new microversion.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;The old API’s will still work until we decide to deprecate them.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;For now this is avoiding changes to the drivers in Cinder and focusing on
just the API for the attach/detach call up until the Manager layer.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;p&gt;Condense initialize_connection and attach down into a single attachment_create
call.&lt;/p&gt;
&lt;p&gt;The intent here is that Cinder shouldn’t know or care so much about what a
consumer is doing with a volume or attachment.  We should only care that they
desire to attach or detach and that’s about it.  In order to do this properly
we will need an attachment_id that the consumer should store and reference
going forward when they are done with the attachment.  This means it’s up to
the consumer to decide when they are truly done and they want to destroy the
attachment as opposed to now where we try and guess for them based on clues.&lt;/p&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;john-griffith&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Implement API calls and wrappers in Cinder&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement cinderclient calls to expose them&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement changes in Nova&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Once the API design is finalized the same Tempest test coverage will be added
as we have for the current attach/detach API. In parallel to this activity the
Nova implementation to pick up the new API shall be started as well which will
add an additional layer of testing.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Will need to update any and all documents about how attach/detach of
volumes in Cinder works.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/373203/"&gt;Nova spec&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
</description><pubDate>Fri, 26 Aug 2016 00:00:00 </pubDate></item><item><title>Parameter combinations for delete (vol, snap, etc.)</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/newton/delete-parameters.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/volume-delete-parameters"&gt;https://blueprints.launchpad.net/cinder/+spec/volume-delete-parameters&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This spec outlines how to improve our volume delete functionality
with regards to optional parameters which request non-default
behaviors.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;It is not possible to combine both volume force delete and cascade delete.&lt;/p&gt;
&lt;p&gt;It is also difficult to add more parameters to volume delete, since
they have to interact in a reasonable way with things like os-force-delete,
which is part of volume delete from a user’s point of view, but not the
same API action.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;This makes it easier to delete a volume which may be in an odd state.&lt;/p&gt;
&lt;p&gt;It also simplifies our API by passing optional parameters to delete
rather than separate action calls.  This allows us to combine the parameters
in meaningful ways (force + cascade), as well as extend the same combinations
to snapshot-delete, cg-delete, etc., without having to make X delete API
actions for each parameter. (eg. os-force-delete, os-force-delete-snapshot,
os-force-delete-cg, etc.)&lt;/p&gt;
&lt;p&gt;Also consider if we wish to add the option later to delete an
attached volume with a “force-detach” parameter, etc.&lt;/p&gt;
&lt;p&gt;This also should reduce the number of cases where an admin/user needs to use
reset-state operations.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Deprecate use of os-force-delete and make “force” a parameter passed to
volume delete like “cascade” is.&lt;/p&gt;
&lt;p&gt;The ability to default “force” to be an admin-only operation via config
will be maintained.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Change nothing.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;New boolean “force” parameter for volume delete,
which defaults to False.&lt;/p&gt;
&lt;p&gt;This will behave the same as os-force-delete if not
combined with other arguments.&lt;/p&gt;
&lt;p&gt;If combined with cascade, a cascade delete which
ignores the volume and snapshot states will be performed.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;$ cinder delete –force –cascade &amp;lt;volume&amp;gt;&lt;/p&gt;
&lt;p&gt;will be accepted.  This gives a “delete this volume regardless
of the state of things” operation which does not exist today.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;eharney&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add “force” as a parameter to volume delete API&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add logic to handle combination of force and cascade&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;(eventually) remove os-force-delete with a new API microversion&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Look at what to do, if anything, in this same regard for
“unmanage”, e.g., “unmanage –cascade”.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;New tempest test for volume delete which uses the parameterized
version rather than os-force-delete.&lt;/p&gt;
&lt;p&gt;Tempest test for cascade + force volume delete.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;New arguments for cinderclient volume delete.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Cascade delete
&lt;a class="reference external" href="https://review.openstack.org/#/c/201748/"&gt;https://review.openstack.org/#/c/201748/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Mon, 23 May 2016 00:00:00 </pubDate></item><item><title>Inspection Mechanism For Capacity Limited Host</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/queens/inspection-mechanism-for-capacity-limited-host.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/inspection-mechanism-for-capacity-limited-host"&gt;https://blueprints.launchpad.net/cinder/+spec/inspection-mechanism-for-capacity-limited-host&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Cinder now has a scheduler filter called &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;CapacityFilter&lt;/span&gt;&lt;/code&gt; which allow users
to create volume under capacity limit. But some APIs which don’t go through
cinder-scheduler will break the destination host’s capacity.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Some backends now support the thin provisioning capability. But only Cinder
gets and checks this capability in cinder-scheduler’s filter: CapacityFilter.
It means that some APIs which go to the backend directly without
cinder-scheduler doesn’t get and check the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;reserved_percentage&lt;/span&gt;&lt;/code&gt; and the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;max_over_subscription_ratio&lt;/span&gt;&lt;/code&gt; of the backend. Then it may break the backend’s
capacity. Such as “extend volume”, “create volume from snapshot”, “copy volume”
and so on.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;Usually, the capacity is a hard limit for the specified backend when Cinder
works with the CapacityFilter (It is one of the default filters in Cinder). It
means that every action to this kind of backend should keep its capacity. We
should not break the capability of the backend which support the thin
provisioning.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add some common functions to check the backend’s capacity at the
cinder-volume layer. The patch[1] is a POC to solve volume creation problem.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The APIs which 1) change the backend’s capacity and, 2) don’t go through
cinder-scheduler, should be directly checked. It includes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;POST /v3/{project_id}/volumes/{volume_id}/action  (os-extend)  (SOLVED)[2]&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;POST /v3/{project_id}/volumes  (create from snapshot, volume or replica)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;POST /v3/{project_id}/groups/action (create_from_src)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;POST /v3/{project_id}/snapshots&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;NOTE:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create volume requests for a snapshot, volume, or replica will change the
backend’s capacity, and will therefore cause the volume’s status to switch to
“error”.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The cinder admin isn’t required to use the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;CapacityFilter&lt;/span&gt;&lt;/code&gt;, since the
volume capacity limit doesn’t need to be checked at the driver layer.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;For the APIs which will change the backend’s capacity and not go through
cinder-scheduler, we could route them through the scheduler instead of jumping
right to a volume-service.&lt;/p&gt;
&lt;p&gt;The problem for the extend API is solved by a bug fix[2] recently.
In the patch, it passes a “volume” parameter which includes the host name to
cinder-scheduler to indicate that the destination host is specified. Then
cinder-scheduler will only check the specified host with
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;backend_passes_filters&lt;/span&gt;&lt;/code&gt; function. If no error raises, it means that the POST
action is allowed.&lt;/p&gt;
&lt;p&gt;NOTE:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;We need to bump the RPC call’s version between cinder-api and
cinder-scheduler to keep backward compatibility for each related API.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The create actions will always call through the cinder-scheduler, even if
the destination host is specified. If the cinder-scheduler can’t match the
new RPC version, the old behavior is kept.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;Instead of sending notifications, we’d better send user messages if the actions
fail.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;The create requests which will exceed the backend’s capacity will make the
volume’s status to “error”.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;wangxiyuan &amp;lt;&lt;a class="reference external" href="mailto:wangxiyuan%40huawei.com"&gt;wangxiyuan&lt;span&gt;@&lt;/span&gt;huawei&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;
Huang Zhiteng &amp;lt;&lt;a class="reference external" href="mailto:winston.d%40gmail.com"&gt;winston&lt;span&gt;.&lt;/span&gt;d&lt;span&gt;@&lt;/span&gt;gmail&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;
Erlon R. Cruz &amp;lt;&lt;a class="reference external" href="mailto:sombrafam%40gmail.com"&gt;sombrafam&lt;span&gt;@&lt;/span&gt;gmail&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;
tommylikehu&amp;lt;&lt;a class="reference external" href="mailto:tommylikehu%40gmail.com"&gt;tommylikehu&lt;span&gt;@&lt;/span&gt;gmail&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add some common check functions and call them in:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;create volume from volume, snapshot or replica&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;create cg from source&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;create group from source&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;create snapshot&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add and update the unit test.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit tests will be added and updated.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;[1] Huang Zhiteng: &lt;a class="reference external" href="https://review.openstack.org/#/c/437677/"&gt;https://review.openstack.org/#/c/437677/&lt;/a&gt;
[2] Erlon R.Cruz: &lt;a class="reference external" href="https://review.openstack.org/#/c/405578/"&gt;https://review.openstack.org/#/c/405578/&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 21 Apr 2016 00:00:00 </pubDate></item><item><title>Stochastic Weighing Scheduler</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/newton/stochastic-weighing-scheduler.html</link><description>

&lt;p&gt;Include the URL of your launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/stochastic-weighing-scheduler"&gt;https://blueprints.launchpad.net/cinder/+spec/stochastic-weighing-scheduler&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The filter scheduler is the de-facto standard scheduler for Cinder and has
a lot of desirable properties. However there are certain scenarios where it’s
hard or impossible to get it to do the right thing. I think some small tweaks
could help make admin’s lives easier.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;I’m concerned about 2 specific problems:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;When there are multiple backends that are not identical, it can be hard to
ensure that load is spread across all the backends. Consider the case of a
few “large” backends mixed with some “small” backends. Even if they’re from
the same vendor by default new volumes will go exclusively to the large
backends until free space decreases to the same level as the small backends.
This can be worked around by using something other than free space to weigh
hosts, but no matter what you choose, you’ll have a similar issue whenever
the backends aren’t homogeneous.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Even if the admin is able to ensure that all the backends are identical in
every way, at some point the cloud will probably need to grow, by adding
new storage backends. When this happens there will be a mix of brand new
empty backends and mostly full backends. No matter what kind of weighing
function you use, initially 100% of new requests will be scheduled on the
new backends. Depending on how good or bad the weighing function is, it
could take a long time before the old backends start receiving new requests
and during this period system performance is likely to drop dramatically.
The problem is particularly bad if the upgrade is a small one: consider
adding 1 new backend to a system with 10 existing backends. If 100% of
new volumes go to the new backend, then for some period, there will be 10x
load on the single backend.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;There is one existing partial solution to the above problems – the goodness
weigher – but that has some limitations worth mentioning. Consider an ideal
goodness function – an oracle that always returns the right value such
that the best backend for new volumes is sorted to the top. Because the inputs
to the goodness function (other than available space) are only evaluated every
60 seconds, bursts of creation requests will nearly always go to the same
backend within a 60 second window. While we could shrink the time window of
this problem by sending more frequent updates, that has its own costs and also
has diminishing returns. In the more realistic case of a goodness function
that’s non-ideal, it may take longer than 60 seconds for the goodness function
output to reflect changes based on recent creation requests.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;The existing scheduler handles homogeneous backends best, and relies on a
relatively low rate of creation requests compared to the capacity of the whole
system, so that it can get keep up to date information with which to make
optimal decisions. It also deals best with cases when you don’t add capacity
over time.&lt;/p&gt;
&lt;p&gt;I’m interested in making the scheduler perform well across a broad range of
deployment scenarios:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Mixed vendor scenarios&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A mix of generations of hardware from a single vendor&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A mix of capacities of hardware (small vs. large configs)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Adding new capacity to a running cloud to deal with growth&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;These are all deployer/administrator concerns. Part of the proposed solution
is to enable certain things which are impossible today, but mostly the goal
is to make the average case “just work” so that administrators don’t have to
babysit the system to get reasonable behavior.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Currently the filter scheduler does 3 things:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Takes a list of all pools and filters out the ones that are unsuitable for
a given creation request.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Generates a weight for each pool based on one of the available weighers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sorts the pools and chooses the one with the highest weight.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I call the above system “winner-take-all” because whether the top 2 weights
are 100 and 0 or 49 and 51, the winner gets the request 100% of the
time.&lt;/p&gt;
&lt;p&gt;I propose adding a new option to the filter scheduler called
“weighted_stochastic”. It should default to False, which would give the
current winner-take-all behavior. If set to True however, the scheduling
algorithm would change as follows:&lt;/p&gt;
&lt;p&gt;In step 3 above, rather than simply selecting the highest weight, the
scheduler would sum up the weight of all choices, assign each pool a subset of
that range with a size equal to that host’s weight, then generate a random
number across the whole range and choose the pool mapped to that range.&lt;/p&gt;
&lt;p&gt;An easier way to visualize the above algorithm is to imagine a raffle drawing.
Each pool is given a number of raffle tickets equal to the pool’s weight
(assume weights normalized from 0-100). The winning pool is chosen by a raffle
drawing. Every creation request results in a new raffle being held.&lt;/p&gt;
&lt;p&gt;Pools with higher weights get more raffle tickets and thus have a higher
chance to win, but any pool with a weight higher than 0 has some chance to
win.&lt;/p&gt;
&lt;p&gt;The advantage to the above algorithm is that it distinguishes between weights
that are close (49 and 51) vs weights that are far (0 and 100) so just because
one pools is slightly better than another pool, it doesn’t always win. Also,
it can give different results within a 60 second window of time when the
inputs to the weigher aren’t updated, significantly decreasing the pain of
slow volume stats updates.&lt;/p&gt;
&lt;p&gt;It should be pointed out that this algorithm not only requires that weights
are properly normalized (the current goodness weigher also requires this) but
that the weight should be roughly linear across the range of possible values.
Any deviation from linear “goodness” can result in bad decisions being made,
due to the randomness inherent in this approach.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;There aren’t many good options to deal with the problem of bursty requests
relative to the update frequency of volume stats. You can update stats faster
but there’s a limit. The limit is to have the scheduler synchronously request
absolute latest volume stats from every backend for every request. Clearly
that approach won’t scale.&lt;/p&gt;
&lt;p&gt;To deal with the heterogeneous backends problem, we have the goodness
function, but it’s challenging to pick a goodness function that yields
acceptable results across all types of variation in backends. This proposal
keeps the goodness function and builds upon it to both make it stronger, and
also more tolerant to imperfection.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;No database changes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;No REST API changes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;No security impact.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;No notification impact.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;End users may indirectly experience better (or conceivably worse) scheduling
choices made by the modified scheduler.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;No performance impact. In fact this approach is proposed expressly because
alternative solutions would have a performance impact and I want to avoid
that.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;I propose a single new config option for the scheduler. The default value for
this option is to act like the existing scheduler does. An administrator would
need to intentionally enable to option to observe changed behavior.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Developers wouldn’t be directly impacted, but anyone working on goodness
functions or other weighers would need to be aware of the linearity
requirement for getting good behavior out of this new scheduler mode.&lt;/p&gt;
&lt;p&gt;In order to avoid accidentally feeding nonlinear goodness values into the
stochastic weighing scheduler, we may want to create alternatively-named
version of the various weights or weighers, forcing driver authors to
explicitly opt-in to the new scheme and thus indicate that the weights
they’re returning are suitably linear.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;bswartz&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;This should be doable in a single patch.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Filter scheduler (cinder)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Goodness weigher (cinder)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Testing this feature will require a multibackend configuration (otherwise
scheduling is just a no-op).&lt;/p&gt;
&lt;p&gt;Because randomness is inherently required for the correctness of the
algorithm, it will be challenging to write automated functional test cases
without subverting the random number generation. I propose that we rely on
unit tests to ensure correctness because it’s easy to “fake” random numbers
in unit tests.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Dev docs need updated to explain to driver authors what the expectations are
for goodness functions.&lt;/p&gt;
&lt;p&gt;Config ref needs to explain to deployers what the new config option does.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;No references.&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Mon, 18 Apr 2016 00:00:00 </pubDate></item><item><title>Add Generic Volume Group Into Quota Management</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/pike/add-volumegroup-into-quota-management.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/add-volumegroup-into-quota-management"&gt;https://blueprints.launchpad.net/cinder/+spec/add-volumegroup-into-quota-management&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Generic Volume Group currently has its own quota mechanism. But we can’t get
any information about the Generic Volume Group quota at the API layer.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Cinder already achieved Generic Volume Group quota mechanism. It means that
there is a Generic Volume Group quota class(the hard_limit is 10) at the DB
layer. But the Generic Volume Group’s quota information wasn’t contained in any
quota API’s response body, so that users can’t get or update it.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;Cinder should allow users to get and update the Generic Volume Group’s quota.
It’s terrible that users could only use the Generic Volume Group quota’s
default value and can’t update it. With this change, users could 1) change the
value of Generic Volume Group’s hard limit, 2) get the Generic Volume Group’s
quota usage, through the Cinder’s quota API.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Let quota management undertake Generic Volume Group quota. And these five APIs
will be changed:
1) quota-class-show&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;quota&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;sets&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;default&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Add a new line in the response body.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"quota_class_set"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"groups"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;2) quota-show, quota-usage&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;GET /os-quota-sets/{project_id}?usage={False, True}
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Add a new line in the response body.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"quota_set"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"groups"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"reserved"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"allocated"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"limit"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"in_use"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;3) quota-defaults&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;quota&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;sets&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;defaults&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Add a new line in the response body.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"quota_set"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"groups"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;4) quota-class-update&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;PUT&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;quota&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;sets&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;default&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Allow update “groups” and Add a new line in the response body.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"quota_class_set"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"groups"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;5) quota-update&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;PUT&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;quota&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;sets&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Allow update “groups” and Add a new line in the response body.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"quota_set"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"groups"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Leave as is.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The response body of “quota-defaults”, “quota-usage”, “quota-show” and
“quota-class-show” APIs will contain Generic Volume Group.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The “quota-update” and “quota-class-update” APIs will accept the
“groups” parameter and the response body will contain Generic Volume Group.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;wangxiyuan&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add Generic Volume Group’s quota to quota APIs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add and update the unit tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update the CinderClient’s quota commands&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Standard unit tests and manual testing.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The response body of quota-defaults, quota-usage, quota-show and
quota-class-show should be updated.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The request body of quota-update, quota-class-update should be updated.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Mon, 18 Apr 2016 00:00:00 </pubDate></item><item><title>Support volume migration in Ceph driver</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/newton/ceph-volume-migrate.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/ceph-volume-migrate"&gt;https://blueprints.launchpad.net/cinder/+spec/ceph-volume-migrate&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Currently cinder supports volume migration with backend assistance.
Some backends like IPSANs support migrating volume in backend level, but
Ceph does not. Though Ceph volume migration has already been supported through
cinder generic migration process in Liberty, the migration efficiency is not
so good. It is necessary to support volume migration in the Ceph driver to
improve the efficiency of migration.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Suppose there are two cinder volume backends which are in the same Ceph
storage cluster.&lt;/p&gt;
&lt;p&gt;Now volume migration between two Ceph volume backends is implemented by
generic migration logic. Migration operation can proceed with file operations
on handles returned from the os-brick connectors, but the migration efficiency
is limited on file I/O speed. If we offload migration operation from
cinder-volume host to Ceph storage cluster, we would get the following
benefits:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Improve the volume migration efficiency between two Ceph storage pools,
especially when the volume’s capacity and data size is big.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reduce the IO pressure on cinder-volume host when doing the volume
migration.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;There are three cases for volume migration. The scope of this spec is for
the available volumes only and targets to resolve the issues within
the following migration case 1:&lt;/p&gt;
&lt;p&gt;Within the scope of this spec:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;1.Available volume migration between two pools from the same Ceph cluster.&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Out of the scope of the spec:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;2.Available volume migration between Ceph and other vendor driver.&lt;/p&gt;
&lt;p&gt;3.In-use(attached) volume migration using Cinder generic migration.&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Solution A: use rbd.Image.copy(dest_ioctx, dest_name) function to migrate
volume from one pool to another pool.&lt;/p&gt;
&lt;p&gt;To offload migration operation from cinder-volume host to ceph cluster,
we need to do the following changes in migrate_volume routine in RBD driver.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Check whether source volume backend and destination volume backend are
in the same ceph storage cluster or not.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If not, return (False, None).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If yes, use rbd.Image.copy(dest_ioctx, dest_name) function to copy volume
from one pool to another pool.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete the old volume.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Solution B: use ceph’s functions of clone image and flatten clone image to
migrate volume from one pool to another pool.&lt;/p&gt;
&lt;p&gt;Solution B contains the following steps:
* Create source volume snapshot snap_a and protect the snapshot snap_a.
* Clone a child image image_a of snap_a to the destination pool.
* Flatten the child image image_a, thus snap_a has not been depended on.
* Unprotect the snapshot snap_a and delete it.&lt;/p&gt;
&lt;p&gt;Using a volume which’s capacity and data size is 12GB to show the
time-consuming comparison between solution A and solution B.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;[Solution-A]Copy volumes1/volume-777617f2-e286-44b8-baff-d1e8b792cc52
from “volumes1” pool to “volumes2” pool.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;root@2C5_19_CG1# time rbd cp
volumes1/volume-777617f2-e286-44b8-baff-d1e8b792cc52 volumes2/test1&lt;/p&gt;
&lt;p&gt;Image copy: 100% complete…done.&lt;/p&gt;
&lt;p&gt;real    2m3.513s
user    0m9.983s
sys     0m25.213s&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[Solution-B-step-1]Create a snapshot of volume
777617f2-e286-44b8-baff-d1e8b792cc52 and protect it.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;root@2C5_19_CG1# time rbd snap create –pool volumes1 –image
volume-777617f2-e286-44b8-baff-d1e8b792cc52 –snap snap_test&lt;/p&gt;
&lt;p&gt;real    0m0.465s
user    0m0.050s
sys     0m0.016s&lt;/p&gt;
&lt;p&gt;root@2C5_19_CG1# time rbd snap protect
&lt;a class="reference external" href="mailto:volumes1/volume-777617f2-e286-44b8-baff-d1e8b792cc52%40snap_test"&gt;volumes1/volume-777617f2-e286-44b8-baff-d1e8b792cc52&lt;span&gt;@&lt;/span&gt;snap_test&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;real    0m0.128s
user    0m0.057s
sys     0m0.006s&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[Solution-B-step-2]Do clone operation on
&lt;a class="reference external" href="mailto:volumes1/volume-777617f2-e286-44b8-baff-d1e8b792cc52%40snap_test"&gt;volumes1/volume-777617f2-e286-44b8-baff-d1e8b792cc52&lt;span&gt;@&lt;/span&gt;snap_test&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;root@2C5_19_CG1# time rbd clone
&lt;a class="reference external" href="mailto:volumes1/volume-777617f2-e286-44b8-baff-d1e8b792cc52%40snap_test"&gt;volumes1/volume-777617f2-e286-44b8-baff-d1e8b792cc52&lt;span&gt;@&lt;/span&gt;snap_test&lt;/a&gt;
volumes2/snap_test_clone&lt;/p&gt;
&lt;p&gt;real    0m0.336s
user    0m0.058s
sys     0m0.012s&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[Solution-B-step-3]Flatten the clone image volumes2/snap_test_clone.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;root@2C5_19_CG1# time rbd flatten volumes2/snap_test_clone
Image flatten: 100% complete…done.&lt;/p&gt;
&lt;p&gt;real    1m58.469s
user    0m4.513s
sys     0m17.181s&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[Solution-B-step-4]Unprotect the snap
&lt;a class="reference external" href="mailto:volumes1/volume-777617f2-e286-44b8-baff-d1e8b792cc52%40snap_test"&gt;volumes1/volume-777617f2-e286-44b8-baff-d1e8b792cc52&lt;span&gt;@&lt;/span&gt;snap_test&lt;/a&gt; and
delete it.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;root@2C5_19_CG1# time rbd snap unprotect
&lt;a class="reference external" href="mailto:volumes1/volume-777617f2-e286-44b8-baff-d1e8b792cc52%40snap_test"&gt;volumes1/volume-777617f2-e286-44b8-baff-d1e8b792cc52&lt;span&gt;@&lt;/span&gt;snap_test&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;real    0m0.150s
user    0m0.058s
sys     0m0.013s&lt;/p&gt;
&lt;p&gt;root@2C5_19_CG1# time rbd snap rm
&lt;a class="reference external" href="mailto:volumes1/volume-777617f2-e286-44b8-baff-d1e8b792cc52%40snap_test"&gt;volumes1/volume-777617f2-e286-44b8-baff-d1e8b792cc52&lt;span&gt;@&lt;/span&gt;snap_test&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;real    0m0.418s
user    0m0.054s
sys     0m0.011s&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;By the above test results of solution A and solution B, solution A needs
(real:2m3.513s, user:0m9.983s, sys:0m25.213s) to finish the volume copy
operation and solution B needs (real:1m59.966s, user:0m4.790s, sys:0m17.239s)
to do that. The time-consuming for the both two solutions are not much
difference, but solution A is more simpler than solution B. So we intend to
use solution A to offload volume migration from cinder-volume host to ceph
cluster.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;The performance of volume migration between two Ceph storage pools
in the same Ceph cluster will be improved greatly.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;chen-xueying1&amp;lt;&lt;a class="reference external" href="mailto:chen.xueying1%40zte.com.cn"&gt;chen&lt;span&gt;.&lt;/span&gt;xueying1&lt;span&gt;@&lt;/span&gt;zte&lt;span&gt;.&lt;/span&gt;com&lt;span&gt;.&lt;/span&gt;cn&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;ji-xuepeng&amp;lt;&lt;a class="reference external" href="mailto:ji.xuepeng%40zte.com.cn"&gt;ji&lt;span&gt;.&lt;/span&gt;xuepeng&lt;span&gt;@&lt;/span&gt;zte&lt;span&gt;.&lt;/span&gt;com&lt;span&gt;.&lt;/span&gt;cn&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Add location info of back-end:&lt;/p&gt;
&lt;p&gt;Add location_info in state of Ceph volume service, it should include the
Ceph cluster name(or id) and storage pool name.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement volume migration:&lt;/p&gt;
&lt;p&gt;1.Check whether the requirements of volume migration are met. If source
back-end and destination back-end are in the same Ceph cluster and volume
status is not ‘in-use’ state, the volume can be migrated.&lt;/p&gt;
&lt;p&gt;2.Copy volume from one pool to another pool and keep it’s original image
name.&lt;/p&gt;
&lt;p&gt;3.Delete the old volume.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit tests will be added. Volume migration test case will be added.&lt;/p&gt;
&lt;p&gt;Both unit and Tempest tests need to be created to cover the code change that
mentioned in “Proposed change” and ensure that volume migration feature
works well while introducing the feature of RBD volume migration.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Wed, 23 Mar 2016 00:00:00 </pubDate></item><item><title>Add Pagination To Other Resources</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/mitaka/add_pagination_to_other_resources.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/add-pagination-to-other-resource"&gt;https://blueprints.launchpad.net/cinder/+spec/add-pagination-to-other-resource&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This spec aims to continue the work that we did in Liberty, adding pagination
support to other cinder resources.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;In Liberty release, we have added pagination to backups and snapshots
according bp[1]. There are still some work that hasn’t been done yet.
In Mitaka, we intend to add pagination support to CG, Volume Type and
Qos specs.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;In large scale cloud systems, end users and manage system that’s on top of
Cinder could make quick querying by using pagination, filter and sort
functions to improve performance of querying.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Consistency Group: Refactor current implementation, using DB pagination
querying, and add support to filter and sort in querying request.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Volume Type: Add pagination and sort support in querying request.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Qos Specs: Add pagination, filter and sort in querying request.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add sql pagination querying support as we did in backup and snapshot.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;According the API-wg guideline about pagination, filter and sort[2]:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;GET /v2/{project_id}/{resource}?limit=xxx&amp;amp;marker=xxx&amp;amp;sort=xxx&amp;amp;{filter}=xxx
RESP BODY: {"resource_links": [{xxx}],
            "resource": [{xxx}, {xxx}, ..., {xxx}]
           }
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;wanghao&amp;lt;&lt;a class="reference external" href="mailto:wanghao749%40huawei.com"&gt;wanghao749&lt;span&gt;@&lt;/span&gt;huawei&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;None&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add pagination support to three resources.
* Implement code in db pagination query.
* Implement code in list querying api.
* Test code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update cinderclient to support this functionality for those resources.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add change to API doc.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Both unit and Tempest tests are needed to be created to cover the code change.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;The cinder API documention will need to be updated to reflect the REST
API changes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;[1]https://blueprints.launchpad.net/cinder/+spec/extend-limit-implementations
[2]https://github.com/openstack/api-wg/blob/master/guidelines/pagination_filter_sort.rst&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Tue, 15 Mar 2016 00:00:00 </pubDate></item><item><title>Cinder FC Zone Manager - User Friendly Zone Names</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/mitaka/brocade-zone-driver-friendly-zone-names.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/brocade-zone-driver-friendly-zone-names"&gt;https://blueprints.launchpad.net/cinder/+spec/brocade-zone-driver-friendly-zone-names&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Introduce user friendly names for zones to include host name and storage
system along with ids to easily identify the host and storage port
details.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;FC Zone Manager will be enhanced to configure friendly names for
zones. At present, zone manager uses the WWNs of Adapter port and
Target port to configure the zone names.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;This addresses the need for zone names to be user friendly so that humans
can easily read the name and understand what host and/or storage system
is represented by that zone.  This feature only has impact on volume
driver developers that need to add the host name and storage system name
into the connection info being passed to the FC zone manager if they wish
to use this feature.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;As per current design, the zone names include a default prefix
‘openstack’ which can be customized and host port wwn and target
wwn (optional) based on the zoning_policy config option:
initiator-target or initiator as follows:&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Initiator-Target Zones:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&amp;lt;openstack&amp;gt;&amp;lt;host WWPN&amp;gt;&amp;lt;target WWPN&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Initiator Zones:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&amp;lt;openstack&amp;gt;&amp;lt;host WWPN&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;These names are not user friendly.&lt;/p&gt;
&lt;p&gt;This proposal is to create friendly zone names with host and storage names
as follows:&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;&lt;strong&gt;Initiator-target zones&lt;/strong&gt;&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&amp;lt;Host Name&amp;gt;_&amp;lt;host WWPN&amp;gt;_&amp;lt;storage System&amp;gt;_&amp;lt;target WWPN&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;&lt;strong&gt;Initiator zones&lt;/strong&gt;&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&amp;lt;Host Name&amp;gt;_&amp;lt;host WWPN&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;The required host name and storage system are populated in &lt;strong&gt;connection_info&lt;/strong&gt;
dictionary returned by fibre channel volume driver &lt;strong&gt;initialize_connection&lt;/strong&gt;
method call. The volume driver will extract the host name from the connector
object passed as parameter to the initialize_connection method. This blueprint
is not documenting the ways the volume driver fetch the storage system value.
It is up to the volume driver to implement a mechanism to retrieve the
storage system value.&lt;/p&gt;
&lt;p&gt;Connection Info samples:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="s1"&gt;'driver_volume_type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'fibre_channel'&lt;/span&gt;
     &lt;span class="s1"&gt;'data'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="s1"&gt;'storage_system'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'AMCE_Array'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;
        &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="s1"&gt;'host_name'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'OS_Host100'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;
        &lt;span class="s1"&gt;'target_discovered'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'target_lun'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'target_wwn'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'1234567890123'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'access_mode'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'rw'&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;or:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="s1"&gt;'driver_volume_type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'fibre_channel'&lt;/span&gt;
     &lt;span class="s1"&gt;'data'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="s1"&gt;'storage_system'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'AMCE_Array'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;
        &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="s1"&gt;'host_name'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'OS_Host100'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;
        &lt;span class="s1"&gt;'target_discovered'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'target_lun'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'target_wwn'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'1234567890123'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'0987654321321'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s1"&gt;'access_mode'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'rw'&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;On attach/detach, Zone Manager will be initialized with &lt;strong&gt;connection_info&lt;/strong&gt;
which is provided by volume driver. Zone Manager in turn will extract the host
name and storage system and will pass this information to the zone driver to
create/delete friendly zone names.&lt;/p&gt;
&lt;p&gt;There is a 64 characters limit for zone names. Hence zone driver implements
a mechanism to normalize the host name and storage system to best fit the zone
name. A WWN is 16 characters long and 32 characters are reserved for host and
storage WWNs. For Initiator and Target policy, the max number of characters
available for host name and storage system is 14 characters each. Zone driver
will trim the names to a max of 14 characters. For Initiator only policy,
the max size allowed for host name is 47 characters. Remaining characters
are reserved for ‘_’.&lt;/p&gt;
&lt;p&gt;Zone Driver updates:&lt;/p&gt;
&lt;p&gt;Zone driver’s add_connection and delete_connection methods will be enhanced
to take host and storage params. These names are defaulted to None. If names
are None, then zone driver will fall back to existing naming mechanism.&lt;/p&gt;
&lt;p&gt;The Zone manager will extract the host name and storage system from
connection_info dictionary using host_name and storage_system keys. If keys
are not found or None, then Zone manager will initialize host name and storage
system local variables to None.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;There is no noticeable performance impact provided FC volume driver will be
able to fetch storage system value swiftly.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;FC Volume drivers need to enhance their existing drivers to support
friendly zone names. This is optional.&lt;/p&gt;
&lt;p&gt;The storage and host name in the &lt;strong&gt;connection_info&lt;/strong&gt; object returned by the
&lt;strong&gt;initialize_connection&lt;/strong&gt; method of FC Volume driver. See the proposed
change section above for details.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Prakash Kaligotla&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Nagendra Rao Jaladanki
Angela Smith&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Enhance the zone manager to pass connection_info object to zone driver.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement Brocade Zone Driver to create zones as per new format
using the host name and storage system in the connector object.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement Cisco Zone Driver to create zones as per new format using
the host name and storage system in the connector object.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Volume drivers are expected to add storage system information to
connector object.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unit test the zone driver and client code.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;Has dependency on FC Volume Drivers to provide host name and storage system
as part of connection_info return dictionary on attach/detach calls.&lt;/p&gt;
&lt;p&gt;If driver does not provide host name and storage system, the existing zone
naming mechanism will be used.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Attach/Detach unit tests will be performed to verify zone manager.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="http://www.brocade.com/downloads/documents/html_product_manuals/FOS_740_CLI/wwhelp/wwhimpl/js/html/wwhelp.htm#href=Title.Fabric_OS.html"&gt;http://www.brocade.com/downloads/documents/html_product_manuals/FOS_740_CLI/wwhelp/wwhimpl/js/html/wwhelp.htm#href=Title.Fabric_OS.html&lt;/a&gt;
&lt;a class="reference external" href="http://www.cisco.com/en/US/docs/storage/san_switches/mds9000/sw/rel_2_x/san-os/command/reference/CR02_z.html"&gt;http://www.cisco.com/en/US/docs/storage/san_switches/mds9000/sw/rel_2_x/san-os/command/reference/CR02_z.html&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Tue, 15 Mar 2016 00:00:00 </pubDate></item><item><title>Brocade Cinder Zone Driver - Virtual Fabric Support</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/mitaka/brocade-zone-driver-virtualfabrics-support.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/brocade-zone-driver-virtualfabrics-support"&gt;https://blueprints.launchpad.net/cinder/+spec/brocade-zone-driver-virtualfabrics-support&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Introduce Virtual Fabric (VF) support for Brocade FC SAN Switches.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;As of Juno, there is no support for zone management in Brocade Virtual Fabrics
thus preventing the administrator to add this automated zone access control
in Brocade Virtual Fabrics (VF) environment.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;This addresses the case where an end user had the Brocade Virtual Fabrics
feature enabled on the FC fabric and zoning needs to be performed in a VF
other than the default.  The impact of this feature is on end users who now
may configure the Virtual Fabric ID in the cinder.conf file for each Brocade
FC fabric block.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;A Brocade FC switch(fixed/modular) can be partitioned into multiple virtual
switches. A unique ID called VFID(Virtual Fabric ID) is assigned to each
virtual switch and all the configurations, including zones, happen within
the context of this VFID. User can configure a particular VFID to be
‘default’ which will be the default context for when users login to the
switch.&lt;/p&gt;
&lt;p&gt;As of Juno, the Brocade Zone Driver and look-up service does not set the
VF context while establishing a session to the switch because of which it
has access only to the zones in the ‘default’ VFID.&lt;/p&gt;
&lt;p&gt;The proposal is to enhance the driver and look-up service to set the VFID
context to support any virtual fabric configured in the chassis.&lt;/p&gt;
&lt;p&gt;A new ‘fc_virtual_fabric_id’ config option is added to zoning fabrics
configuration options as follows:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;fc_virtual_fabric_id&lt;/strong&gt; (StrOpt) VFID of virtual fabric. Default value
is ‘None’.&lt;/p&gt;
&lt;p&gt;The zone driver and look-up service will read the fabric configuration
and extract the VFID to read/apply the configurations on the specific
virtual fabric.&lt;/p&gt;
&lt;p&gt;Multiple Virtual Fabrics Support:&lt;/p&gt;
&lt;p&gt;Cinder already has support for configuring multiple fabrics. In this
release, we are adding the support to configure multiple &lt;strong&gt;virtual fabrics&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Configuring multiple virtual fabrics is similar to configuring regular
fabrics. In case of a virtual fabric, the cinder admin will configure
&lt;strong&gt;fc_virtual_fabric_id&lt;/strong&gt; config option in addition to all other fabric
configuration options.&lt;/p&gt;
&lt;p&gt;On volume attach/detach, the fibre channel volume driver will use SAN lookup
service to traverse through the fabrics configured in cinder.conf to identify
the targets connected to a host and returns a map of initiator and target port
WWNs for each fabric.&lt;/p&gt;
&lt;p&gt;Sample map object returned by the look up service:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Fabric1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s1"&gt;'initiator_port_wwn_list'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'200000051e55a100'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'200000051e55a121'&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="s1"&gt;'target_port_wwn_list'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'100000051e55a100'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'100000051e55a121'&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Virtual_Fabric_2&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s1"&gt;'initiator_port_wwn_list'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'300000051e55a100'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'300000051e55a121'&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="s1"&gt;'target_port_wwn_list'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'400000051e55a100'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'400000051e55a121'&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The volume driver will process this information to extract initiator and
target map for each fabric and builds a new initiator_target_map object.&lt;/p&gt;
&lt;p&gt;Sample initiator_target_map object:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'host WWPN 1'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'target WWPN 1'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'target WWPN 2'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="s1"&gt;'host WWPN 2'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'target WWPN 3'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'target WWPN 4'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The zone manager will be provided with the above map of initiator and it’s
corresponding target port WWNs by the volume driver to create/delete zones.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;Zoning enforces ACL in SAN. Zoning is same in either regular or virtual
fabrics. There are no specific security impacts with respect to virtual
fabrics.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;Configuration of virtual fabric requires providing the &lt;strong&gt;fc_virtual_fabric_id&lt;/strong&gt;
config option with valid virtual fabric VF ID in zoning fabric configuration.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Volume drivers will NOT have to be modified to support virtual fabric.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Prakash Kaligotla&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Nagendra Rao Jaladanki
Angela Smith&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Enhance the Brocade look-up service to find host and targets connected
to a VF.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enhance the Brocade Zone Driver to execute commands in the context of
a VFID.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unit test the zone driver and look-up service.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit tests will be performed to make sure all CRUD operations are
successful on virtual and physical SAN fabrics.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Configuration details of &lt;strong&gt;fc_virtual_fabric_id&lt;/strong&gt; config option will be added
to the fabric zoning configuration of Brocade Fibre Channel Zone Driver.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="http://www.brocade.com/downloads/documents/html_product_manuals/FOS_730_CLI/wwhelp/wwhimpl/js/html/wwhelp.htm#href=Title.Fabric_OS.html"&gt;http://www.brocade.com/downloads/documents/html_product_manuals/FOS_730_CLI/wwhelp/wwhimpl/js/html/wwhelp.htm#href=Title.Fabric_OS.html&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Tue, 15 Mar 2016 00:00:00 </pubDate></item><item><title>capacity headroom</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/mitaka/capacity-headroom.html</link><description>

&lt;p&gt;Include the URL of your launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/capacity-headroom"&gt;https://blueprints.launchpad.net/cinder/+spec/capacity-headroom&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The proposal is to provide a mechanism surfacing the visibility of
the total remaining block storage capacity which is available to
allocate or resize volumes. It will be an indication for deployer
to have the future plan.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently, there is not a clear way for admin users to know how
much block storage capacity left totally in cinder can be deployed.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;condition with several backends&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;condition with a backend supporting “over subscription” which
temporary capacity not used can be utilized to deploy new volumes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;condition with a backend which reports capacity as “infinite” or
“unknown”&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;The proposal calculates the virtual free capacity for each pool
and also sum for each backend. It will notify the info together
with other useful capacity info which already exist to ceilometer
service. The ceilometer service will utilize the notification to
generate capacity samples. The admin users may have a hint about
the trend of cinder capacity usage, and it will be useful for
future capacity planning.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Calculates the virtual free capacity for each pool which reports
capcity normally and sums the total for the backend.&lt;/p&gt;
&lt;p&gt;How to calculate the virtual free capacity(virtual_free):&lt;/p&gt;
&lt;p&gt;For thin provisioning, according to the over
subscription mechanism implemented for LVM,
the remaining virtual capacity for a pool
can be used as terminology:
virtual_free = apparent_available_virtual_capacity.
It can be calculated by following formula:&lt;/p&gt;
&lt;p&gt;virtual_free = apparent_available_virtual_capacity =
total_capacity * max_over_subscription_ratio - provisioned_capacity&lt;/p&gt;
&lt;p&gt;For thick provisioning, just use physical capacity.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Notify the pool capacity and also the total capacity for
a backend to ceilometer service. The capacity notification
includes total/free/allocated/provisioned/virtual_free.&lt;/p&gt;
&lt;p&gt;For backend which reports “unknown/infinite”, just report
it as “unknown/infinite”.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="new-methods-in-hoststate"&gt;
&lt;h3&gt;New methods in HostState&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;get_capacity()
- call get_pools()
- calculate the capacity info for pool and then sum for each backend&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Another alternative could be:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;create a new data table which describe capacity info into database
in scheduler.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;provide a cinder api to retrieve the capacity info from database.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Compare with the proposal, database write operations in scheduler may
cost more.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;The method update_service_capabilities() in host_manager will
call get_capacity() and send notifications to ceilometer service.
Then ceilometer service can produce capacity samples.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;N/A.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;N/A.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;N/A.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;It will be better if Cinder volume drivers can report
provisioned_capacity if it has. This will improve the
efficiency of the storage utilization.
Note: This proposal will calculate virtual capacity
thru provisioned_capacity. Otherwise we will calculate
physical capacity instead.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;XinXiaohui&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Other contributors:&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Calculate the capacity:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Calculates the total virtual_free capacity for a pool if thin
provisioning is supported.&lt;/p&gt;
&lt;p&gt;virtual_free = apparent_available_virtual_capacity =
total_capacity * max_over_subscription_ratio -
provisioned_capacity&lt;/p&gt;
&lt;p&gt;Otherwise, just use the physical capacity.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;notify capacity (total/free/allocated/provisioned/virtual_free)
for each pool and also notify total capacity for the backend to
ceilometer service, if the backend reports “unknown/infinite”,
just report it as it is.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The proposal depends on the over subscription mechanism of backend
drivers.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit tests will be added.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="https://etherpad.openstack.org/p/kilo-cinder-over-subscription"&gt;https://etherpad.openstack.org/p/kilo-cinder-over-subscription&lt;/a&gt;
&lt;a class="reference external" href="https://etherpad.openstack.org/p/kilo-cinder-capacity-headroom"&gt;https://etherpad.openstack.org/p/kilo-cinder-capacity-headroom&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Tue, 15 Mar 2016 00:00:00 </pubDate></item><item><title>Cinder Volume Active/Active support - API Races</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/mitaka/cinder-api-atomic-status-change.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/cinder-volume-active-active-support"&gt;https://blueprints.launchpad.net/cinder/+spec/cinder-volume-active-active-support&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Right now cinder-volume service can run only in Active/Passive HA fashion.&lt;/p&gt;
&lt;p&gt;One of the reasons for this is non-atomic state transitions in c-api that may
cause race conditions.&lt;/p&gt;
&lt;p&gt;This spec proposes a change to do atomic DB changes in Cinder API using
compare-and-swap to prevent them.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Current Cinder API Service code has sections where contents from the DB are
retrieved at one point and then checked for validity and in case all checks
pass and the operation can proceed DB is changed accordingly.&lt;/p&gt;
&lt;p&gt;Elapsed time between the retrieval and the DB changes depends on the nature of
the validation, in some cases it’s just a simple check of the ‘status’ field,
while in others it requires checking other tables for example to confirm that a
volume is not attached or has no snapshots.&lt;/p&gt;
&lt;p&gt;This way of handling checks and changes in the API creates a window of
opportunity for code races to occur. These races would happen when changes are
made to the DB after we have retrieved its contents, leading us to make a
decision based on outdated data and not only change the DB using obsolete data
as reference, but in most cases also incorrectly calling Volume Manager’s
Service to perform an operation.&lt;/p&gt;
&lt;p&gt;One example of these API races is the extend method in cinder/volume/api.py
where we check at one point the status:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;if volume[‘status’] != ‘available’:&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Then later on we change the status:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;self.update(context, volume, {‘status’: ‘extending’})&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;And we finally make an RPC request to perform the operation:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;self.volume_rpcapi.extend_volume(context, volume, new_size, reservations)&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;Operator would want to avoid unexpected behavior in their clouds, moreover
since these race conditions could lead to data corruption in the storage
back-end.  And these are probably situations more likely to happen in an
Active/Active configuration that can handle a higher volume workload.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Proposed solution is to use compare-and-swap updates, with retries on
Deadlocks, to ensure that we only update the DB when all required conditions
are met.&lt;/p&gt;
&lt;p&gt;Basically a compare-and-swap is just a complex DB query that has a condition
added to the update query to ensure that modifications to the DB only occurs if
those conditions are met.  They can be simple conditions like status ==
‘available’ or more complex conditions referring to other tables.&lt;/p&gt;
&lt;p&gt;This solution has been chosen over other alternatives because &lt;a class="reference external" href="http://gorka.eguileor.com/cinders-api-races/"&gt;performance
numbers&lt;/a&gt; in tests show that even under the most extreme conditions in a
multi-master cluster DB configuration they will have great performance results.&lt;/p&gt;
&lt;p&gt;The idea is to keep Cinder API service behaving as close as possible to the
original code, so we will fail and succeed under the same conditions.  Even
though reported errors will be slightly different, the only relevant difference
will be when we previously would have had a race condition, and possibly data
corruption, that both API caller would have received an affirmative response to
their request and now one of them will receive a failure as if both operations
had been performed sequentially.&lt;/p&gt;
&lt;p&gt;The small difference in how we report errors comes from the fact that on
failure we no longer know which of the conditions triggered the failure.  So in
name of efficiency and code clarity we will be returning a generic error
stating that some of the required conditions were not met and therefore
requested operation could not be completed.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;An alternative to returning a generic error on failure, that was rejected for
its complexity, would be to return the exact same errors we are returning now.
For that, we would get updated data from the DB and give it to the validation
method that will check which of the conditions is not met and raise the right
exception with the right error message.  For example this method could be
checking the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;status&lt;/span&gt;&lt;/code&gt; of a volume and raise a message if it is not
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;available&lt;/span&gt;&lt;/code&gt;, and then check that the volume has not snapshots and if it does
then raise a different exception or the same exception with a different
message.&lt;/p&gt;
&lt;p&gt;Skeleton of the procedure:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;conditional_update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;conditions&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;resource&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_resource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;raise_right_validation_error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;rpc_call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;But there is a potential race here, we could be requesting a conditional update
that fails (because the conditions in the DB are not met), and when we retrieve
the data from the DB it has just changed (now it would meet the conditions for
the update), so when we call the method in charge of raising the right
validation error with this changed data it will not find any reason why we
cannot perform the operation, so it will not raise any exception and will just
return control to the caller.&lt;/p&gt;
&lt;p&gt;In that case, since we didn’t raise an error, we would continue with the rpc
call without having changed the DB, which is a problem.  That is why we need a
loop in the conditional update, to make sure we either succeed on the update or
we raise the error regardless of racing conditions on the data.&lt;/p&gt;
&lt;p&gt;Updated skeleton of the procedure:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;conditional_update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;conditions&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;resource&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_resource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;raise_right_validation_error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;rpc_call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;In this implementation it would be a good idea to have a maximum number of
retries instead of just looping until we either update the DB or can properly
raise an error.  That way we would not have an infinite loop if we have an
error in our conditional update or our validation code.&lt;/p&gt;
&lt;p&gt;There are also multiple alternatives to compare-and-swap that have been
explored and discarded for being less efficient - as in being slower or
requiring more queries to the DB.&lt;/p&gt;
&lt;p&gt;Discarded alternatives are:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;SELECT …  FOR UPDATE, with retries on Deadlocks, which even though it works
with multi-master configurations it has more Deadlock retries than proposed
solution.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Using a Distributed Locking Manager with different backends to enforce
exclusive access to resources.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;More information on the tests can be found in &lt;a class="reference external" href="http://gorka.eguileor.com/cinders-api-races/"&gt;performance numbers&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Performance impact will be negligible, and may even have better performance
since there will be only one query to the DB instead of multiple queries.  For
example on volume deletion, where we now have one query to see the status and
another to get the count of snapshots for that volume.  With the new
compare-and-swap we will only have 1 query that will update the DB if the
status is correct and no snapshot exist.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Once changes are made to Cinder API methods, all new API methods that are added
will need to conform to this new compare-and-swap way of updating the DB to
prevent new race conditions from entering the code base.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Gorka Eguileor (geguileo)&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Anyone is welcome to help&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Atomic update method for DB.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This method will require certain capabilities:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Basic comparing:
status = ‘available’
status != ‘available’&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Comparing of multiple values:
status in [‘available’, ‘error’]
status not in [‘attaching’, ‘detaching’]&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Handling None values like Python does: When doing a negative comparison
against a non None value it should return None values as well. So checking
for ‘migration_status’ != ‘migrating’ would also return values that have
‘migration_status’ set to None.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Using additional complex filters: In some cases, like checking for
attachments, more complex queries may be needed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set update values depending on other fields.  For example when detaching a
volume you will have to set the status to ‘available’ if there are no more
volume attachments for that volume, and set it to ‘in-use’ if there are more
attachments (it was multi attached).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set update values based on fields on the DB:
previous_status = status, status = ‘retyping’
size = size + 10&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Atomic update method in Versioned Objects.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Besides exposing the functionality provided by above DB conditional update item
it also needs to:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Automatically add the ID of the resource to the conditional update.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If no conditions are given it must assume we want the DB record to be
unaltered.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It must allow saving dirty attributes together with the update.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It must be able to update the versioned object with data that has been
written to the DB, even on conditional values.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Update Cinder API Service methods to use compare-and-swap.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;No openstack dependencies, but it has a SQLAlchemy depencency on version 1.0.10
that includes Parameter-Ordered Updates (&lt;a class="reference external" href="https://bitbucket.org/zzzeek/sqlalchemy/issues/3541/"&gt;issue #3541&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;On some DBs’ update method is order dependent, so they behave differently
depending on the order of the values, example on a volume with ‘available’
status:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;UPDATE volumes SET previous_status=status, status=’retyping’ WHERE
id=’44f284f9-877d-4fce-9eb4-67a052410054’;&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Will result in a volume with ‘retyping’ status and ‘available’ previous_status
both on SQLite and MariaDB, but&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;UPDATE volumes SET status=’retyping’, previous_status=status WHERE
id=’44f284f9-877d-4fce-9eb4-67a052410054’;&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Will yield the same result in SQLite but will result in a volume with status
and previous_status set to ‘retyping’ in MariaDB, which is not what we want, so
order must be taken into consideration.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit tests will be added for Atomic Update methods.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://etherpad.openstack.org/p/cinder-active-active-vol-service-issues"&gt;https://etherpad.openstack.org/p/cinder-active-active-vol-service-issues&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/205834"&gt;https://review.openstack.org/#/c/205834&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/216377"&gt;https://review.openstack.org/#/c/216377&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/205835"&gt;https://review.openstack.org/#/c/205835&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/216378"&gt;https://review.openstack.org/#/c/216378&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/221441"&gt;https://review.openstack.org/#/c/221441&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/221442"&gt;https://review.openstack.org/#/c/221442&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Tue, 15 Mar 2016 00:00:00 </pubDate></item><item><title>Support query volume detail with glance metadata</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/mitaka/support-volume-glance-metadata-query.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/support-volume-glance-metadata-query"&gt;https://blueprints.launchpad.net/cinder/+spec/support-volume-glance-metadata-query&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Provide a function to support query volume detail filter by glance metadata.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;The purpose of this feature is to make user to query volume detail more
conveniently. User can query a specific bootable volume quickly filtering by
image_name or other glance metadata.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;At large scale deployment, there could be many bootable volumes in a tenant.
So if user want query some bootable volume detail filtering by the image name
or other info came from glance metadata, they could use this feature to query
it more conveniently.
No need to list all volumes and find what you want tiring.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Add DB query filter using volume_glance_metadata in api of sqlaclchemy.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;User can use glance metadata to filter volume detail in cinder api.
The query url is like this:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="s2"&gt;"volumes/detail?glance_metadata={"&lt;/span&gt;&lt;span class="n"&gt;image_name&lt;/span&gt;&lt;span class="s2"&gt;":"&lt;/span&gt;&lt;span class="n"&gt;xxx&lt;/span&gt;&lt;span class="s2"&gt;"}"&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Add query filter support using glance metadata:&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;GET /v2/{project_id}/volumes/detail?glance_metadata={“image_name”:”xxx”}&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Search a lot of glance metadata may take longer than other querying.
It may need add new index to column key and value in volume_glance_metadata
table to improve searching performance.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;wanghao&amp;lt;&lt;a class="reference external" href="mailto:wanghao749%40huawei.com"&gt;wanghao749&lt;span&gt;@&lt;/span&gt;huawei&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Implement code in db query filter.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update cinderclient to support this function.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add change API doc.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Both unit and Tempest tests need to be created to cover the code change that
mentioned in “Proposed change”.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;The cinder API documentation will need to be updated to reflect the REST
API changes.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Tue, 15 Mar 2016 00:00:00 </pubDate></item><item><title>List volumes and snapshots available for manage-existing</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/newton/list-manage-existing.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/list-manage-existing"&gt;https://blueprints.launchpad.net/cinder/+spec/list-manage-existing&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Cinder currently has the ability to take over the management of existing
volumes and snapshots (“manage existing”) and to relinquish management of
volumes and snapshots (“unmanage”). The API to manage an existing volume takes
a reference, which is a driver-specific string that is used to identify the
volume on the storage backend. This process is currently confusing and error
prone. This spec’s purpose is to detail APIs for listing volumes and snapshots
available for management to make this flow more user-friendly. Allowing the
listing of available volumes/snapshots will allow for the creation of an
easy-to-use GUI to migrate existing volumes to a new OpenStack environment, or
to recover in the case the Cinder database is lost.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;There is no Cinder API to list the volumes and snapshots available for
managing, nor to know what reference string to use without referring to
driver-specific documentation. This means that an admin must query the storage
backend, get the appropriate references, and put them into the appropriate
Cinder API. Without the proposed APIs this flow is confusing and error-prone.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;Having Cinder manage an existing block storage volume or snapshot, using only
Cinder APIs and without referring to external driver documentation.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Add new APIs to:
1) list volumes available for management in a given pool.
2) list snapshots available for management in a given pool.&lt;/p&gt;
&lt;p&gt;The APIs would return information regarding the volumes/snapshots, provided by
the driver. In addition, for each resource, an indication will be provided if
it is safe to manage it. The cinder-volume manager will call the appropriate
driver to get a list of resources. For each, the driver will return a safety
indication, which includes if a volume is attached, or a Cinder ID if it
suspects the resource is already managed by Cinder. The manager will look up
any resources suspected already in use in the DB and mark them as not safe
(this avoids the driver accessing the DB).&lt;/p&gt;
&lt;p&gt;A list of items will be returned to the user, consisting of:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;ref&lt;/em&gt; (string): a backend-specific reference to the volume that will be
specified when the user wants to manage that volume.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;size&lt;/em&gt; (integer): the size of the volume, rounded up to Gigabytes, as an
OpenStack user would see it if the volume is managed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;actual_size&lt;/em&gt; (integer): the size of the volume in bytes, which may not be a
precise Gigabyte multiple, as the volume was not created by OpenStack.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;safe_to_manage&lt;/em&gt; (boolean): True if a call to manage the volume specified by
host_ref is expected to be safe, False if it is known that it will not be
(for example, if the driver detects that the volume is attached, or
cinder-volume detects that it already manages the resource).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;reason_not_safe&lt;/em&gt; (string): If “safe_to_manage” is False, specifies why.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;driver-specific key-value pairs&lt;/em&gt; (list of string:string): Any additional
information that a driver may wish to return to help the admin identify the
volumes/snapshots, for example a description, timestamps, etc.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For listing snapshots, return these additional fields:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;source_volume_ref&lt;/em&gt; (string): The backend-specific reference of the volume
that is the source of the snapshot.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;source_volume_id&lt;/em&gt; (string): The Cinder volume ID of the volume that owns the
snapshot if the volume is already managed by Cinder.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Leave as is.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;Add two additional API extensions.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;Cinder currently has the ability to create objects in the storage pool, and
view or modify those objects. This allows the admin to view volumes not created
by Cinder. On the other hand, the admin can take the storage credentials that
Cinder has and perform the action on the storage backend itself, so there is no
real impact.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Driver maintainers can add the two new calls to bring this functionality to
their drivers.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;p&gt;I propose that list_manageable be added as a new GET action on the
os-volume-manage Cinder extension.  It would be separately specifiable in
Cinder’s policy.json file to restrict access appropriately (default being
admin_api).&lt;/p&gt;
&lt;p&gt;There would be new RPC calls to cinder-volume which would call two new driver
APIs (list_manageable_volumes and list_manageable_snapshots). I will implement
the LVM driver code as well, as a reference implementation.&lt;/p&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;avishay&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create APIs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create RPC calls&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create driver interface&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement LVM reference&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement tempest test&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Standard unit tests and manual testing, as well as tempest test for these
proposed APIs, as well as manage and unmanage.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;The new APIs will be documented.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Sun, 21 Feb 2016 00:00:00 </pubDate></item><item><title>Delete multiple volume metadata keys</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/newton/delete-multiple-metadata-keys.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/delete-multiple-metadata-keys"&gt;https://blueprints.launchpad.net/cinder/+spec/delete-multiple-metadata-keys&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;The current implementation of Cinder API functionality supports deleting of
multiple volume metadata as multiple requests for deleting only one metadata
key with a request. The more keys are necessary to remove, the more API
requests and DB queries are needed. It would be more efficient to delete
multiple metadata keys with a single request at a time.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;Deleting multiple volume metadata keys with a single request.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;To delete multiple metadata items without affecting the remaining ones,
just update the metadata items with the updated complete list of ones
(without items to delete) in the body of the request. On success, the
server responds with a 200 status code.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;A PUT request should use etags to avoid the lost update problem.&lt;/p&gt;
&lt;/div&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Have a request that deletes all keys rather than a specified list as an
option.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;The existing API for update metadata will be used in this case. The API
call will fail in the case some of the items that are specified to delete
does not exist. The API call will send the set of keys that are supposed
to be updated and ignore missing keys.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;One delete notification will be emitted per metadata item deleted as today.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;A user will have new API.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;The deleting of a volume metadata keys with a single request allows to
improve performance by reducing DB calls. It’s very important in case with
many keys. Better performance due to fewer request round trips.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Primary assignee:
Yuriy Nesenenko(&lt;a class="reference external" href="mailto:ynesenenko%40mirantis.com"&gt;ynesenenko&lt;span&gt;@&lt;/span&gt;mirantis&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;)&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Extend python-cinderclient to support new API.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add unit and tempest tests.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;Depends on Cinder API microversion.
Depends on API WG patch &lt;a class="reference external" href="https://review.openstack.org/281511/"&gt;https://review.openstack.org/281511/&lt;/a&gt;
Depends on API WG patch &lt;a class="reference external" href="https://review.openstack.org/301846/"&gt;https://review.openstack.org/301846/&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit and functional tests are needed to ensure response is working correctly.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Documents concerning the API will need to reflect these changes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 11 Feb 2016 00:00:00 </pubDate></item><item><title>Cheesecake</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/mitaka/cheesecake.html</link><description>

&lt;p&gt;Include the URL of your launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/replication"&gt;https://blueprints.launchpad.net/cinder/+spec/replication&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This spec proposes further refinement to the Cinder replication.
After more vendors have tried to implement replication and we’ve
learned more lessons about the differences in backends and their
semantics we’ve decided we should step back and look at simplifying
this even further.&lt;/p&gt;
&lt;p&gt;The goal of the new design is to address a large amount of confusion
and differences in interpretation.  Rather than try and cover multiple
use cases in the first iteration, this spec aims to address a single
fairly well defined use case.  Then we can iterate and move on from
there.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;The existing design is great for some backends, but is challenging for many
devices to fit in to.  It’s also filled with pitfalls with the question of
managed/unmanaged, not to mention trying to deal with failing over some
volumes and leaving others. The concept of failing over on a volume basis
instead of on a device basis while nice for testing doesn’t fit well into
the intended use case and results in quite a bit of complexity and also is not
something that a number of backends can even support.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;This is intended to be a DR mechanism.  The model Use Case is a catastrophic
event occurring on the backend storage device, but some or all volumes that
were on the primary backend may have been replicated to another backend device
in which case those volumes may still be accessible.&lt;/p&gt;
&lt;p&gt;The flow of events are as follows:
1.  Admin configures a backend device to enable replication.  We have a
configured cinder backend just as always (Backend-A) but we add config
options for a replication target (Backend-B).&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ol class="loweralpha simple"&gt;
&lt;li&gt;&lt;p&gt;We no longer deal with differentiation between managed and unmanaged
Now, to enable a replication target(s), the replication_target entry
is the ONLY method allowed and is specified as a section in the driver.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Depending on the back-end device enabling this may mean that EVERY
volume created on the device is replicated, or for those that have
the capability and if admins choose to do so a Volume-Type of
“replicated=True” can be created and used by tenants.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Note that if the backend only supports replicating “all” volumes, or
if the Admin wants to set things up so that “all” volumes are
replicated that the Type creation may or may not be necessary.&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;ol class="arabic" start="2"&gt;
&lt;li&gt;&lt;p&gt;Tenant creates a Volume that is replicated (either by specifying
appropriate Type, or by the nature of the backend device)
Result in this example is a Volume we’ll call “Foo”&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Backend-A is caught in the crossfire of a water balloon fight that
shouldn’t have been taking place in the data center, and looses it’s magic
smoke, “It’s dead Jim!”&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Admin issues “cinder replication-failover” command with possible arguments
a.  Call propagates to Cinder Driver, which performs appropriate steps for
that driver to now point to the secondary (target) device (Backend-B).&lt;/p&gt;
&lt;ol class="loweralpha simple" start="2"&gt;
&lt;li&gt;&lt;p&gt;The Service Table in Cinder’s database is updated to indicate that a
replication failover event has occurred, and the driver is currently
pointing to an alternate target  device.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In this scenario volumes that were replicated should still be accessible by
tenants.  The usage may or may not be restricted depending on options
provided in the failover command.  If no restrictions are set we expect to
be able to continue using them as we would prior to the failure event.&lt;/p&gt;
&lt;p&gt;Volumes that were attached/in-use are a special case in this scenario and
will require additional steps.  The Tenant will be required in this case to
detach the volumes from any instances manually.  Cinder does not have the
ability to call Nova’s volume-detach methods, so this has to be done by the
Tenant or the Admin.&lt;/p&gt;
&lt;ol class="loweralpha simple" start="3"&gt;
&lt;li&gt;&lt;p&gt;Freeze option provided as an argument to Failover
The failover command includes a “freeze” option.  This option indicates
that a volume may still be read or written to, HOWEVER that we will not
allow any additional resource create or delete options until an admin
issues a “thaw” command.  This means that attempts to call
snapshot-create, xxx-delete, resize, retype etc should return an
InvalidCommand error.  This is intended to try and keep things in as
stable of a state as possible, to help in recovering from the
catastrophic event.  We think of this as the backend resources becoming
ReadOnly from a management/control plan perspective.  This does not mean
you can’t R/W IO from an instance to the volume.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How to get back to “normal”
a.  If the original backend device is salvageable, the failover command
should be used to switch back to the original primary device.  This of
course means that there should be some mechanism on the backend and
operations performed by the Admin that ensures the resources still exist on
the Primary (Backend-A) and that their data is updated based on what may
have been written while they were hosted on Backend-B.  This indicates that
for backends to support this something like 2-way replication is going to
be required.  For backends that can’t support this, it’s likely that we’ll
need to instead swap the primary and secondary configuration info
(Reconfigure making Backend-B the Primary).&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;It’s important to emphasize, if the volume is not of type “replicated” it will
NOT be accessible after the failover.  This approach fails over the entire
backend to another device.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;One of the goals of this patch is to try and eliminate some of the challenges
with the differences between manage and unmanaged replication targets.  In this
model we make this easier for backends.  Rather than having some volumes on
one backend and some on another and not doing things like stats update, we now
fail over the entire backend including stats updates and everything.&lt;/p&gt;
&lt;p&gt;This does mean that non-replicated type volumes will be left behind and
inaccessible (unavailable), that’s an expectation in this use case (the
device burst into flames).  We should treat these volumes just like we
currently treat volumes in a scenario where somebody disconnects a backend.
That’s essentially what is happening here and it’s no different really.&lt;/p&gt;
&lt;p&gt;For simplicity in the first iteration, we’re specifying the device as a driver
parameter in the config file and we’re not trying to just read in a secondary
configured backend device.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;[driver-foo]
volume_driver=xxxx
valid_replication_devices=’remote_device={‘some unique access meta}’,…&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;NOTE That the remote_device access MUST be handled via the
configured driver.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Add the following API calls
replication-enable/disable ‘backend-name’&lt;/p&gt;
&lt;p&gt;This will issue a command to the backend to update the capabilities being
reported for replication.&lt;/p&gt;
&lt;p&gt;replication-failover [–freeze] ‘backend-name’
This triggers the failover event, assuming that the current primary
backend is no longer accessible.&lt;/p&gt;
&lt;p&gt;replication-thaw ‘backend-name’
Thaw a backend that experienced a failover and is frozen&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="special-considerations"&gt;
&lt;h3&gt;Special considerations&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;async vs sync
This spec does not make any assumptions about what replication method
the backend uses, nor does it care.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;transport
Implementation details and the &lt;em&gt;how&lt;/em&gt; the backend performs replication
is completely up to the backend.  The requirements are that the interfaces
and end results are consistent.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Volume driver for the replicated backend MUST have the ability to
communicate with the other backend and route the calls correctly based on
what’s selected as the current primary.  One example of an important detail
here is the “update stats” call.&lt;/p&gt;
&lt;p&gt;In the case of a failover, it is expected that the secondary/target device is
now reporting stats/capabilities, NOT the now &lt;em&gt;dead&lt;/em&gt; backend.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tenant visibility
The visibility by tenants is LIMITED!!!  In other words the tenant
should know very little about what’s going on.  The only information that
should really be propogated is that the backend and the volume is
in a “failed-over” state, and if it’s “frozen”.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the case of a failover where volumes are no longer available on the new
backend, the driver should raise a NotFound Exception for an API calls that
attempt to access them.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;There are all sorts of alternatives, the most obvious of which is to leave
the implementation we have and iron it out.  Maybe that’s good, maybe that’s
not.  In my opinion this approach is simpler, easier to maintain and more
flexible; otherwise I wouldn’t propose it.  The fact that there’s only
one vendor that’s implemented replication in the existing setup and they
have a number of open issues currently we’re not causing a terrible amount
of churn or disturbance if we move forward with this now.&lt;/p&gt;
&lt;p&gt;The result will be something that should be easier to implement and as an
option will have less impact on the core code.&lt;/p&gt;
&lt;p&gt;One appealing option would be to leave Cinder more cloud-like and not even
offer replication.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;We’ll need a new column in the host table that indicates “failed-over” and
“frozen”  status.&lt;/p&gt;
&lt;p&gt;We’ll also need a new property for volumes, indicating if they’re failed-over
and if they’re frozen or not.&lt;/p&gt;
&lt;p&gt;Finally, to plan for cases where perhaps a backend has multiple replication
targets, we need to provide them a mechanism to persist some ID info as to
where the fail-over was sent to.  In other words, make sure the driver has
a way to set things back up correctly on an init.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;replication-enable/disable ‘backend-name’&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;This will issue a command to the backend to update the capabilities being
reported for replication.&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;replication-failover [–freeze] ‘backend-name’&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;This triggers the failover event, assuming that the current primary
backend is no longer accessible.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;Describe any potential security impact on the system.  Some of the items to
consider include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Does this change touch sensitive data such as tokens, keys, or user data?&lt;/p&gt;
&lt;p&gt;Nope&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Does this change alter the API in a way that may impact security, such as
a new way to access sensitive information or a new way to login?&lt;/p&gt;
&lt;p&gt;Nope, not that I know of&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Does this change involve cryptography or hashing?&lt;/p&gt;
&lt;p&gt;Nope, not that I know of&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Does this change require the use of sudo or any elevated privileges?&lt;/p&gt;
&lt;p&gt;Nope, not that I know of&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Does this change involve using or parsing user-provided data? This could
be directly at the API level or indirectly such as changes to a cache layer.&lt;/p&gt;
&lt;p&gt;Nope, not that I know of&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Can this change enable a resource exhaustion attack, such as allowing a
single API interaction to consume significant server resources? Some examples
of this include launching subprocesses for each connection, or entity
expansion attacks in XML.&lt;/p&gt;
&lt;p&gt;Nope, not that I know of&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For more detailed guidance, please see the OpenStack Security Guidelines as
a reference (&lt;a class="reference external" href="https://wiki.openstack.org/wiki/Security/Guidelines"&gt;https://wiki.openstack.org/wiki/Security/Guidelines&lt;/a&gt;).  These
guidelines are a work in progress and are designed to help you identify
security best practices.  For further information, feel free to reach out
to the OpenStack Security Group at &lt;a class="reference external" href="mailto:openstack-security%40lists.openstack.org"&gt;openstack-security&lt;span&gt;@&lt;/span&gt;lists&lt;span&gt;.&lt;/span&gt;openstack&lt;span&gt;.&lt;/span&gt;org&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;We’d certainly want to add a notification event that we “failed over”&lt;/p&gt;
&lt;p&gt;Also freeze/thaw, as well as enable/disable events.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;Aside from the API, are there other ways a user will interact with this
feature?&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Does this change have an impact on python-cinderclient? What does the user
interface there look like?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;TBD&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Describe any potential performance impact on the system, for example
how often will new code be called, and is there a major change to the calling
pattern of existing code.&lt;/p&gt;
&lt;p&gt;Examples of things to consider here include:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;A periodic task might look like a small addition but when considering
large scale deployments the proposed call may in fact be performed on
hundreds of nodes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Scheduler filters get called once per host for every volume being created,
so any latency they introduce is linear with the size of the system.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A small change in a utility function or a commonly used decorator can have a
large impacts on performance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Calls which result in a database queries can have a profound impact on
performance, especially in critical sections of code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Will the change include any locking, and if so what considerations are there
on holding the lock?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;Discuss things that will affect how you deploy and configure OpenStack
that have not already been mentioned, such as:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;What config options are being added? Should they be more generic than
proposed (for example a flag that other volume drivers might want to
implement as well)? Are the default values ones which will work well in
real deployments?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Is this a change that takes immediate effect after its merged, or is it
something that has to be explicitly enabled?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If this change is a new binary, how would it be deployed?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Please state anything that those doing continuous deployment, or those
upgrading from the previous release, need to be aware of. Also describe
any plans to deprecate configuration values or features.  For example, if we
change the directory name that targets (LVM) are stored in, how do we handle
any used directories created before the change landed?  Do we move them?  Do
we have a special case in the code? Do we assume that the operator will
recreate all the volumes in their cloud?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Discuss things that will affect other developers working on OpenStack,
such as:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;If the blueprint proposes a change to the driver API, discussion of how
other volume drivers would implement the feature is required.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Who is leading the writing of the code? Or is this a blueprint where you’re
throwing it out there to see who picks it up?&lt;/p&gt;
&lt;p&gt;If more than one person is working on the implementation, please designate the
primary author and contact.&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;john-griffith&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&amp;lt;launchpad-id or None&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;Work items or tasks – break the feature up into the things that need to be
done to implement it. Those parts might end up being done by different people,
but we’re mostly trying to understand the timeline for implementation.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Include specific references to specs and/or blueprints in cinder, or in other
projects, that this one either depends on or is related to.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If this requires functionality of another project that is not currently used
by Cinder (such as the glance v2 API when we previously only required v1),
document that fact.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Does this feature require any new library dependencies or code otherwise not
included in OpenStack? Or does it depend on a specific version of library?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Need Horizon support&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Please discuss how the change will be tested. We especially want to know what
tempest tests will be added. It is assumed that unit test coverage will be
added so that doesn’t need to be mentioned explicitly, but discussion of why
you think unit tests are sufficient and we don’t need to add more tempest
tests would need to be included.&lt;/p&gt;
&lt;p&gt;Is this untestable in gate given current limitations (specific hardware /
software configurations available)? If so, are there mitigation plans (3rd
party testing, gate enhancements, etc).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;What is the impact on the docs team of this change? Some changes might require
donating resources to the docs team to have the documentation updated. Don’t
repeat details discussed above, but please reference them here.&lt;/p&gt;
&lt;p&gt;Obviously this is going to need docs and devref info in cinder docs tree&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;Please add any useful references here. You are not required to have any
reference. Moreover, this specification should still make sense when your
references are unavailable. Examples of what you could include are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Links to mailing list or IRC discussions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Links to notes from a summit session&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Links to relevant research, if appropriate&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Related specifications as appropriate (e.g. link to any vendor documentation)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Anything else you feel it is worthwhile to refer to&lt;/p&gt;
&lt;p&gt;The specs process is a bit much, we should revisit it.  It’s rather
bloated, and while the first few sections are fantastic for requiring
thought and planning, towards the end it just gets silly.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Fri, 29 Jan 2016 00:00:00 </pubDate></item><item><title>Extend a volume while volume is attached to an instance</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/pike/extend-attached-volume.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/extend-attached-volume"&gt;https://blueprints.launchpad.net/cinder/+spec/extend-attached-volume&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This spec covers the Cinder changes in the volume extend volume
flow that will allow volume drivers that support extending for
attached volumes to extend the attached volume.&lt;/p&gt;
&lt;p&gt;Extending an attached volume requires Nova side changes. A Nova spec
covers the Nova changes necessary to extend a volume that is
attached to one or more instances.&lt;/p&gt;
&lt;p&gt;Cinder will interact with Nova via the existing
os-server-external-events extension to notify Nova that the volume
has changed size and react to the change in size.&lt;/p&gt;
&lt;p&gt;After Nova has processed the extend size API call,
the instance administrator might need to take action to make use of the
new space associated with the volume. Within the instance the appropriate
actions must be taken for the OS the instance is running to discover
the new size of the volume. The instance administrator can then make
use of the new space in the volume.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Cinder requires that a volume be in the available state.
This requires an attached volume to be detached from an instance before
the volume can be extended in size. This means taking the volume offline
from the standpoint of the application using the volume.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;An operator wants to increase the size of a volume that is currently
attached to an instance without detaching that volume from the instance.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;In the Cinder extend API, allow the volume extend operation to
continue processing when the volume status is ‘in‐use’ for volume
drivers that can support extending an ‘in‐use’ volume.
A volume could be extended if the volume status is ‘available’ or
‘in-use’ if the volume driver supports in-use extend.
All other volume status values besides ‘available’ and ‘in-use’
would raise an exception.&lt;/p&gt;
&lt;p&gt;A volume driver wishing to support in-use extend must add a new
capability (in-use-extend) that indicates the driver supports
extending a volume while that volume is ‘in-use’. If a driver does
not have the capability to extend its volumes while they are
‘in-use’, the API will fail the extend request with a message
indicating that the volume driver does not support extending
a volume that is in the ‘in-use’ state.&lt;/p&gt;
&lt;p&gt;A new policy will be introduced so a deployer can disable the volume
extend operation on attached volume if the deployment does not fully
support the feature. For example, Nova virt driver not supporting
online volume size extension.&lt;/p&gt;
&lt;p&gt;If the volume driver capabilities indicate that the driver supports
in-use extend then the volume status will be changed to ‘extending’
and then call the driver extend_volume. After changing
the volume status to ‘in‐use’, notify Nova that the volume has changed size.
Nova will react to the change in size for all the instances
that have the volume attached.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;One alternative is to create a new volume and attach that volume
to the instance. Once the new volume is discovered on the instance,
use LVM to extend the space to the application LV. This is the method
being used today to allow more space to be allocated. This is
undesirable in the long run as each time a volume is extended the
extension results in a new volume to be allocated, discovered on
the instance, and added to a volume group, then extending the LV to
include the volume. Operators have expressed concerns about using
this approach as it eventually encounters limitations in the
number of volumes that can be attached to a specific OS. For the
volume controllers that have the ability to grow a volume while it
is in‐use, it is desirable to use that ability.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;No changes to the API interface itself, as no change is required to the
arguments to the API. The API documentation will change to reflect
that an in-use volume may now be extended, if the volume driver capabilities
allow in-use extend.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;TBD&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;End user will be able to extend their volumes without having to
detach them first.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Driver owners whose backend controllers support extending a volume that is
in-use by an instance may want to enable in-use extend.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Primary assignee:
* Mathieu Gagné&lt;/p&gt;
&lt;p&gt;Other contributors:
* Gerald McBrearty
* Sam Matzek&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;The Cinder extend volume API will check volume driver capability to see if
the driver supports in-use-extend when the status of the volume is in-use.&lt;/p&gt;
&lt;p&gt;The extend_volume rpcAPI will need to change the status of a volume back to
‘in-use’ if the volume is attached to an instance or ‘available’ if the volume
is not attached to an instance, unless the driver raises an error which
will cause the volume status to be changed ‘error-extending’.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Nova spec: Allow an attached volume to be extended &lt;a class="footnote-reference brackets" href="#id2" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;
Adds the Nova external events support for volume-changed.
It will call the os-brick extend_volume API to trigger
the host kernel size information to be updated on
the host where the volume has been discovered.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;The following scenarios for in-use volumes will need to be covered in
UT and FVT&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;volume driver without in-use-extend capability.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;volume driver with in-use-extend capability with Nova not supporting
the volume-changed external event.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;volume driver with in-use-extend capability with Nova supporting
the volume-changed external event.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;The extend documentation will need to be updated to indicate that a
volume that is attached to an instance can be extended if the driver has
the capability ‘in-use-extend’.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id2" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://specs.openstack.org/openstack/nova-specs/specs/pike/approved/nova-support-attached-volume-extend.html"&gt;http://specs.openstack.org/openstack/nova-specs/specs/pike/approved/nova-support-attached-volume-extend.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Tue, 26 Jan 2016 00:00:00 </pubDate></item><item><title>Online DB schema upgrades</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/mitaka/online-schema-upgrades.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/online-schema-upgrades"&gt;https://blueprints.launchpad.net/cinder/+spec/online-schema-upgrades&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;One of the priorities for Mitaka cycle is making Cinder able to perform rolling
upgrades. This effort requires a lot of discipline to block any changes that
can break interoperability of different services versions.&lt;/p&gt;
&lt;p&gt;Some database migrations can break this interoperability. This spec aims to
provide a guideline of how we handle such changes to make sure Cinder is able
to do rolling upgrades.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Non backward compatible database migrations include:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Non-additive migrations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Column, tables removals&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Column, tables renames&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Adding constraints&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Long-running data migrations (for example from one column to another)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All of these should be run when all the services are down. This may not be a
problem for small amount of data, but when we’re talking about thousands of
rows, the downtime may be significant.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;Deployer would like to be able to perform Cinder upgrade without downtime of
control plane services.&lt;/p&gt;
&lt;p&gt;User would like not to experience downtime of control plane when cloud he’s
using is getting upgraded.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;In general we want to build on Nova’s experiences and adapt their solution for
our needs. Detailed description of how Nova is doing DB migrations in a live
way is presented in &lt;a class="reference external" href="http://www.danplanet.com/blog/2015/10/07/upgrades-in-nova-database-migrations/"&gt;Dan Smith’s blogpost&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;At this moment please note that we’re not basing on older Nova’s approach
called &lt;a class="reference external" href="https://blueprints.launchpad.net/nova/+spec/online-schema-changes"&gt;Online Schema Changes&lt;/a&gt; that was automatically doing additive and
contracting DB migrations based on current and desired DB model described in
models.py. This approach would eventually lead to developers not needing to
write migrations manually. We will not adopt this solution as it was considered
experimental, was known for destroying data, wasn’t working in late Liberty and
was &lt;a class="reference external" href="https://review.openstack.org/#/c/239922/"&gt;recently removed from Nova&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The main difference between Cinder and Nova that affects online DB schema
upgrades solution is the fact that in Cinder all the services are querying the
DB. In Nova only nova-conductor has access to the DB. Therefore we need to
modify the approach slightly. The changes force us to span the migrations over
3 releases instead of 2 like in Nova.&lt;/p&gt;
&lt;p&gt;First of all we should introduce a unit test that will block migrations that
are contracting. Basically such test is failing when a migration using DROP or
ALTER command is in tree. We will do it in a similar way &lt;a class="reference external" href="https://review.openstack.org/#/c/197349/"&gt;like Nova&lt;/a&gt; did.&lt;/p&gt;
&lt;p&gt;After adding such test we should allow only migrations that are expanding or
additive, that is - are adding new columns or tables. Good part is that since
Juno we’ve only merged migrations that are like that. This means that we will
need the special way rarely.&lt;/p&gt;
&lt;p&gt;And (a little complicated) special way goes as follows. Let’s use a real-world
example to make this a little more useful. We’ll try to model live DB schema
change that will change the relationship between consistency groups and volume
types to be modelled correctly. This is a n-n relationship that currently is
represented by &lt;cite&gt;volume_type_id&lt;/cite&gt; column in &lt;cite&gt;consistencygroups&lt;/cite&gt; table that is
storing comma-separated ids of volume types related to the consistency group.
Correct way to represent that is to use &lt;cite&gt;ConsistencyGroupVolumeTypeMapping&lt;/cite&gt;
table which maintains connections between CG and VT.&lt;/p&gt;
&lt;p&gt;We will be working through 3 releases (+ the current one), so let’s identify
them using letters:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;L - current&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;M - in development&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;N&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;O&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="m-release"&gt;
&lt;h3&gt;M release&lt;/h3&gt;
&lt;p&gt;In L release we have only the old representation of this relationship. In M we
should merge a change that adds &lt;cite&gt;ConsistencyGroupVolumeTypeMapping&lt;/cite&gt; model and
required columns in &lt;cite&gt;ConsistencyGroup&lt;/cite&gt; and &lt;cite&gt;VolumeType&lt;/cite&gt; models that will form
relationships to the table mentioned earlier. This additive migration can be
easily executed on database while L services are running.&lt;/p&gt;
&lt;p&gt;As on upgrade we will have L and M releases operating in the same moment we
should modify M’s CG versioned object to:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Write data in both places.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Read data from old place.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That way we maintain compatibility with M-&amp;gt;L (M is writing to old place) and
L-&amp;gt;M (M is reading from old place).&lt;/p&gt;
&lt;p&gt;Once upgrade is completed admin should use a tool that will finish data
migrations. This tool will be developed in cinder-manage and will operate on
chunks of CG rows (to limit performance impact). It will simply iterate and set
the relationship in new place.&lt;/p&gt;
&lt;p&gt;In the end everything is running M services, so everythings writes to both
places and reads from the old one. Also we should have all the data migrated at
this point so for all CGs have relationship defined both in new and old way.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="n-release"&gt;
&lt;h3&gt;N release&lt;/h3&gt;
&lt;p&gt;Now on upgrade we will have M and N release versions. N’s versioned objects:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Write data in both places.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Read data from new place.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This way we maintain compatibility M-&amp;gt;N (N is writing in place M is reading)
and N-&amp;gt;M (M is writing in place N is reading).&lt;/p&gt;
&lt;p&gt;As N is reading from new place, before starting any N’s service we need to make
sure that all the CGs are migrated. To enforce that, as a first N’s migration
we should merge a dummy one that will block subsequent ones if there are items
that weren’t migrated yet.&lt;/p&gt;
&lt;p&gt;Please note that we still have old representation in SQLAlchemy model, so we
would be unable to drop the column even if we managed to switch N services to
write only to the new place.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="o-release"&gt;
&lt;h3&gt;O release&lt;/h3&gt;
&lt;p&gt;This time we’ll have N and O services cooperating.&lt;/p&gt;
&lt;p&gt;In O we finally modify the SQLAlchemy model to remove the old
&lt;cite&gt;ConsistencyGroup&lt;/cite&gt; &lt;cite&gt;volume_type_id&lt;/cite&gt; field. This time we’re able to, because
it’s guaranteed that all services write and read from new place.  We also
remove it from O’s versioned object - it will now read and write data only to
the new place.&lt;/p&gt;
&lt;p&gt;After the upgrade we have everything writing and reading only from the new
place. Moreover - SQLAlchemy models in O’s services doesn’t have a notion of
&lt;cite&gt;volume_type_id&lt;/cite&gt; column. Therefore we can have a post-upgrade migration script
that finally drops the column (or we can simply add it as migration in P
release if we want to limit number of steps needed to do upgrades.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;We may simply block both contracting and data migrations. This however will
prevent us from fixing bad decisions made in the past, which may hurt the
project, as I don’t believe it is mature enough yet.&lt;/p&gt;
&lt;p&gt;It’s possible to implement &lt;a class="reference external" href="https://blueprints.launchpad.net/nova/+spec/online-schema-changes"&gt;Online Schema Changes&lt;/a&gt; to make DB migrations to
have two steps divided automatically. Nova was considering this as
experimental. Moreover the code got removed in Mitaka-1. It also doesn’t solve
long-running data migrations problem so doesn’t remove all the complications
this spec is proposing.&lt;/p&gt;
&lt;p&gt;We can also leave things as they are now and assume you need this downtime to
upgrade. This probably isn’t what operators want and all the efforts we’ve
already did (versioned objects, RPC compatibility) would be wasted.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;We don’t expect impact to the data model itself, but to the way we’re doing
migrations of the data model.&lt;/p&gt;
&lt;p&gt;Changes in the model would need to be reviewed carefully to make sure they
follow this guideline.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;We can expect a little performance impact on DB calls because we’ll be queuing
and saving additional columns instead of dropping unused ones right away. This
shouldn’t be very significant however.&lt;/p&gt;
&lt;p&gt;There will be overhead on the DB when executing small chunks of DB migrations
while the cloud is running. This is however a tradeoff, as alternative to that
is downtime of the whole cloud.&lt;/p&gt;
&lt;p&gt;Nova does this in a very similar way and they doesn’t report performance
issues.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;It will be needed for deployer to be aware of how to do DB upgrade in a correct
way. This will be documented, but knowledge will need to be propagated.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;There will be huge impact on developers and reviewers as both groups will need
to be aware how Cinder is doing DB migrations and write/review the code
accordingly to prevent rolling upgrades feature from breaking.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;michal-dulko-f (dulek)&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Engagement from whole core team is needed to make sure the code is reviewed
also from the perspective of live upgrades.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add unit test blocking contracting migrations (needed in Mitaka).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add online DB data migrations bits to cinder-manage.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Write developer guide on how to write DB migrations properly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add DB migrations bits to Cinder’s upgrade documentation.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None for itself. Whole rolling upgrades story depends on RPC compatibility
(API versioning and versioned objects with compatibility mode).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Partial Grenade tests should be added to make sure upgrading services
one-by-one doesn’t break rolling upgrades. This should also cover DB migrations
step.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;We need to write detailed developer guide on how to write DB migrations in new
model to make sure that we have a clear resource which we can point developers
to.&lt;/p&gt;
&lt;p&gt;To educate administrators and deployers on how to do rolling upgrades DB
migrations parts should be added to general upgrade instruction for Cinder.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://www.youtube.com/watch?v=2BLJMPsaWZg"&gt;Discussion at the Design Summit&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Thu, 07 Jan 2016 00:00:00 </pubDate></item><item><title>Retype volumes with different encryptions</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/newton/retype-encrypted-volumes.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/retype-encrypted-volume"&gt;https://blueprints.launchpad.net/cinder/+spec/retype-encrypted-volume&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Enable the function that changing volume type of a volume [1] to another
type with different encryptions.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently Cinder prevents retyping volumes to a volume type with different
encryptions.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Customers use unencrypted volumes, but later they would like
to change the volumes to encrypted.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Customers use encrypted volumes and later want to change to unencrypted.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Customers want to change encryptions of a volume.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Allow retype between encrypted and unencrypted volumes.
Same as current retype mechanism, it allows to retype volumes in available
and in-use volumes.&lt;/p&gt;
&lt;p&gt;If a volume is in available status, the detailed process will be:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create a new volume according to new volume_type.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Map the two volumes to the volume host.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open the device with dm-crypt if volumes are encrypted. This is done
through os-brick/encryptors [2].&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Copy data from original volume to new volume.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Close dm-crypt and detach the volumes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete original volume in backend storage.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If a volume is in-use status, nothing needs to change except the bug fix [3].&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;With the feature, it allows users to retype a volume to different
encryptions.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;Cinder needs to access encryption keys and decrypt the data.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;A flag will be added to current retype notification to show whether
it needs encryption change.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;During retyping volumes with different encryptions, Cinder needs to get key.
But Barbican can be configued only to give key materials to tenants, not admin.
This may lead that admin can’t retype volumes successfully. In such cases,
Cinder will catch the exception, log the error. The volume to retype will be
set to original state.
As os-brick/encryptors doesn’t work on RBD, Sheepdog volumes, the function to
retype such volumes to different encryptions will fail, and volumes will be
set to original state.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;It adds the step of encrypting/decrypting data during retype process,
and the impact is dependent on the performance of encryption.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;The feature is dependent on Castellan [4]. Meanwhile, Barbican [5] is currently
the only key manager backend supported by Castellan. Both the two packages
are needed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;LisaLi &amp;lt;&lt;a class="reference external" href="mailto:xiaoyan.li%40intel.com"&gt;xiaoyan&lt;span&gt;.&lt;/span&gt;li&lt;span&gt;@&lt;/span&gt;intel&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Remove current limitation which disallows the retype.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Attach/detach encrypted volume through dm-crypt.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit tests need to be created to cover the code change that
mentioned in “Proposed change”.
New tempest test cases will be added after current retype test [6].&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;The cinder API documentation will need to be updated to describe the change.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;[1]: &lt;a class="reference external" href="http://docs.openstack.org/cli-reference/cinder.html#cinder-retype"&gt;http://docs.openstack.org/cli-reference/cinder.html#cinder-retype&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[2]: &lt;a class="reference external" href="https://review.openstack.org/#/c/247372/"&gt;https://review.openstack.org/#/c/247372/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[3]: &lt;a class="reference external" href="https://review.openstack.org/#/c/252809/"&gt;https://review.openstack.org/#/c/252809/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[4]: &lt;a class="reference external" href="https://github.com/openstack/castellan"&gt;https://github.com/openstack/castellan&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[5]: &lt;a class="reference external" href="https://github.com/openstack/barbican"&gt;https://github.com/openstack/barbican&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[6]: &lt;a class="reference external" href="https://review.openstack.org/#/c/195443/"&gt;https://review.openstack.org/#/c/195443/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Mon, 23 Nov 2015 00:00:00 </pubDate></item><item><title>Integrate Castellan for Key Management</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/newton/use-castellan-key-manager.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/use-castellan-key-manager"&gt;https://blueprints.launchpad.net/cinder/+spec/use-castellan-key-manager&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Castellan is a key manager interface library that is intended to be usable
with multiple back ends, including Barbican. The Castellan code is based on
the basic key manager interface that resides in Nova and Cinder. Now that the
key manager interface lives in a separate library, the key manager code can be
removed from Nova and Cinder, and Castellan can be used as the key manager
interface instead.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;As encryption features in OpenStack projects are becoming more common, the
projects typically need a way to interface with a key manager. Different
deployers may have different requirements for key managers, so the key
manager interface must also be configurable to have different back ends. The
Castellan key manager interface was based off the key manager interfaces found
in Cinder and Nova. Now that the shared key manager interface lives in a
separate library, the original key manager interface embedded in Cinder can be
removed and Castellan used instead.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;Castellan supports existing features such as volume encryption.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Castellan must be added to the required libraries list.&lt;/p&gt;
&lt;p&gt;Castellan by default pulls configuration options from a Castellan-specific
configuration file in /etc/castellan, but can also take in configuration
options if passed in directly. The configuration options for the key manager
can still be specified in cinder.conf, and passed along to Castellan.&lt;/p&gt;
&lt;p&gt;The old key manager interface code and back end implementations in
cinder/keymgr and tests in cinder/tests/unit/keymgr can be removed. Any place
in the Cinder code where the key manager interface was called will be replaced
by calls to Castellan instead. Castellan does not include ConfKeyManager, an
insecure fixed-key key manager that reads the key from the configuration file.
The implementation for ConfKeyManager will remain in Cinder but will be
converted to a Castellan plugin to exercise the relevant code paths.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;The alternative is to leave the key manager interface as it is, but this means
that Cinder’s key manager will not benefit from the updates, new features, and
future additional back ends available in Castellan.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;Castellan behaves very similarly to the current Cinder key manager. Castellan
has added improvements and bug fixes beyond what is currently in the Nova and
Cinder key managers, making it more secure. The fixed-key key manager found in
Nova and Cinder is insecure for deployments, but is useful for testing.
Castellan doesn’t include the fixed-key key manager, so the ConfKeyManager
will be converted to a Castellan plugin and will remain in the Cinder code.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;The deployer should be made aware of a change in the default key manager back
end. The current default back end in Cinder is a fixed key, but Castellan uses
Barbican as the default. This means that the deployer should ensure Barbican is
running and the fixed key added to Barbican so it can continue to be used.&lt;/p&gt;
&lt;p&gt;The options in the Cinder configuration file for volume encryption will
change. The option ‘keymgr’ will be spelled out to ‘key_manager’. The key
manager option group will still have an option ‘api_class’ to specify the
desired back end. In the ‘barbican’ option group, a few new options will be
available to increase the robustness of the back end, such as the number of
times to check if a key has been successfully created.&lt;/p&gt;
&lt;p&gt;To maintain backwards compatibility, the old options will still be listed as
deprecated options. Standard deprecation policy will be followed, and these
old options should be removed in the next release cycle.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Cinder developers should not be impacted by this change. If developers find
more uses for a key manager, Castellan should be just as easy to use as the
current Cinder key manager interface.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Kaitlin Farr &amp;lt;&lt;a class="reference external" href="mailto:kaitlin.farr%40jhuapl.edu"&gt;kaitlin&lt;span&gt;.&lt;/span&gt;farr&lt;span&gt;@&lt;/span&gt;jhuapl&lt;span&gt;.&lt;/span&gt;edu&lt;/a&gt;&amp;gt; kfarr on IRC&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;None&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add Castellan to Cinder requirements.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Replace calls to Cinder’s key manager with calls to Castellan.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Remove Cinder key manager code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update documentation.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;This change depends on Castellan, version &amp;gt;= 0.2.0. Castellan is already in
OpenStack’s global requirements.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;This change can be unit tested using a simple in-memory back end. As actual
deployments should be using Barbican, this feature should be tested using a
Barbican back end, too.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;These changes will be documented. Cinder documentation for volume encryption
will be updated to reference Castellan [4].&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;[1] Castellan source code:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/castellan"&gt;https://github.com/openstack/castellan&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;[2] Castellan in OpenStack’s global requirements:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/requirements/blob/master/global-requirements.txt"&gt;https://github.com/openstack/requirements/blob/master/global-requirements.txt&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;[3] Current Cinder key manager implementation&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/cinder/tree/master/cinder/keymgr"&gt;https://github.com/openstack/cinder/tree/master/cinder/keymgr&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;[4] Volume encryption configuration reference&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/liberty/config-reference/content/section_volume-encryption.html"&gt;http://docs.openstack.org/liberty/config-reference/content/section_volume-encryption.html&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
</description><pubDate>Thu, 19 Nov 2015 00:00:00 </pubDate></item><item><title>Cinder Volume Active/Active support - Cleanup</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/newton/ha-aa-cleanup.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/cinder-volume-active-active-support"&gt;https://blueprints.launchpad.net/cinder/+spec/cinder-volume-active-active-support&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Right now cinder-volume service can run only in Active/Passive HA fashion.&lt;/p&gt;
&lt;p&gt;One of the reasons for this is that we have no concept of a cluster of nodes
that handle the same storage back-end, and we assume only one volume service
can access a specific storage back-end.&lt;/p&gt;
&lt;p&gt;Given this premise, current code handles the cleanup for failed volume services
as if no other service is working with resources from his back-end, and that is
problematic when there are other volume services working with those resources,
as is the case on an Active/Active configuration.&lt;/p&gt;
&lt;p&gt;This spec introduces a new cleanup mechanism and modifies current cleanup
mechanism so proper cleanup is done regardless of cinder configuration,
Active/Passive or Active/Active.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Current Cinder code only supports Active/Passive configurations, so the cleanup
takes that into account and cleans up resources from ongoing operations
accordingly, but that is incompatible with an Active/Active deployment.&lt;/p&gt;
&lt;p&gt;The incompatibility comes from the fact that volume services on startup look on
the DB for resources that are in the middle of an operation and are from their
own storage back-end - detected by the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;host&lt;/span&gt;&lt;/code&gt; field - and proceed to clean
them up depending on the state they are in.  For example a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;downloading&lt;/span&gt;&lt;/code&gt;
volume will be changed to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;error&lt;/span&gt;&lt;/code&gt; since the download was interrupted and we
cannot recover from it.&lt;/p&gt;
&lt;p&gt;With the new job distribution mechanism the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;host&lt;/span&gt;&lt;/code&gt; field will contain the
host configuration of the volume service that created the resource, but that
resource may now be in use by another volume service from the same cluster, so
we cannot just rely on this &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;host&lt;/span&gt;&lt;/code&gt; field for cleanup, as it may lead to
cleaning wrong resources or skipping the ones we should be cleaning.&lt;/p&gt;
&lt;p&gt;When we are working with an Active/Active system we cannot just clean all
resources from our storage-backend that are in an ongoing state, since they may
be legitimate undergoing jobs being handled by other volume services.&lt;/p&gt;
&lt;p&gt;We are going to forget for a moment how we are doing the cleanup right now and
focus on the different cleanup scenarios we have to cover.  One is when a
volume service “dies” -by that we mean that it really stops working, or it is
fenced- and failover boots another volume service to replace it as if it were
the same service -having the same &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;host&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cluster&lt;/span&gt;&lt;/code&gt; configurations-, and
the other scenario is when the service dies and no other service takes its
place, or the service that takes its place shares the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cluster&lt;/span&gt;&lt;/code&gt; configuration
but has a different &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;host&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Those are the cases we have to solve to be able to support Active/Active and
Active/Pasive configurations with proper cleanups.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;Operators that have hard requirements, SLA or other reasons, to have their
cloud operational at all times or have higher throughput requirements will want
to have the possibility to configure their deployments with an Active/Active
configuration and have proper cleanup of resources when services die.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Since checking for the status and the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;host&lt;/span&gt;&lt;/code&gt; field of the resource is no
longer enough to know if it needs cleanup -because the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;host&lt;/span&gt;&lt;/code&gt; field will be
referring to the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;host&lt;/span&gt;&lt;/code&gt; configuration of the volume service  that created the
resource and not the owner of the resource as explained in the &lt;a class="reference external" href="https://review.openstack.org/327283"&gt;Job
Distribution&lt;/a&gt; specs- we will create a new table to track which service from
the cluster is working on each resource.&lt;/p&gt;
&lt;p&gt;We’ll call this new table &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;workers&lt;/span&gt;&lt;/code&gt; and it will include all resources that
are being processed with cleanable operations, and therefore would require
cleanup if the service that is doing the operation crashed.&lt;/p&gt;
&lt;p&gt;When a cleanable job is requested by the API or any of the services -for
example a volume deletion can be requested by the API or by the c-vol service
during a migration- we will create a new row in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;workers&lt;/span&gt;&lt;/code&gt; table with the
resource we are working on and who is working on it.  And once the operation
has been completed -successfully or unsuccessfully- this row will be deleted to
indicate processing has concluded and a cleanup will no longer be needed if the
service dies.&lt;/p&gt;
&lt;p&gt;We will not be adding a row for non cleanable operations and resources that are
used in cleanable operations but won’t require cleanup, as this would create a
significant increase in DB operations that would end up affecting performance
of all operations.&lt;/p&gt;
&lt;p&gt;These &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;workers&lt;/span&gt;&lt;/code&gt; rows serve as &lt;em&gt;flags&lt;/em&gt; for the cleanup mechanism to know it
must check that resource in case of a crash and see if it needs cleanup.  There
can only exist 1 cleanable operation at a time for a given resource.&lt;/p&gt;
&lt;p&gt;To ensure that both scenarios mentioned above are taken care of, we will have
cleanup code on cinder-volume and Scheduler services.&lt;/p&gt;
&lt;p&gt;Cinder-volume service cleanups will be similar to the ones we currently have on
startup -&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;init_host&lt;/span&gt;&lt;/code&gt; method- but with small modifications to use the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;workers_table&lt;/span&gt;&lt;/code&gt; so services can tell which resources require cleanup because
they were left in the middle of an operation.  With this we take care of one of
the scenarios, but we still have to consider the case where no replacement
volume service comes up with the same &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;host&lt;/span&gt;&lt;/code&gt; configuration, and for that we
will add a mechanism on the scheduler that will take care of requesting other
volume service from the cluster, that manage the same backend, to do the
cleaning for the fallen service.&lt;/p&gt;
&lt;p&gt;The cleanup mechanism implemented on the scheduler will have manual and
automatic options, manual option will require the caller to specify which
services should be cleaned up using filters, and automatic operation will let
the scheduler decide which services should be cleaned up based on their status
and how long they have been down.&lt;/p&gt;
&lt;p&gt;Automatic cleanup mechanism will consist of a periodic task that will sample
services that are down, with a frequency of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;service_down_time&lt;/span&gt;&lt;/code&gt; seconds, and
will proceed to clean up resources that were left by those services that are
down after &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;auto_cleanup_checks&lt;/span&gt;&lt;/code&gt; x &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;service_down_time&lt;/span&gt;&lt;/code&gt; seconds have passed
since the service went down.&lt;/p&gt;
&lt;p&gt;Since we can have multiple Scheduler services and the cinder-volume service all
trying to do the cleanup simultaneously, code needs to be able handle these
situations.&lt;/p&gt;
&lt;p&gt;On one hand, to prevent multiple Schedulers from cleaning the same services’s
resources they will be reporting all automatic cleanup operations requested to
the cinder-volumes to the other Scheduler services and will ask other scheduler
services which services have already been cleaned on service start.&lt;/p&gt;
&lt;p&gt;On the other hand, to prevent cleanup concurrency issues if a cleanup is
requested on a service that is already being cleaned up, we will issue all
cleanup operations with a timestamp indicating that only &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;workers&lt;/span&gt;&lt;/code&gt; entries
before that should be cleaned up, so when a service starts doing the cleanup
for a resource it updates the entry an prevents additional cleanup operations
on the resource.&lt;/p&gt;
&lt;p&gt;Row deletion operations in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;workers&lt;/span&gt;&lt;/code&gt; table will be a real deletions in the
DB, not soft deletes like we do for other tables, because the number of
operations, and therefore of rows, will be quite high and because we will be
setting constraints on the rows that would not hold true if we had the same
resource multiple times (there are workarounds, but it doesn’t seem to be worth
it).&lt;/p&gt;
&lt;p&gt;Since these will be big, complex changes, we will not be enabling any kind of
automatic cleanup by default, and it will need to be either enabled in the
configuration using &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;auto_cleanup_enabled&lt;/span&gt;&lt;/code&gt; option or triggered using the
manual cleanup API -using filters- or the automatic cleanup API.&lt;/p&gt;
&lt;p&gt;It will be possible to trigger the automatic cleanup mechanism via the API even
when it is disabled, as the disabling only prevents it from being automatically
triggered.&lt;/p&gt;
&lt;p&gt;It is important to mention that using “reset-state” operation on any resource
will remove any existing &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;workers&lt;/span&gt;&lt;/code&gt; table entry in the DB.&lt;/p&gt;
&lt;p&gt;When proceeding with a cleanup we will ensure that no other service is working
on that resource (claiming the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;worker&lt;/span&gt;&lt;/code&gt;’s entry) and that the data on the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;workers&lt;/span&gt;&lt;/code&gt; entry is still valid for the given resource (status matches) since
a user may have forcefully issued another action on the resource in the
meantime..&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;There are multiple alternatives to proposed change, the most appealing ones
are:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Use Tooz with a DLM that allows Leader Election to prevent more than one
scheduler from doing cleanup of down services.  Downsides to this solution
are considerable:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Increased dependency on a DLM.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Limiting DLM choices since now it needs to have Leader Election
functionality.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We will still need to let other schedulers know when the leader does
cleanups because when electing a new leader will need this information to
determine if down services have already been cleaned.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;workers&lt;/span&gt;&lt;/code&gt; DB entries for every operation on a resource.
Disadvantages of this alternative are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Considerable performance impact.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Greatly increase cleanup mechanism complexity, as we would need to mark all
entries as being processed by the service we are going to clean (this has
its own complexity because multiple schedulers could be requesting it or a
scheduler and the service itself), then see which of those resources would
require cleanup according to the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;workers&lt;/span&gt;&lt;/code&gt; table and check if no other
service is already working on that resource because a user decided to do a
cleanup on his own (for example a force delete on a deleting resource) and
if there’s no other service working on the resource and the resource has a
status that is cleanable, then do the cleanup.  Doing all this without
races is quite complicated.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;Create new &lt;cite&gt;workers&lt;/cite&gt; table with following fields:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;id&lt;/span&gt;&lt;/code&gt;: To uniquely identify each entry and speed up some operations&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;created_at&lt;/span&gt;&lt;/code&gt;: To mark when the job was started at the API&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;updated_at&lt;/span&gt;&lt;/code&gt;: To mark when the job was last touched (API, SCH, VOL)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;deleted_at&lt;/span&gt;&lt;/code&gt;: Will not be used&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;resource_type&lt;/span&gt;&lt;/code&gt;: Resource type (Volume, Backup, Snapshot…)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;resource_id&lt;/span&gt;&lt;/code&gt;: UUID of the resource&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;status&lt;/span&gt;&lt;/code&gt;: The status that should be cleaned on service failure&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;service_id&lt;/span&gt;&lt;/code&gt;: service working on the resource&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;Two new admin only API endpoint will be created, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/workers/cleanup&lt;/span&gt;&lt;/code&gt; and
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/workers/auto_cleanup&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/workers/cleanup&lt;/span&gt;&lt;/code&gt; endpoint we will be able to supply filtering
parameters, but if no arguments are provided cleanup will issue a clean message
for all services that are down.  But we can restrict which services we want to
be cleaned using parameters &lt;cite&gt;service_id&lt;/cite&gt;, &lt;cite&gt;cluster_name&lt;/cite&gt;, &lt;cite&gt;host&lt;/cite&gt;, &lt;cite&gt;binary&lt;/cite&gt;,
&lt;cite&gt;disabled&lt;/cite&gt;.&lt;/p&gt;
&lt;p&gt;Cleaning specific resources is also possible using &lt;cite&gt;resource_type&lt;/cite&gt; and
&lt;cite&gt;resource_id&lt;/cite&gt; parameters.&lt;/p&gt;
&lt;p&gt;Cleanup cannot be triggered during a cloud upgrade, but a restarted service
will still cleanup it’s own resources during an upgrade.&lt;/p&gt;
&lt;p&gt;Both API endpoints will return a dictionary with 2 lists, one with services
that have been issued a cleanup request (&lt;cite&gt;cleaning&lt;/cite&gt;) and another list with
services that cannot be cleaned right now because there is no alternative
service to do the cleanup in that cluster (&lt;cite&gt;unavailable&lt;/cite&gt;), that way the caller
can know which services will be cleaned up.&lt;/p&gt;
&lt;p&gt;Data returned for each service in the lists are &lt;cite&gt;id&lt;/cite&gt;, &lt;cite&gt;name&lt;/cite&gt;, and &lt;cite&gt;state&lt;/cite&gt;
fields.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Small impact on cleanable operations since we have to use the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;workers&lt;/span&gt;&lt;/code&gt; table
to &lt;em&gt;flag&lt;/em&gt; that we are working on the resource.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Any developer that wants to add new resources requiring cleanup or wants add
cleanup for the status -new or existing- of an existing resource will have to
use the new mechanism to mark the resource as cleanable, add which states are
cleanable, and add the cleanup code.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Gorka Eguileor (geguileo)&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Michal Dulko (dulek)
Anyone is welcome to help&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Make DB changes to add the new &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;workers&lt;/span&gt;&lt;/code&gt; table.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement adding rows to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;workers&lt;/span&gt;&lt;/code&gt; table.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Change &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;host_init&lt;/span&gt;&lt;/code&gt; to use an RPC call for the cleanup.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify Scheduler code to do cleanups.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create devref explaining requirements to add cleanup resources/statuses.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;&lt;a class="reference external" href="https://review.openstack.org/327283"&gt;Job Distribution&lt;/a&gt;:&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;This depends on the job distribution mechanism so the cleanup can be done by
any available service from the same cluster.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unittests for new cleanup behavior.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Document new configuration option &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;auto_cleanup_enabled&lt;/span&gt;&lt;/code&gt; and
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;auto_cleanup_checks&lt;/span&gt;&lt;/code&gt; as well as the cleanup mechanism.&lt;/p&gt;
&lt;p&gt;Document behavior of reset-state on Active-Active deployment.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;General Description for HA A/A: &lt;a class="reference external" href="https://review.openstack.org/232599"&gt;https://review.openstack.org/232599&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Job Distribution for HA A/A: &lt;a class="reference external" href="https://review.openstack.org/327283"&gt;https://review.openstack.org/327283&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Tue, 13 Oct 2015 00:00:00 </pubDate></item><item><title>NFS Snapshots</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/mitaka/nfs-snapshots.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/nfs-snapshots"&gt;https://blueprints.launchpad.net/cinder/+spec/nfs-snapshots&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Add support for snapshots (create, delete, clone from) to the
NFS volume driver, so that it is as functional as other
Cinder drivers.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;The NFS driver does not support many features expected in a modern Cinder
driver.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;create snapshot&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;delete snapshot&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;clone from snapshot&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;The basic model for how snapshots can be implemented here has been proven
in the GlusterFS driver.  The general idea here is to re-use that same
model and much of the code for the NFS driver, which works the same as
the GlusterFS driver in general.&lt;/p&gt;
&lt;p&gt;In Juno, most of the snapshot-related code was refactored into a
RemoteFSSnapshot class.&lt;/p&gt;
&lt;p&gt;The NFS driver should inherit code from this base class (and probably
make minor changes) to gain snapshot support.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;No real alternative, baseline NFS servers do not have the ability to snapshot
files.  This method is already used in other Cinder drivers and works, so the
only alternative is to decide we don’t want snapshots for this driver.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;Nothing significant.&lt;/p&gt;
&lt;p&gt;initialize_connection will return additional fields specifying the format
of the volume file so that Nova knows how to attach it properly.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None, see notes here.&lt;/p&gt;
&lt;p&gt;This change needs to be tested with the NFS security infrastructure added
in Kilo to ensure nothing breaks and that all files before, after, and during
snapshot operations have the expected permissions.  There is no reason to
expect problems here.&lt;/p&gt;
&lt;p&gt;In Juno a security concern related to qcow2 file handling was addressed.
( &lt;a class="reference external" href="https://bugs.launchpad.net/cinder/+bug/1350504"&gt;https://bugs.launchpad.net/cinder/+bug/1350504&lt;/a&gt; )&lt;/p&gt;
&lt;p&gt;This is now considered fixed from a security perspective as there are no
known ways to exploit it, but is still being fixed in a more robust manner
in the “Support storing volume format info” spec.  This work is possible in
parallel as there is no strict interdependency here.
( &lt;a class="reference external" href="https://review.openstack.org/#/c/103750/"&gt;https://review.openstack.org/#/c/103750/&lt;/a&gt; )&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;We do not yet support backups of qcow2-based volumes.  (Unsure if targeted
in Kilo elsewhere.)&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;The NFS driver needs to have a per-volume-id lock for operations that
manipulate volume/snapshot data.  This does not cause any performance
regression in existing functionality and should not be a large concern
in most scenarios when using snapshots.&lt;/p&gt;
&lt;p&gt;See &lt;a class="reference external" href="https://review.openstack.org/#/c/106095/"&gt;https://review.openstack.org/#/c/106095/&lt;/a&gt; (GlusterFS example)&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;New config option, nfs_qcow2_volumes, to specify if you would like to
always create volume files as qcow2 images rather than raw.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;eharney and akerr (?)&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;NetApp has indicated they will CI this driver.  (bswartz)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Try to inherit RemoteFSSnapshot code into NFS driver.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Iterate on issues there.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Test security concerns.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Storing volume format info: &lt;a class="reference external" href="https://review.openstack.org/#/c/103750/"&gt;https://review.openstack.org/#/c/103750/&lt;/a&gt;&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Not a strict dependency, and which lands first is not vital, but this
effort also needs to land in Kilo along with this work and is strongly
related.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;I will submit another spec addressing the snapshot API between Cinder and
Nova which will be used here, but nothing there blocks this work.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Standard third-party CI of the NFS driver&lt;/p&gt;
&lt;p&gt;Consider testing this in-gate as a later effort&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;New config option, nfs_qcow2_volumes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Original snapshot effort which this is based on:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/qemu-assisted-snapshots"&gt;https://blueprints.launchpad.net/cinder/+spec/qemu-assisted-snapshots&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;RemoteFS snapshot code refactoring, done to support this effort:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/106066/"&gt;https://review.openstack.org/#/c/106066/&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;SMBFS volume driver, an example of another driver re-using this code:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/106046/"&gt;https://review.openstack.org/#/c/106046/&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
</description><pubDate>Tue, 29 Sep 2015 00:00:00 </pubDate></item><item><title>Attach/detach volumes without Nova</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/mitaka/use-cinder-without-nova.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/use-cinder-without-nova"&gt;https://blueprints.launchpad.net/cinder/+spec/use-cinder-without-nova&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Services like Ironic want to use Cinder w/o Nova. Also it would be useful
to attach Cinder volumes not only for Nova/Ironic instances: e.g. make
simple CLI to attach volume to some host (VM, workstation, etc) outside
OpenStack cloud.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently there is not a tool which could automate all the attach/detach
process without using Nova.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Attach volume to Ironic instance&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Attach volume to any virtual/baremetal host which is not provisioned by Nova
or Ironic&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Attach volume to Magnum container&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Attach volume to Docker container&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Provide a command-line (CLI) tool and Python API which could interact with
Cinder and attach volumes to the local host. It will be implemented as
python-cinderclient extension and won’t require to add any dependency if
extension is not used. This extension won’t be installed by default. Users
will be able to install it using PIP or OS package management tool:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;pip&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;brick&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;cinderclient&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ext&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;CLI interface e.g.:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;cinder&lt;/span&gt; &lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;attach&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;volume_id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;cinder&lt;/span&gt; &lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;detach&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;attachment&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="n"&gt;attachment&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;volume_id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;cinder&lt;/span&gt; &lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;connector&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;In case of Ironic when we don’t want to install any package into the user’s
instances. Users could install package themselves via &lt;cite&gt;pip&lt;/cite&gt; or OS package
managers (apt, yum, etc.).&lt;/p&gt;
&lt;p&gt;After this command cinder client will call Cinder API to change volume
status to ‘in-use’ because we don’t know when user will attach volume to the
host.&lt;/p&gt;
&lt;p&gt;Volume attachment:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;cinder&lt;/span&gt; &lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;attach&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;mountpoint&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;mnt&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;disk&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
                    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;multipath&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
                    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;enforce&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;multipath&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
                    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;mode&lt;/span&gt; &lt;span class="n"&gt;rw&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
                    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;volume_id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Volume detachment:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;cinder&lt;/span&gt; &lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;detach&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;attachment&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
                    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;multipath&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
                    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;enforce&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;multipath&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
                    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt; &lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
                    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;volume_id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;‘attachment_uuid’ is required option only for multi-attachment scenario.&lt;/p&gt;
&lt;p&gt;Detach procedure should contain the following steps:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;disconnect_volume&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;terminate_connection with a ‘force’ flag&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;detach&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Force detach feature is out of scope of this spec and will be described in a
separate spec.&lt;/p&gt;
&lt;p&gt;Get connector details:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;cinder get-connector&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Since mount/unmount is admin only operation we need to run python-cinderclient
as root to not add oslo.rootwrap dependency.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Cinder already has all needed APIs. Any API consumer could use existing
methods to implement attach/detach actions without Nova.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We can implement needed API inside new python-brickclient.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We can introduce new binary (e.g.: brick) inside python-cinderclient
project.
In such case we’ll have two different clients inside single repository.
From the packager’s point of view it will increase numbers of possible
python-cinderclient packages. E.g.: python-cinderclient-iscsci,
python-cinderclient-rbd, etc.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;TBD&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;This change will provide new CLI options and Python for python-cinderclient.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Deployers could install new package to have new functionality&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;All drivers should implement initialize_connection which could be invoked
several times without any side-effect. We’ve filed bugs for some of the
drivers.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Ivan Kolodyazhny &amp;lt;e0ne&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Implement proof-of-concept based on a python-cinderclient&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Get feedback and complete the spec&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fix typos in the spec&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make changes to Cinder API if needed&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unit-tests and Tempest tests are required&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Functional tests on python-cinderclient gates will be implemented&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;New repository for python-brick-cinderclient-ext is needed&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;os-brick&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;python-cinderclient&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Linux: open-iscsi, ceph-common, nfs-common or other tool to attach and detach
volumes via drivers’ protocols
Windows: tools for Windows to be able to attach and detach volume via
drivers’ protocols.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit-tests should be implemented&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;New python-cinderclient API will be tested via functional tests on gates
to test attach/detach features without Nova instances.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Functional tests for Ironic will be implemented to test attach/detach
features to Ironic instances.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;User manual will be updated to contain information about python-cinderclient
extension.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/254878"&gt;https://review.openstack.org/254878&lt;/a&gt; and related patches&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://lists.openstack.org/pipermail/openstack-dev/2015-July/068763.html"&gt;http://lists.openstack.org/pipermail/openstack-dev/2015-July/068763.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://etherpad.openstack.org/p/liberty-cinder-ironic-integration"&gt;https://etherpad.openstack.org/p/liberty-cinder-ironic-integration&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/ironic/+spec/volume-connection-information"&gt;https://blueprints.launchpad.net/ironic/+spec/volume-connection-information&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;python-brickclient Proof-of-Concept implementation: &lt;a class="reference external" href="https://github.com/e0ne/python-brickclient"&gt;https://github.com/e0ne/python-brickclient&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cinder Meeting Minutes: &lt;a class="reference external" href="http://goo.gl/ztuYTa"&gt;http://goo.gl/ztuYTa&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://eavesdrop.openstack.org/meetings/cinder/2015/cinder.2015-11-11-16.00.log.html"&gt;http://eavesdrop.openstack.org/meetings/cinder/2015/cinder.2015-11-11-16.00.log.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Wed, 16 Sep 2015 00:00:00 </pubDate></item><item><title>Update drivers to new base class structure</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/liberty/abc-driver-update.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/abc-driver-update"&gt;https://blueprints.launchpad.net/cinder/+spec/abc-driver-update&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The new abc structure was introduced by &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;bp/abc-volume-drivers&lt;/span&gt;&lt;/code&gt; [1]. All
drivers needs to get updated in order to benefit from the new structure.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Instead of raising NotImplementedErrors during runtime this features
allows to discovers the drivers feature set during startup and makes
it discoverable for CI/code check systems.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;The support matrix (see [2] for a draft implementation) can be extracted
to see the graduation process of new functionality moving to a common
function implemented by all drivers.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;All cinder volume drivers needs to get updated with the following approach:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;FooDriver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RetypeVD&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TransferVD&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ExtendVD&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CloneableVD&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CloneableImageVD&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SnapshotVD&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BaseVD&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;A drivers must inherit from BaseVD and implement the basic functions. In order
to mark that a driver does implement further feature sets it must inherit from
the corresponding class.&lt;/p&gt;
&lt;p&gt;If all drivers implement a certain feature set the functions will be moved to
BasicVD at the end.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;No porting at all, which would make the [1] pointless.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;See [1]&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;This change will change all implemented drivers slightly. The functionality
itself shouldn’t be changed at all but all driver need to be adopted to the
new class model.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Marc Koderer (m-koderer)&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;All driver maintainers&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;Etherpad if necessary.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Individual driver unit tests needs to get adapted.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;[1]: &lt;a class="reference external" href="https://review.openstack.org/#/c/114168/"&gt;https://review.openstack.org/#/c/114168/&lt;/a&gt;
[2]: &lt;a class="reference external" href="https://review.openstack.org/#/c/160346/"&gt;https://review.openstack.org/#/c/160346/&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Fri, 28 Aug 2015 00:00:00 </pubDate></item><item><title>Allow brick to support other iSCSI transports besides TCP</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/liberty/brick-add-open-iscsi-transport-suppport.html</link><description>

&lt;p&gt;Include the URL of your launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/brick-add-open-iscsi-transport-support"&gt;https://blueprints.launchpad.net/cinder/+spec/brick-add-open-iscsi-transport-support&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Currently open-iscsi in openstack does not allow the use of offload iscsi
transports (cxgb4i, qla4xx, bnx2i etc) or other software iscsi transports
(like iser). This blueprint aims to add support for this&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;open-iscsi has hardware iSCSI transport support. The interface argument
specifies the hardware iSCSI interface to use for the operation. Any hardware
vendors that currently  provide hardware interfaces for open-iscsi cannot use
them in  openstack as the interfaces (iface) argument is not currently
supported in the iSCSI driver.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;Use of such iSCSI hardware transports requires providing a corresponding
interface file (referred to as iface), which can be autogenerated via iscsiadm
but need correctness checks or can also be generated on the fly, given the
3-tuple of ipaddress, hwaddress &amp;amp; transport name to be used. The iface format
itself is generic and does not use any propreitary fields irrespective of
transport being used.&lt;/p&gt;
&lt;p&gt;These changes are already in nova, code can be seen here :
&lt;a class="reference external" href="https://review.openstack.org/#/c/146233/"&gt;https://review.openstack.org/#/c/146233/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This will also enable use of iSER directly through the iSCSI driver, though
deprecating the iSER driver is not the aim of this spec, and will probably
start with iSER disabled, (and also because iSER requires target support
unlike hardware transports)&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;On the initiator side the only difference between using software iSCSI and
hardware iSCSI transport is the interface flag (–interface=[iface])&lt;/p&gt;
&lt;p&gt;e.g. “iscsiadm -m discovery -t st -p ip:port -I &amp;lt;iface file&amp;gt;”&lt;/p&gt;
&lt;p&gt;iface files can automatically be generated for all hardware present on a
system that is supported by open-iscsi by ‘iscsiadm -m iface’. The default
format for iface file names is in the form &amp;lt;transport_name.hw_address&amp;gt;&lt;/p&gt;
&lt;p&gt;The default iface name is ‘default’. Not using the -I parameter (which is how
open-iscsi  is currently being used in nova) is the same as specifying&lt;/p&gt;
&lt;p&gt;‘iscsiadm -m discovery -t st -p ip:port -I default’&lt;/p&gt;
&lt;p&gt;Required changes are :&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;A new parameter to specify which transport should be used while doing iscsi
discovery/login, falling back to TCP if operation does not succeed, or if
parameter is not provided (-I default)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Offloaded transports use the device path with a prefix pci-0000:00:00.0-,
change related code to handle this&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Use manual discovery of iscsi-targets, and provide -I parameter when doing
discovery. Transport names are written in the resultant records generated by
open-iscsi, however this does not guarantee hardware transports will be used,
as this can be overridden with depending on how cli params are constructed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Actual iSCSI performance can generally be improved by using transports over
iscsi_tcp, no other impact.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;This can be used to deprecate the separate iSER connector, as use of iser
simply implies providing -I iser param to iscsiadm&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;anish7 &amp;lt;&lt;a class="reference external" href="mailto:anish%40chelsio.com"&gt;anish&lt;span&gt;@&lt;/span&gt;chelsio&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add -I parameter to all iscsiadm login/discovery commands currently being
used in brick&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add prefix support to _get_device_path()&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None as such. However, the minimum information required for using a tansport
if it is not already configured is a 3 tuple of ip, transport name &amp;amp; hardware
address.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Current iSCSI tests will work just fine, run separately using a faux transport
(open-iscsi already supports this ability)&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Use of transport ifaces will need relevant documentation.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/os-brick/+bug/1370226"&gt;https://bugs.launchpad.net/os-brick/+bug/1370226&lt;/a&gt; (Launchpad bug this addresses)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/146233/"&gt;https://review.openstack.org/#/c/146233/&lt;/a&gt; (Corresponding code in nova)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://www.open-iscsi.org/docs/README"&gt;http://www.open-iscsi.org/docs/README&lt;/a&gt; (Section 5.1 iSCSI iface setup)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://red.ht/1BJxsjL"&gt;http://red.ht/1BJxsjL&lt;/a&gt; (Configuring an iface for iSCSI Offload, RedHat documentation)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Fri, 28 Aug 2015 00:00:00 </pubDate></item><item><title>Extract Brick library from Cinder</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/liberty/extract-brick.html</link><description>

&lt;p&gt;Include the URL of your launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/extract-brick"&gt;https://blueprints.launchpad.net/cinder/+spec/extract-brick&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This Specification talks about 2 points.  First the extraction
of the brick/cinder directory into it’s own standalone library.
Second, changing cinder to use the external library.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;The idea of ‘brick’ was created back in the Havana timeframe.  All along
it was meant to be a standalone library that Cinder, Nova and any other
project in OpenStack could use.  Currently brick lives in a directory
inside of Cinder, which means that only Cinder can use it.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;Use the same library code both in Nova and Cinder.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;We want to extract the brick directory and encapsulate it into it’s own pypi
library that any python project can use.&lt;/p&gt;
&lt;p&gt;So we need to do:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;First create a separate python project and release it into pypi&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add brick to cinder’s requirements.txt&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Remove the existing cinder/brick directory&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Everywhere in Cinder that uses cinder/brick will need to be modified to use
the new pypi library.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;We could simply keep brick inside of Cinder and not share it’s code.  The
problem with this is that any changes/fixes to brick will then need to be
backported into the same code in Nova. This is the existing problem.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;This doesn’t change the data model for Cinder.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;Any security related issues that impact brick may impact anything in Cinder
that would use the new library.   Brick will be placed into stackforge for
code reviews, so anyone can contribute fixes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;There should be no performance impact, as the same code will exist in the
pypi brick library as it does today in Cinder.   The import will pull the
library from a system installed location instead of the cinder codebase.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;Brick will be a requirement for Cinder.  So whoever builds distribution
packages for cinder will also need to ensure that brick gets installed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Currently, any Cinder developer can add new features and fix bugs in brick
as part of the Cinder project.   Going forward, developers will need to clone
the source of brick from stackforge and make their changes there.&lt;/p&gt;
&lt;p&gt;The downside to this is that If there are new features, APIs or interface
changes in the brick library, a release will have to be published in order
for Cinder to get those changes.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Walter A. Boring IV - walter-boring&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;e0ne&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;I have already started the work of creating a standalone brick library here:
&lt;a class="reference external" href="https://github.com/hemna/cinder-brick"&gt;https://github.com/hemna/cinder-brick&lt;/a&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;This repo will need to be registered into stackforge, so brick can benefit
from the community process and gerrit.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Once in stackforge, an official release needs to be made so that the package
exists in pypi.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Then a patch to Cinder can be made to add it to the requirements.txt&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The another patch to follow that removes brick/cinder and adjusts all of
Cinder to use the new library.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;All of the existing unit tests in cinder for brick can remain to ensure that it
works as advertised.   The existing Cinder brick unit tests will be migrated to
the new project and run there as well.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Existing standalone project: &lt;a class="reference external" href="https://github.com/hemna/cinder-brick"&gt;https://github.com/hemna/cinder-brick&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The original Cinder brick proposal
&lt;a class="reference external" href="https://wiki.openstack.org/wiki/CinderBrick"&gt;https://wiki.openstack.org/wiki/CinderBrick&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Fri, 28 Aug 2015 00:00:00 </pubDate></item><item><title>Standard Capabilities</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/liberty/standard-capabilities.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/standard-capabilities"&gt;https://blueprints.launchpad.net/cinder/+spec/standard-capabilities&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;For the Liberty release there is a proposal [1] to allow storage backends to
push capabilities of their pools [1]. Eventually we would want some common
capabilities to graduate into becoming a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;well&lt;/span&gt; &lt;span class="pre"&gt;defined&lt;/span&gt;&lt;/code&gt; capability. The
point of this spec is to agree on the initial &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;well&lt;/span&gt; &lt;span class="pre"&gt;defined&lt;/span&gt;&lt;/code&gt; capabilities.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;Having the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;well&lt;/span&gt; &lt;span class="pre"&gt;defined&lt;/span&gt;&lt;/code&gt; capabilities will allow the deployer to see what
common capabilities are shared beyond their deployed backends in Cinder.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;The initial &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;well&lt;/span&gt; &lt;span class="pre"&gt;defined&lt;/span&gt;&lt;/code&gt; capabilities are:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;QOS&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Compression&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Replication&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Thin provisioning&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Keep in mind this is just an agreement that these are common features that
a backend could support. As shown in the proposal of how this will work [1],
backends will still be able to push up the specific keys they look for in
volume types for these capabilities.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None. This information comes directly from the volume drivers, reported to the
scheduler, to the Cinder API.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Volume driver maintainers will need report capabilities from their driver to
the scheduler. They can get this information directly from the backend and pass
it right up to the scheduler if it already follows the format specified
earlier. If not, it’s up to the driver to parse the response from the backend
in a format the scheduler will understand. If capabilities are not being
reported, the default &lt;strong&gt;False&lt;/strong&gt; on features will be done.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;thingee&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Standardize on the Capabilities here. Right here, right now.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;The developer docs for driver maintainers will need to be updated to include
the list of common capabilities the maintainer needs to have their driver push
that they support. By default capabilities are marked as False, as in not being
supported by the driver.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;[1] - &lt;a class="reference external" href="https://review.openstack.org/#/c/183947/"&gt;https://review.openstack.org/#/c/183947/&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Fri, 28 Aug 2015 00:00:00 </pubDate></item><item><title>Add Cinder Support for DB2 (v10.5+)</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/liberty/db2-database.html</link><description>

&lt;p&gt;Include the URL of your launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/db2-database"&gt;https://blueprints.launchpad.net/cinder/+spec/db2-database&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The community currently supports MySQL and PostgreSQL production databases.
Several other core projects already support DB2 (Keystone, Glance, Ceilometer,
Heat). This blueprint adds support to Cinder for DB2 as a production
database.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Currently there is no support in the community for a deployer to run Cinder
against a DB2 backend database.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For anyone running applications against an existing DB2 database that wants
to move to OpenStack, they’d have to use a different database engine to
run Cinder in OpenStack.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There is currently an inconsistent support matrix across the core projects
since the majority of core projects support DB2 but Cinder does not
yet.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;The changes required to enable Cinder to run on DB2 are limited given that
Cinder’s database structure is not complicated.  No changes are currently
required to the migration scripts to enable deployment on a DB2 database.&lt;/p&gt;
&lt;p&gt;Unit test will need to be updated to support running tests against a DB2
backend with the ibm_db_sa driver and all Cinder patches will be tested
against a Tempest full run with 3rd party CI running DB2, maintained by IBM.
Note that these 3rd Party CI runs have already been enabled for Cinder.&lt;/p&gt;
&lt;p&gt;There is already code in Oslo’s db.api layer to support common function
with DB2 like duplicate entry error handling and connection trace, so that is
not part of this spec.  Cinder, however, will need to sync up to the latest
Oslo DB code to enable DB2 support.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Deployers can use other supported database backends like MySQL or PostgreSQL,
but this may not be an ideal option for customers already running applications
with DB2 that want to integrate with OpenStack. In addition, you could run
other core projects with multiple schemas in a single DB2 OpenStack database,
but you’d have to run Cinder separately which is a maintenance/configuration
problem.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;There are no impacts on the current Cinder data model.  Any issues that arise
due to future changes will be uncovered by the 3rd Party CI tests and will be
able to be addressed at that point in time.&lt;/p&gt;
&lt;p&gt;The one exception to this statement is in the unit test path.  I made two
commits in Icehouse to start implementing the infrastructure to enable DB2
unit testing.  The commits were to add a bool_type dictionary
(2a7b11922bd9389287915c45de92ca5eed3d448e) and a time_type dictionary
(a9527de9ed3a2eae951564c3c74b7319113e8bf5).  I will need to add the
appropriate types for DB2, as was done for MySQL, as part of the unit test
changes I will be making for DB2.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Execution of migration unit tests on DB2 may take longer than on other
backend databases due to the time required to create the database schema.
This impact, however, will only be seen when running unit tests for DB2.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;There are no plans to migrate the Cinder database from a pre-existing
installation (I.E. MySQL) to DB2.  So deployers will need to be starting
with a fresh Cinder installation to enable DB2 as a backend database.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;The only impact on developers is if they are adding DB API code or migrations
that don’t work with DB2, they will have to adjust those appropriately, just
like we do today with MySQL and PostgreSQL. IBM ATCs would provide
support/guidance on issues like this which require specific conditions for DB2,
although for the most part, the DB2 InfoCenter provides adequate detail on how
to work with the engine and provides details on error codes.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;DB2 SQL error message explanations can be found here:
&lt;a class="reference external" href="http://pic.dhe.ibm.com/infocenter/db2luw/v10r5/index.jsp?topic=%2Fcom.ibm.db2.luw.messages.sql.doc%2Fdoc%2Frsqlmsg.html"&gt;http://pic.dhe.ibm.com/infocenter/db2luw/v10r5/index.jsp?topic=%2Fcom.ibm.db2.luw.messages.sql.doc%2Fdoc%2Frsqlmsg.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Information on developing with DB2 using python can be found here:
&lt;a class="reference external" href="http://pic.dhe.ibm.com/infocenter/db2luw/v10r5/index.jsp?topic=%2Fcom.ibm.swg.im.dbclient.python.doc%2Fdoc%2Fc0054366.html"&gt;http://pic.dhe.ibm.com/infocenter/db2luw/v10r5/index.jsp?topic=%2Fcom.ibm.swg.im.dbclient.python.doc%2Fdoc%2Fc0054366.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Main contacts for DB2 questions in OpenStack:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Matt Riedemann (&lt;a class="reference external" href="mailto:mriedem%40us.ibm.com"&gt;mriedem&lt;span&gt;@&lt;/span&gt;us&lt;span&gt;.&lt;/span&gt;ibm&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;) - Nova core member&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Brant Knudson (&lt;a class="reference external" href="mailto:bknudson%40us.ibm.com"&gt;bknudson&lt;span&gt;@&lt;/span&gt;us&lt;span&gt;.&lt;/span&gt;ibm&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;) - Keystone core member&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Jay Bryant (&lt;a class="reference external" href="mailto:jsbryant%40us.ibm.com"&gt;jsbryant&lt;span&gt;@&lt;/span&gt;us&lt;span&gt;.&lt;/span&gt;ibm&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;) - Cinder core member&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Rahul Priyadarshi (&lt;a class="reference external" href="mailto:rahul.priyadarshi%40in.ibm.com"&gt;rahul&lt;span&gt;.&lt;/span&gt;priyadarshi&lt;span&gt;@&lt;/span&gt;in&lt;span&gt;.&lt;/span&gt;ibm&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;) - ibm_db_sa maintainer&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Email: &lt;a class="reference external" href="mailto:jsbryant%40us.ibm.com"&gt;jsbryant&lt;span&gt;@&lt;/span&gt;us&lt;span&gt;.&lt;/span&gt;ibm&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;
Launchpad ID: jsbryant&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Make the test_migrations.py module work with a configured DB2 backend for
running unit tests.&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Add the appropriate column types for DB2.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add support for creating the DB2 schema for Cinder testing.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;DB2 support was added to sqlalchemy-migrate 0.9 during Icehouse:
&lt;a class="reference external" href="https://blueprints.launchpad.net/sqlalchemy-migrate/+spec/add-db2-support"&gt;https://blueprints.launchpad.net/sqlalchemy-migrate/+spec/add-db2-support&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There are no requirements changes in Cinder for the unit tests to work. The
runtime requirements are the ibm-db-sa and ibm_db modules, which are both
available from pypi. sqlalchemy-migrate optionally imports ibm-db-sa. The
ibm-db-sa module requires a natively compiled ibm_db which has the c binding
that talks to the DB2 ODBC/CLI driver.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Note that only DB2 10.5+ is supported since that’s what added unique index
support over nullable columns which is how sqlalchemy-migrate handles unique
constraints over nullable columns.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;IBM is already running 3rd party CI for DB2 on Cinder.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DB2 Unit Test for Cinder will be enabled.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The install guides in the community do not go into specifics about setting up
the database.  The RHEL/Fedora install guide says to use the openstack-db
script provided by openstack-utils in RDO which uses MySQL.  The other
install guides just say that SQLite3, MySQL and PostgreSQL are widely used
databases. So for the install guides, those generic statements about
supported databases would be updated to add DB2 to the list. Similar generic
statements are also made in the following places which would be updated as
well:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/training-guides/content/developer-getting-started.html"&gt;http://docs.openstack.org/training-guides/content/developer-getting-started.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/admin-guide/compute.html"&gt;http://docs.openstack.org/admin-guide/compute.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/trunk/openstack-ops/content/cloud_controller_design.html"&gt;http://docs.openstack.org/trunk/openstack-ops/content/cloud_controller_design.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There are database topics in the security guide, so there would be DB2
considerations there as well, specifically:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/security-guide/databases/database-backend-considerations.html"&gt;http://docs.openstack.org/security-guide/databases/database-backend-considerations.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/security-guide/databases/database-transport-security.html"&gt;http://docs.openstack.org/security-guide/databases/database-transport-security.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;There are Chef cookbooks on stackforge which support configuring OpenStack
to run with an existing DB2 installation:
&lt;a class="reference external" href="http://git.openstack.org/cgit/stackforge/cookbook-openstack-common/"&gt;http://git.openstack.org/cgit/stackforge/cookbook-openstack-common/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A wiki document originally written to describe DB2 for OpenStack:
&lt;a class="reference external" href="https://wiki.openstack.org/wiki/DB2Enablement"&gt;https://wiki.openstack.org/wiki/DB2Enablement&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DB2 10.5 InfoCenter: &lt;a class="reference external" href="http://pic.dhe.ibm.com/infocenter/db2luw/v10r5/index.jsp"&gt;http://pic.dhe.ibm.com/infocenter/db2luw/v10r5/index.jsp&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Some older manual setup instructions for DB2 with OpenStack:
&lt;a class="reference external" href="http://www.ibm.com/developerworks/cloud/library/cl-openstackdb2/index.html"&gt;http://www.ibm.com/developerworks/cloud/library/cl-openstackdb2/index.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ibm-db-sa: &lt;a class="reference external" href="https://code.google.com/p/ibm-db/source/clones?repo=ibm-db-sa"&gt;https://code.google.com/p/ibm-db/source/clones?repo=ibm-db-sa&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Mon, 24 Aug 2015 00:00:00 </pubDate></item><item><title>Efficient volume copy for volume migration</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/liberty/efficient-volume-copy-for-volume-migration.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/efficient-volume-copy-for-cinder-assisted-migration"&gt;https://blueprints.launchpad.net/cinder/+spec/efficient-volume-copy-for-cinder-assisted-migration&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Currently, cinder supports these 3 ways for volume migration.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;#&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Migration method&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Data copy method&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Handler of migration&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;1&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;storage driver&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;depend on vendor storage&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;inside storage array&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;2&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;copy_volume_data()&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;dd command&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;cinder volume node&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;3&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;swap_volume()&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;libvirt block rebase copy&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;nova compute node&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;During volume migration case #2, Cinder uses dd command for data copy
of volume migration, but the copy always copies full blocks even if
the source data contains many null and zero blocks.
The dd command has an option conv=sparse to skip null or zero blocks for
more efficient data copy.&lt;/p&gt;
&lt;p&gt;The purpose of this request is to introduce a mechanism to handle sparse
copy option properly for volume migration using dd command.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;If we create a volume from thin-provisioning pool, volume blocks are
not pre-allocated, and the volume blocks will be allocated on demand.
In this situation, if we migrate detached volume using dd command,
dd will copy full block from source to destination volume even if
the source volume contains many null or zero blocks. As a result,
usage of the destination volume will be always 100%. Here is an example
volume migration using thin LVM driver.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Before migration&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;LV&lt;/span&gt;            &lt;span class="n"&gt;VG&lt;/span&gt;    &lt;span class="n"&gt;Attr&lt;/span&gt;       &lt;span class="n"&gt;LSize&lt;/span&gt;   &lt;span class="n"&gt;Pool&lt;/span&gt;     &lt;span class="n"&gt;Origin&lt;/span&gt; &lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;
&lt;span class="n"&gt;vg1&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;pool&lt;/span&gt;      &lt;span class="n"&gt;vg1&lt;/span&gt;   &lt;span class="n"&gt;twi&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;tz&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;   &lt;span class="mf"&gt;3.80&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt;                &lt;span class="mf"&gt;10.28&lt;/span&gt;
&lt;span class="n"&gt;volume&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1234&lt;/span&gt;   &lt;span class="n"&gt;vg1&lt;/span&gt;   &lt;span class="n"&gt;Vwi&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;tz&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;   &lt;span class="mf"&gt;1.00&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt; &lt;span class="n"&gt;vg1&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;pool&lt;/span&gt;       &lt;span class="mf"&gt;19.53&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;After migration without conv=sparse option&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;LV&lt;/span&gt;            &lt;span class="n"&gt;VG&lt;/span&gt;    &lt;span class="n"&gt;Attr&lt;/span&gt;       &lt;span class="n"&gt;LSize&lt;/span&gt;   &lt;span class="n"&gt;Pool&lt;/span&gt;     &lt;span class="n"&gt;Origin&lt;/span&gt; &lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;
&lt;span class="n"&gt;vg2&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;pool&lt;/span&gt;      &lt;span class="n"&gt;vg2&lt;/span&gt;   &lt;span class="n"&gt;twi&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;tz&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;   &lt;span class="mf"&gt;3.80&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt;                &lt;span class="mf"&gt;31.45&lt;/span&gt;
&lt;span class="n"&gt;volume&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1234&lt;/span&gt;   &lt;span class="n"&gt;vg2&lt;/span&gt;   &lt;span class="n"&gt;Vwi&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;tz&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;   &lt;span class="mf"&gt;1.00&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt; &lt;span class="n"&gt;vg2&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;pool&lt;/span&gt;      &lt;span class="mf"&gt;100.00&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;Using sparse copy is able to reduce volume usage of destination storage
array compared to using full block copy.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;If the volume pre-initilization(zero cleared) is ensured beforehand
at the destination c-vol, we can skip copy of null and zero blocks
to destination volume by using conv=sparse option for dd.&lt;/p&gt;
&lt;p&gt;However, if the destination volume is not zero cleared beforehand,
we should disable sparse copy and copy full block from source to
destination volume to avoid data corruption problem.&lt;/p&gt;
&lt;p&gt;For example, following case, we should disable sparse copy and copy
full block because new volume of thick LVM might not be initialized,
we must not use conv=sparse option for similar cases.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Source c-vol driver: Thin LVM&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Dest c-vol driver: Drivers who provides an uninitialized new volume.
(ex. Thick LVM)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In order to handle sparse option properly, following changes
are required.&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Add cinder_sparse_copy_volume capability into capabilities list
as a well-defined option.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="s1"&gt;'cinder_sparse_copy_volume'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'False'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ol class="arabic simple" start="2"&gt;
&lt;li&gt;&lt;p&gt;Get capability list from the “destination cinder volume driver”
using &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;get_capabilities&lt;/span&gt;&lt;/code&gt; method before starting volume copy.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;get_capabilities&lt;/span&gt;&lt;/code&gt; method is proposed following Spec.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Updating Get Volume Driver Capabilities Spec:
&lt;a class="reference external" href="https://review.openstack.org/#/c/183947/1"&gt;https://review.openstack.org/#/c/183947/1&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These are steps of migrate_volume related to sparse copy.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;vol&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;                   &lt;span class="n"&gt;dest&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;vol&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt;                                           &lt;span class="o"&gt;|&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;========================================&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="n"&gt;Ask&lt;/span&gt; &lt;span class="n"&gt;capability&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;sparse&lt;/span&gt; &lt;span class="n"&gt;copy&lt;/span&gt; &lt;span class="n"&gt;via&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="n"&gt;get_capabilities&lt;/span&gt;                        &lt;span class="o"&gt;|&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;========================================&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="n"&gt;Dest&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;vol&lt;/span&gt; &lt;span class="n"&gt;returns&lt;/span&gt; &lt;span class="n"&gt;capabilities&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;vol&lt;/span&gt;                            &lt;span class="o"&gt;|&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;========================================&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Start&lt;/span&gt; &lt;span class="n"&gt;volume&lt;/span&gt; &lt;span class="n"&gt;copy&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;without&lt;/span&gt; &lt;span class="n"&gt;sparse&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;based&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;retun&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;dest&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;vol&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt;                                           &lt;span class="o"&gt;|&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Copy full blocks from source volume to destination volume. And then,
try fstrim or blkdiscard to release unused blocks to backend storage.
However, if the backend storage doesn’t support UNMAP SCSI command,
we can’t release unused blocks after migration.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;Add cinder_sparse_copy_volume parameter as a well_defined capability.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="s1"&gt;'cinder_sparse_copy_volume'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'False'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;This feature improves required time to copy data between source and
destination volume.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;mitsuhiro-tanino&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Add cinder_sparse_copy_volume capability into capabilities list.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add handler of get_capabilities in migrate_volume method.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update LVM reference implementation with cinder_sparse_copy_volume
capability.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update NFS driver with cinder_sparse_copy_volume capability:&lt;/p&gt;
&lt;p&gt;NFS driver already has _sparse_copy_volume_data option but this way
doesn’t ask capability to destination cinder volume before volume copy.
We should use same way to handle sparse copy.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit tests&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Need to update openstack cloud administrator guide.
&lt;a class="reference external" href="http://docs.openstack.org/admin-guide/blockstorage_volume_migration.html"&gt;http://docs.openstack.org/admin-guide/blockstorage_volume_migration.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Related Cinder Spec&lt;/p&gt;
&lt;p&gt;Updating Get Volume Driver Capabilities Spec:
&lt;a class="reference external" href="https://review.openstack.org/#/c/183947/1"&gt;https://review.openstack.org/#/c/183947/1&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Related fix&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/183633/"&gt;https://review.openstack.org/#/c/183633/&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Mon, 24 Aug 2015 00:00:00 </pubDate></item><item><title>Incremental backup improvements for L</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/liberty/incremental-backup-improvements-for-l.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/cinder-incremental-backup-improvements-for-l"&gt;https://blueprints.launchpad.net/cinder/+spec/cinder-incremental-backup-improvements-for-l&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This specification proposes to improve the current incremental backup by adding
is_incremental  and has_dependent_backups flags to indicate the type of backup
and enriching the notification system via adding parent_id to report.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;In Kilo release we supported incremental backup, but there are still some
points that need to be improved.
1. From the API perspective, there is no place to show the backup is
incremental or not.
2. User also doesn’t know if the incremental backup can be deleted or not,
It’s important that Cinder doesn’t allow this backup to be deleted since
‘Incremental backups exist for this backup’. Currently, they must have a try to
know it. So if there is a flag to indicate the backup can’t be deleted or not,
it will bring more convenience to user and reduce API call.
3. Enriching the notification system via reporting to Ceilometer,
add parent_id to report&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;It’s useful for 3rd party billing system to distinguish the full backup and
incremental backup, as using different size of storage space, they could have
different fee for full and incremental backups.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;1. When show single backup detail, cinder-api needs to judge if this backup is
a full backup or not checking backup[‘parent_id’].
2. If it’s an incremental backup, judge if this backup has dependent backups
like we do in process of delete backup.
3. Then add ‘is_incremental=True’ and ‘has_dependent_backups=True/False’ to
response body.
4. Add parent_id to notification system.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;The response body of show incremental backup detail is changed like this:&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;::&lt;/dt&gt;&lt;dd&gt;&lt;dl&gt;
&lt;dt&gt;{&lt;/dt&gt;&lt;dd&gt;&lt;dl&gt;
&lt;dt&gt;“backup”: {&lt;/dt&gt;&lt;dd&gt;&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;……,
“is_incremental”: True/False,
“has_dependent_backups”: True/False&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;If there is full backup, the is_incremental flag will be False.
And has_dependent_backups will be True if the full backup has dependent
backups.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;Add parent_id to backup notification.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;End user can get more info about incremental backup. Enhance user experience.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Because we add an additional judgment for dependent backups. We can eliminate
performance impact by adding index to backup table and counting the number of
dependent backups to make judgment in SQL.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;wanghao&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add querying and judging code in cinder-api.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add parent_id to notification system.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add unit tests.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit tests are needed to ensure response is working correctly.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;1. Cloud admin documentations will be updated to introduce the changes:
&lt;a class="reference external" href="http://docs.openstack.org/admin-guide/blockstorage_volume_backups.html"&gt;http://docs.openstack.org/admin-guide/blockstorage_volume_backups.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;2. API ref will be also updated for backups:
&lt;a class="reference external" href="http://developer.openstack.org/api-ref-blockstorage-v2.html"&gt;http://developer.openstack.org/api-ref-blockstorage-v2.html&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Mon, 24 Aug 2015 00:00:00 </pubDate></item><item><title>Add ability for Cinder backend to report discard/unmap/trim</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/liberty/cinder-backend-report-discard.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/cinder-backend-report-discard"&gt;https://blueprints.launchpad.net/cinder/+spec/cinder-backend-report-discard&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Currently, libvirt/qemu has support for a discard option when attaching a
volume to an instance. With this feature, the unmap/trim command can be sent
from guest to the physical storage device.&lt;/p&gt;
&lt;p&gt;A cinder back-end should report a connection capability that can be used to
instruct Nova how to attach a volume.&lt;/p&gt;
&lt;p&gt;This spec aims to add the assist to support enabling discard for cinder
volumes.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently there is no way for Nova to know if a Cinder back end supports
discard/trim/unmap functionality.  This aims to provide that info to Nova.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;If a Cinder backed uses media that can make use of discard functionality
there should be a way to do this.  This will improve long term performance
of such back ends.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Any driver which wants to support this will just add an entry to the
properties returned by intialize_connection.&lt;/p&gt;
&lt;p&gt;“discard”: True,&lt;/p&gt;
&lt;p&gt;An example from the Pure Storage driver would be&lt;/p&gt;
&lt;div class="highlight-Python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;properties&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"driver_volume_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"iscsi"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"target_iqn"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;target_port&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"iqn"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s2"&gt;"target_portal"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;target_port&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"portal"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s2"&gt;"target_lun"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"lun"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s2"&gt;"target_discovered"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"access_mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"rw"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"discard"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Alternatives include adding a setting to cinder.conf for each backend that
supports this. This includes a manual step that would be more error prone.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;Documentation on the response to ‘initialize_connection’ will need to be
updated with notes explaining that this new info is provided.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;There will be a performance gain for back ends that benefit from having
discard functionality.&lt;/p&gt;
&lt;p&gt;See &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Trim_(computing"&gt;https://en.wikipedia.org/wiki/Trim_(computing&lt;/a&gt;) for more info.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;Deployers will need to add some properties to Glance images to make
this work.  Once an instance is booted from the modified image the
discard capability reported by the driver will be activated.&lt;/p&gt;
&lt;p&gt;hw_scsi_model=virtio-scsi
hw_disk_bus=scsi&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;glance image-update –property hw_scsi_model=virtio-scsi&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;–property hw_disk_bus=scsi &amp;lt;image-uuid&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;This causes the correct controller to be created on the instance
via code changes here &lt;a class="reference external" href="https://review.openstack.org/#/c/70263/"&gt;https://review.openstack.org/#/c/70263/&lt;/a&gt;.
Once the correct controller is in place the unmap functionality
specified by the Cinder backend will be utilized.&lt;/p&gt;
&lt;p&gt;A secondary volume attachment will be treated separately and will
honor the discard settings provided at connection time.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Primary assignee:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Daniel Wilson&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;Add the “discard”: True line to the Pure Storage driver.&lt;/p&gt;
&lt;p&gt;Implement the funcionality in Nova as well.
&lt;a class="reference external" href="https://review.openstack.org/#/c/205726/1"&gt;https://review.openstack.org/#/c/205726/1&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Tempest tests will not be needed for this spec. Pure Storage CI will test
this code path with existing tempest tests.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Documentation on the response to ‘initialize_connection’ will need to be
updated with notes explaining that this new info is provided.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="https://en.wikipedia.org/wiki/Trim_(computing"&gt;https://en.wikipedia.org/wiki/Trim_(computing&lt;/a&gt;)&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Tue, 11 Aug 2015 00:00:00 </pubDate></item><item><title>Brick fetch volume paths API</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/mitaka/brick-fetch-paths.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/brick-fetch-paths"&gt;https://blueprints.launchpad.net/cinder/+spec/brick-fetch-paths&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The Brick (os-brick) library currently has the knowledge of how
to discover and remove volumes from the scsi subsystem on a host.
Every connector object has the ability to return a list of existing
paths on the system for a given volume, as well as the location
where those volume paths live.   This spec’s purpose is to detail
a formal API for fetching the existing paths for a volume, as well
as the search path, and the list of all existing volumes for a
connector.   The purpose of this is to allow the verification of
volume paths after attachment, as well as verification of a volume
being removed after detachment.   Once we have this API in place,
then it’s possible to automate the verification of attaches and
detaches for complex operations.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Historically in OpenStack, we haven’t had a way of automatically
verifying that the detach process doesn’t leave behind orphaned
volumes.  I define orphaned volumes as volume paths on a system
that were associated with a volume, that has been detached.&lt;/p&gt;
&lt;p&gt;This can cause problems later on when volumes are attached to that
host.  Some SAN arrays reuse iqn’s and or LUN ids for volumes.
This can get a host in the state where a volume on the host conflicts
with an orphaned volume path on the host, leading to corruption with
i/o.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;The primary use case is for fetching the list of existing paths for a volume
on a system after attach and detach.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Add new APIs to each os-brick connector to
1) fetch the existing paths on the system for a given volume.
2) fetch all of the volume paths for a connector.&lt;/p&gt;
&lt;p&gt;Flask based API script.
Add a new flask script that exposes these API calls that can be run
in a test environment.  This flask script is needed in order to
automatically verify the success of detach during nova live migration
which happens on multiple compute hosts.   This flask script is only
intended on being used during jenkins tests and gate checking.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Someone can write individual verification scripts, outside of os-brick,
for each type of volume (connector), but won’t benefit from future fixes
in connectors.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;os-brick already returns a single path entry after connect_volume calls.
What os-brick doesn’t do today is return a list of all volume paths
associated with a connector.&lt;/p&gt;
&lt;p&gt;It’s noted here that the flask script as described in the proposed change,
should not be run/used on a production/live system.  This is intended for
check/gate testing only.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Connector developers will be required to implement the new APIs for their
connector, even if they are stubs.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;walter-boring&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;anthony-mic-lee&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;I have a Work In Progress patch already up in gerrit for the API work.
We need to add a follow up patch that creates the flask script for remotely
calling the methods for the connector.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Standard unit tests.
I have also done manual testing with it.  Eventually, we would like to add
verification in check/gate testing for volume attaches as well.
For each connector object we should have 3rd party CI to test the new APIs
as well.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;The code is documented.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;The existing patch in gerrit
* &lt;a class="reference external" href="https://review.openstack.org/#/c/199764/"&gt;https://review.openstack.org/#/c/199764/&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Tue, 21 Jul 2015 00:00:00 </pubDate></item><item><title>Ability to update volume type public status</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/liberty/volume-types-public-update.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/volume-types-public-update"&gt;https://blueprints.launchpad.net/cinder/+spec/volume-types-public-update&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This proposal is to add the ability to update volume type is_public status.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently, the v2 volume type update api doesn’t support updating volume type’s
public status. All volume types created are public by default if not specified,
It is not possible to update a existing volume_type is_public status.
It is necessary to add updating public status for volume type. If a volume
type updated from public to private, the volumes created with this type will
not be affected, but the user without access will not be able to create volume
with this type anymore.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;Suppose the admin created a volume type. And he/she wants to make the volume
type not public and add access to specified projects.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Modify volume_type update API adding is_public property support.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;Volume type update change&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Update volume type API
* V2/&amp;lt;tenant id&amp;gt;/types/volume_type_id
* Method: PUT
* JSON schema definition for V2:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"volume_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"test_type"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Test volume type"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"is_public"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"False"&lt;/span&gt; &lt;span class="c1"&gt;# new&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;In the existing update volume type API, add a new parameter “is_public” to
allow updating public status for volume type.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;python-cinderclient needs to be changed to support the modified API.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Update volume type
cinder type-update –name &amp;lt;name&amp;gt; –description &amp;lt;description&amp;gt;
–is-public &amp;lt;is-public&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;liyingjun&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Other contributors:&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;API change:
* Modify Update Volume Type API.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;New unit tests will be added to test the changed code.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Documentation changes are needed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;/section&gt;
</description><pubDate>Mon, 20 Jul 2015 00:00:00 </pubDate></item><item><title>Cinder API WSGI application under Apache/Nginx</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/liberty/non-eventlet-wsgi-app.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/non-eventlet-wsgi-app"&gt;https://blueprints.launchpad.net/cinder/+spec/non-eventlet-wsgi-app&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Cinder API uses eventelt as a webserver and WSGI application managing. Eventlet
provides own WSGI application to provide web server functionality.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Cinder API is deployed in other way as a common web application. Apache/Nginx
is generally used web servers for REST API application.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cinder API is runned as a separate service. It means that cloud operator need
to configure some software to monitor that Cinder API is running.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Apache/Nginx works better under the real heavy load then eventlet.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Deploy Cinder API with Apache/Nginx like an any other web applicaction.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;Deploy Cinder API with Apache/Nginx to have load balancing and web applicaion&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;monitoring out of the box. E.g. Nginx/uWSGI can restart backend service if
it stopped by any case.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Provide WSGI application based on used web-framework instead of eventlet. Leave
eventlet-based WSGI application as a default option and make it configurable.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Leave as is and use eventlet for REST API web serving. Use something like
haproxy for API requests load balancing and some watchdog to restart Cinder API
service after shutdown.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Potential performance impact could be present if we will have a lot of requests
to Cinder API. Performance impact will be tested with Rally.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;Deployers should configure Apache/Nginx/etc and WSGI module to handle requests
to Cinder API. By default, Cinder API will use eventlet and no deployer impact
will be.&lt;/p&gt;
&lt;p&gt;No new configuration options for Cinder will be introduced.&lt;/p&gt;
&lt;p&gt;New deployment mode should be supported by Chef cookbooks and Puppet manifests.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Ivan Kolodyazhny &amp;lt;e0ne&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Anton Arefiev &amp;lt;aarefiev&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Implement WSGI application based on webob framework.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Test performance impact with Rally.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Write documentation how to run Cinder API with Apache/Nginx.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement configuration option in Devstack to support new deployment mode.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make sure usage of eventlet doesn’t break WSGI in Nginx/Apache.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Start cross-project initiative to implement this in oslo.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Functional tests for new deployment mode will be implemented. We need to test
this feature on every commit on infra with CI.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Administrators Guide will be updated.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/154642/"&gt;https://review.openstack.org/#/c/154642/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/164035/"&gt;https://review.openstack.org/#/c/164035/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/196088/"&gt;https://review.openstack.org/#/c/196088/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://lists.openstack.org/pipermail/openstack-dev/2015-February/057359.html"&gt;http://lists.openstack.org/pipermail/openstack-dev/2015-February/057359.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Wed, 17 Jun 2015 00:00:00 </pubDate></item><item><title>Volume state enforcer</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/liberty/create-states.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/cinder-state-enforcer"&gt;https://blueprints.launchpad.net/cinder/+spec/cinder-state-enforcer&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Concurrent resource access in cinder is a problem that has caused resource
corruption when simultaneous resources are mutated on by multiple cinder
entrypoints (api and manager for example). In Icehouse there has been some
addition &amp;amp; usage of locks around manager functions to queue up those requests
when a resource is being simultaneous worked on by multiple
functions (this stops one of those operations from concurrently mutating the
underlying resource). Sadly this is more of a &lt;em&gt;sledgehammer&lt;/em&gt; approach and
hides the symptoms of the problem and makes it non-obvious when debugging what
other requests are queued up behind the lock (or why dead-locking is
occurring, if and when it does).&lt;/p&gt;
&lt;p&gt;To help alleviate and hopefully solve this problem we will try to attack some
of these issues in a different manner, integrating a &lt;em&gt;allowed&lt;/em&gt; state transition
table into the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;create_volume&lt;/span&gt;&lt;/code&gt; workflow and doing &lt;em&gt;strategic&lt;/em&gt; state
transitions and aborting/erroring out when these state transitions are not
allowed. In the future this will help create a concrete set of well defined
states and transitions for other workflows as well (and will make it clear
while looking at code and during debugging which transitions are allowed at the
same time and what transitions are actively occurring).&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;A high-level description of the problem:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Concurrent resource mutation, bad (EOM).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;More detailed description:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Locks in cinder are being added to protect against simultaneous resource
modification, for example in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;create_volume,&lt;/span&gt; &lt;span class="pre"&gt;attach_volume,&lt;/span&gt;&lt;/code&gt;
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;delete_volume,&lt;/span&gt; &lt;span class="pre"&gt;detach_volume...&lt;/span&gt;&lt;/code&gt; a external lock is acquired in the
manager with name &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volume_id,&lt;/span&gt; &lt;span class="pre"&gt;f.__name__&lt;/span&gt;&lt;/code&gt;. This has helped make the
manager more safe to concurrent resource access but the initial goal of this
was for it to only be a temporary solution to a wider problem. One of the
issues with this mechanism is that it is not using a &lt;a class="reference external" href="http://en.wikipedia.org/wiki/Distributed_lock_manager"&gt;DLM&lt;/a&gt; (distributed
lock manager) but only a local filesystem lock instead. This means that a
cinder-api service can mutate the resource (or initiate a request to do
this) while a second mutation is actively in flight. When a single manager is
active this will work out (since one of the in flight requests will backup
behind the external lock). This solves the problem when a
single &lt;em&gt;master&lt;/em&gt; manager is running; yet this is an atypical deployment
pattern and should not be recommended as the way to deploy and run
cinder (it should be horizontally scalable so that there can be X
active managers, where X is &amp;gt; 1). We need some other type of solution that
scales horizontally but also solves the same end goal (disallowing
simultaneous resource mutation by X entities at the same time).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Since the scope of this problem is bigger (it applies to all/most operations
that act on resources) we have to start somewhere so we will start by working
through how this will look for the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;create_volume&lt;/span&gt;&lt;/code&gt; workflow. It does raise a
larger question of how can this change be done in a &lt;em&gt;piecemeal&lt;/em&gt; fashion since
the other operations will still be lock dependent, and mixing state transitions
and lock acquisition techniques will likely not end in a correct solution. We
will have to explore how to do this in a way that is &lt;em&gt;piecemeal&lt;/em&gt; but also does
not destabilize cinder more.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Instead of acquiring local filesystem locks in the manager processes refactor
the concept of a lock to instead be a set of allowed and disallowed state
transitions (which is in concept similar to the internal mechanism that a
lock uses anyway).&lt;/p&gt;
&lt;p&gt;Lets take an abbreviated example of how this could work:&lt;/p&gt;
&lt;p&gt;When a volume is requested to be created, a database record is created for
this volume, in this database record there exists a field called
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;status&lt;/span&gt;&lt;/code&gt; (in fact there exists multiple of these statuses fields, in the
future these should maybe be removed?) that is used to report back to the user
data about the status of the create volume request as it moves through the
various components in cinder (api, scheduler, and manager).&lt;/p&gt;
&lt;p&gt;This status itself has a expected transition diagram and itself is a starting
point in determining the larger states transitions that a cinder volume create
request goes through (and is allowed to go through). Instead of overriding
this &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;status&lt;/span&gt;&lt;/code&gt; field this proposal proposes to augment the data storage layer
in cinder with a new &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;resource_states&lt;/span&gt;&lt;/code&gt; table. It may be represented by
something other than a table depending on where this data is stored (if
&lt;a class="reference external" href="http://zookeeper.apache.org/"&gt;zookeeper&lt;/a&gt; was used it would be represented as a resource tree), the only
constraint that we &lt;em&gt;must&lt;/em&gt; enforce is that we can atomically fetch and update
the given state of a resource in a single atomic operation.&lt;/p&gt;
&lt;p&gt;A potential schema could look like the following:&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;&lt;strong&gt;Resource&lt;/strong&gt;&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;&lt;strong&gt;State&lt;/strong&gt;&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;&lt;strong&gt;Transitioned on&lt;/strong&gt;&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;7c92ee46-7a2e-4183-99c5-909f3d46a90e
7c92ee46-7a2e-4183-99c5-909f3d46a90e
7c92ee46-7a2e-4183-99c5-909f3d46a90e
7c92ee46-7a2e-4183-99c5-909f3d46a90e&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CREATING_DB
SCHEDULING
CREATING_VOL
NULL/None&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;2014-05-22T15
2014-05-23T15
2014-05-23T15
2014-05-24T15&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;This table structure will then be used (with &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;NULL&lt;/span&gt;&lt;/code&gt; states to delimit when
a request has fulfilled its set of allowed state transitions) to determine at
the API level (before a request has been accepted) what a resource is currently
being used for and the API server can then attempt to initiate a transition to
a desired state (for example, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DETACHING&lt;/span&gt;&lt;/code&gt;) and depending on if this
transition is allowed (by looking at the last known state) it may fail or
succeed at performing this transition. If it succeeds it continues with the
rest of the workflow for the desired operation (subsequent transitions will
also be made in the rest of the workflow, as needed, with the final transition
being a transition to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;NULL/None&lt;/span&gt;&lt;/code&gt;, to denote that the operation has
completed). If the transition is disallowed/fails the API request will be
denied and the operation will not be allowed to make forward progress (in the
future this model can be relaxed to allow for simultaneous state transitions
for operations where this makes sense).&lt;/p&gt;
&lt;p&gt;To accomplish this, in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;create_volume&lt;/span&gt;&lt;/code&gt; operation there exists the usage
of taskflow, which has helped decompose the workflows that volume creation
goes through (it also makes it possible to resume from a prior state if the
process crashes). This decomposition makes it obvious (or more obvious) where
the transitions should occur and what the transitions are. The proposed path
is to add in new nodes into the workflow that will perform &amp;amp; validate
these state transitions (attempting to mutate the above resource state table)
at a granular-enough level to be useful &amp;amp; meaningful (the transition table also
can be useful for operators and developers attempting to determine what is
happening inside cinder). When this is combined with notifications from
taskflow about its own internal &lt;a class="reference external" href="http://docs.openstack.org/developer/taskflow/states.html"&gt;states&lt;/a&gt; (via &lt;a class="reference external" href="http://docs.openstack.org/developer/taskflow/notifications.html"&gt;notifications&lt;/a&gt;) the ability to
decipher what is going on internally to cinder becomes very easy &amp;amp; provides
invaluable information to users, developers and operators using &amp;amp; operating
cinder.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;One possibility for avoiding the above &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;resource_states&lt;/span&gt;&lt;/code&gt; table is to use
a &lt;a class="reference external" href="http://en.wikipedia.org/wiki/Distributed_lock_manager"&gt;DLM&lt;/a&gt; and use a similar approach that is being used with file locks in
cinder. The usage of it would be similar to the usage of file locks, although
there are scenarios at RPC boundaries where it would still require state
transition validation. For example when a lock is released and an async RPC
call is made there becomes the possibility for other async RPC calls to also
be active at the same time and there would require a state transition and
lock system to be used when the receivers of those RPC calls accept and perform
the requested RPC operation.&lt;/p&gt;
&lt;p&gt;Another possible solution that does not require state transitions is to not use
async RPC calls but instead use sync RPC calls, and the sender would only
release the &lt;a class="reference external" href="http://en.wikipedia.org/wiki/Distributed_lock_manager"&gt;DLM&lt;/a&gt; lock it owns after it has received confirmation that the
receiver has started to process (or accepted the request). The receiver would
then acquire the lock during this period when it accepts the request, ensuring
that correct lock hand-off happens between the send and receiver. This would
require a sensitive and hard to get correct lock hand-off code
path &amp;amp; process (this path would need to be tested heavily to ensure
correctness).&lt;/p&gt;
&lt;p&gt;IMHO both of these alternative methods are too fragile and do not make the
state transition process and diagram obvious to developers, operators, and
users. This lack of information impedes cinder adoption, and makes it more
difficult to recovery from (and understand) inevitable failures and
operational issues.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="what-this-does-not-solve"&gt;
&lt;h3&gt;What this does not solve&lt;/h3&gt;
&lt;p&gt;I would also like include a note to what the scope of this specification does
&lt;strong&gt;not&lt;/strong&gt; encompass.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;It does &lt;strong&gt;not&lt;/strong&gt; encompass cross-project resource usage and
inconsistencies related to state transitions being done by a project using
cinder (for example the initiation of a detach of a volume by nova will not
be aborted early in the nova API flow, but instead will be aborted later in
the workflow if cinder is performing other state transitions on that
resource).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It also does &lt;strong&gt;not&lt;/strong&gt; also stop cinder from deleting a volume underneath
nova (aka a VM can be using a volume while cinder is deleting it).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These are larger cross-project consistency issues and will need to be solved
at a higher level across the projects. It should be noted that once a project
itself has a consistent set of states and transitions it becomes &lt;em&gt;much&lt;/em&gt; easier
to make cross-project consistency possible (without &lt;strong&gt;internal&lt;/strong&gt; consistency
cross-project resource usage might as well be discouraged/avoided).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;See the above proposed table.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="cross-project-impact"&gt;
&lt;h3&gt;Cross-project impact&lt;/h3&gt;
&lt;p&gt;We &lt;strong&gt;must&lt;/strong&gt; be careful to retain the existing API so that nova which is
dependent on cinders currently visible states continues to work. This just
means that we need to have a exposed mapping that nova is compatible with;
while we have an internal mapping which is much more detailed and consistent.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;Maybe in the future.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None currently, the state transition information could also be sent out to
the notification system if this is desirable in the future to do so.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;End users should now expect more errors (or try again later) responses when
performing operations concurrently on the same set of resources. Previously
some of these operations may or may not have succeeded.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;A new table will be created in &lt;a class="reference external" href="http://www.sqlalchemy.org/"&gt;sqlalchemy&lt;/a&gt; and a new model will be created
for this new schema. This table will be high read and write traffic (since all
operations that occur in cinder will write data to it) so it might be
recommended to alter the table type to a more friendly format that performs
better for this tables limited usage. Since this table is relatively simple it
should also be possible in the future (when correctness is achieved) to
switch this table to some other backend that can optimize itself for small
read/writes with little history (history is not as useful, except for operators
and developers who wish to interrogate what has happened to a
resource in the past).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Developers would likely get a lot of the benefit of this information to start
since it will help them understand the states a workflow goes through (at
the cinder level), combining this with the event stream that taskflow emits
creates a lot of useful runtime information that can be used while running
cinder or while developing cinder (where to add new state transitions in
becomes more obvious when the state transitions that occur are well defined
and understood).&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Primary assignee:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Harlowja&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Other contributors:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;DuncanT&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Others?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You the person reading this?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Determine state digram and debate what states should be used internally to
cinder (the &lt;strong&gt;critical&lt;/strong&gt; must-have states) and what states are more
&lt;strong&gt;informational&lt;/strong&gt; (DuncanT has apparently done some of this analysis).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create database schema migration/addition for the decided upon new schema.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create database models for new schema (and determine and discuss on how the
atomic state update will be accomplished).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Identify key locations where these state transitions will occur (before or
after which taskflow tasks) or at a layer outside of taskflow.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add new tests that trigger these new state transitions and violation checks,
ensuring that what is desired to occur actually occurs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Simultaneously work on creating a model inside of taskflow that can help
other projects avoid recreating chunks of the above code for there own
similar needs/use-cases.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Test like &lt;em&gt;crazy&lt;/em&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Do load-testing/concurrency-testing (using rally or tempest) to verify the
improvement has helped and not hurt cinder.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="milestones"&gt;
&lt;h3&gt;Milestones&lt;/h3&gt;
&lt;p&gt;J/3 into K (this is likely not a short-term specification).&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Since this change affects how cinder operates at a low level, it will require
a good amount of testing to verify that concurrent operations are disallowed.
Currently tempest may not be the best way to test these concurrent operations
since to my knowledge it does not run in parallel (and only when it runs in
a controlled parallel process can u find these concurrency issues). So the
way to test these concurrency issues needs to be determined (is &lt;a class="reference external" href="https://wiki.openstack.org/wiki/Rally"&gt;rally&lt;/a&gt; the
way to go here, using its concurrent scenarios to probe that this
feature works?).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;There may be new documentation required to explain why operations that were
allowed to occur concurrently are no longer allowed to occur concurrently since
this new state transition will be more strict as to what can and what can not
occur at the same time.&lt;/p&gt;
&lt;p&gt;It will also become possible to start to form documents like taskflow
&lt;a class="reference external" href="http://docs.openstack.org/developer/taskflow/states.html"&gt;states&lt;/a&gt; that show exactly what the internals of cinder are doing
and what the allowed state transitions (aka the cinder reference operation
states) are.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Summit discussion/session:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://etherpad.openstack.org/p/juno-cinder-state-and-workflow-management"&gt;https://etherpad.openstack.org/p/juno-cinder-state-and-workflow-management&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Tue, 14 Apr 2015 00:00:00 </pubDate></item><item><title>Valid States API</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/liberty/valid-states-api.html</link><description>

&lt;p&gt;Include the URL of your launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/valid-states-api"&gt;https://blueprints.launchpad.net/cinder/+spec/valid-states-api&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Provide an API to obtain the set of valid states that are permissible to be
used in the function to reset the state of a volume and snapshot.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;The purpose of this feature is to facilite exposing the reset-state API in
horizon in a meaningful way by restricting the set of permissible states that
the administrator can specify for a volume.  There is no API for this, and it
is undesirable to hardcode this information into horizon.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;A new API function and corresponding cinder command will be added to determine
the set of valid states for volumes or snapshots.&lt;/p&gt;
&lt;p&gt;The initial proposal is to create a single function, get_valid_states, to
obtain the valid states for any type of resource (volume, snapshot).&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;For consistency with the rest of cinder, get_valid_states may be renamed and/or
split into multiple functions, one per resource type; this decision will be
left as an implementation detail and will be finalized as part of the normal
code review process.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Add a new REST API to retrieve valid states:&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;GET /v2/{tenant_id}/states&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;JSON response schema definition:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="s1"&gt;'valid_states'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'array'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'items'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'string'&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;A new command, get-valid-states, will be added to python-cinderclient.  This
command mirrors the underlying API function.&lt;/p&gt;
&lt;p&gt;Obtaining the list of valid states for a volume or snapshot can be performed
by:
$ cinder get-valid-states&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;thingee&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Implement REST API&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement cinder client functions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement cinder command&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;Horizon blueprints that will depend on this one:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/horizon/+spec/cinder-reset-volume-state"&gt;https://blueprints.launchpad.net/horizon/+spec/cinder-reset-volume-state&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/horizon/+spec/cinder-reset-snapshot-state"&gt;https://blueprints.launchpad.net/horizon/+spec/cinder-reset-snapshot-state&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;The cinder client documentation will need to be updated to reflect the new
command.&lt;/p&gt;
&lt;p&gt;The cinder API documentation will need to be updated to reflect the REST API
changes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Tue, 14 Apr 2015 00:00:00 </pubDate></item><item><title>Add vHost Executor</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/liberty/vhost-support.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/vhost-support"&gt;https://blueprints.launchpad.net/cinder/+spec/vhost-support&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The vHost driver was added in the 3.6 Linux kernel. The Linux-IO Target vHost
fabric module implements I/O processing based on the Linux virtio mechanism. It
provides virtually bare-metal local storage performance for KVM guests.
Currently Linux guest VMs are supported.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;The vHost driver is not a self-contained virtio device, as it depends on
userspace to handle the control plane while the data plane is done in kernel.
This means the data plane does not go through emulations, which can slow down
I/O performance. Cinder today does not provide an option for taking advantage
of the Linux vHost driver.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Add an additional brick executor that knows how to work with vHost.  The
executor will have a first pass implementation of creating, deleting, listing
vHost endpoints through LIO.&lt;/p&gt;
&lt;p&gt;Creating the endpoint requires a block device to be available on the machine
that is creating the vHost target. The vHost executor would pass the block
device path to to rtstools, and rtstools will create vHost endpoint with a lun
to the block device.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;n/a&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;n/a&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;n/a&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;n/a&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;n/a&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;n/a&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Cinder itself being the control plane will not experience any different
performance. The data plane should experience a greater deal of performance
[1].&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;n/a&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;n/a&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;thingee&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add vHost executor to brick&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;n/a&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;There will be appropriate unit tests available making sure target creation,
deletion, listing works.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;n/a&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;[1] - &lt;a class="reference external" href="http://linux-iscsi.org/wiki/VHost#Linux_performance"&gt;http://linux-iscsi.org/wiki/VHost#Linux_performance&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Tue, 14 Apr 2015 00:00:00 </pubDate></item><item><title>Configurable SSH Host Key Policies for Cinder</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/juno/configurable-ssh-host-key-policy.html</link><description>

&lt;p&gt;Include the URL of your launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/configurable-ssh-host-key-policy"&gt;https://blueprints.launchpad.net/cinder/+spec/configurable-ssh-host-key-policy&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;To address concerns of weak ssh security in Cinder, the way that
ssh host keys are handled by Cinder should be configurable, allowing
system administrators to choose how secure they wish their SSH connections
to be.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;During Icehouse testing and development it was discovered that
SSHPool in cinder/utils.py was using the paramiko.AutoAddPolicy()
option.  This meant that changes to the SSH key on the storage back-end
would just be accepted with only a warning being printed.  This leaves
a security weakness as it is possible for a Man-In-the-Middle (MITM)
attack to happen between the Cinder Volume host and the back-end storage.
If a MITM attack were to happen, the users data could be compromised.
In a worst case scenario, users could be tricked into attaching or even
booting spoofed volumes containing malicious code.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;The spec and associated blueprint propose making the way that SSH
host keys are handled configurable, allowing system administrators
to make a conscious decision about the level of security they need
on their system.&lt;/p&gt;
&lt;p&gt;The solution would require two new configuration items as well as
a change to the current default behavior.  First, there would need
to a ‘strict_ssh_host_key_policy’ configuration option with possible
settings of ‘false’ (default) or ‘true’.  When this option is set to
‘false’ it will automatically accept the host key on the first connection
and then will throw an exception if the host key changes in the future.
This is where the default behavior changes from the current functionality.&lt;/p&gt;
&lt;p&gt;In the case that ‘strict_ssh_host_key_policy’ is set to ‘true’ then a
second option ‘ssh_host_keys_file’ must be configured.  When the strict
configuration is used it is assumed that the administrator is going to
have pre-configured ssh host keys and any deviation from those expected
keys will be handled with an exception.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Obviously, we could keep the current functionality but this leaves
a security weakness.  We could also just require that an ssh host key
file be specified, but I feel this is undesirable as it is yet another
configuration option that users must deal with.  The last option would
be to make the functionality fully configurable, making it possible to
keep the current functionality, where changes in the host key only cause
a warning to be reported, in addition to the new configuration options
listed above, but I don’t feel leaving the security weakness in place
is the right approach if we are making this change.  We are actually
bringing Cinder’s handling of ssh keys in line with what users are
used to from the command line, which seems like the most sensible
approach.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;This change improves security by handling ssh keys in a manner that
will help to avoid the possibility of Man-in-the-Middle attacks.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;As mentioned above, this change will make it so that, by default, the
user will see a failure connecting to their back-end storage system
in the case the ssh keys on that system change.  The user will have
the ability to set the level of security they wish to enforce on their
volume server using the ‘strict_ssh_host_key_policy’ and also be able
to specify the host keys they wish to use with the ‘ssh_host_keys_file’
option.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;Deployers that wish to have a more secure ssh implementation will need to
set the ‘strict_ssh_host_key_policy’ and ‘ssh_host_keys_file’
configuration options.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Drivers that currently use ssh to connect to their back-end storage
systems will need to ensure that their drivers are using this approach
for securing their ssh keys.  Future driver developers will also need
to be consistent with this improved security model.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;jsbryant (&lt;a class="reference external" href="mailto:jsbrant%40us.ibm.com"&gt;jsbrant&lt;span&gt;@&lt;/span&gt;us&lt;span&gt;.&lt;/span&gt;ibm&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt; or jungleboyj on IRC)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;Initial changes to cinder/utils.py to enable this new functionality.
Update existing drivers to properly utilize the functionality.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Beyond unit tests, I don’t know that there is much more testing that can be
done unless there is a way, in Tempest, to simulate bad ssh keys being
returned.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Documentation will need to be updated for the configuration options and
explanation of how the functionality is designed to work.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;Original bug which started this discussion:  &lt;a class="reference external" href="https://bugs.launchpad.net/cinder/+bug/1320056"&gt;https://bugs.launchpad.net/cinder/+bug/1320056&lt;/a&gt;
Initial fix for utils.py in the community: &lt;a class="reference external" href="https://review.openstack.org/#/c/94165/"&gt;https://review.openstack.org/#/c/94165/&lt;/a&gt;
Weekly Cinder Meeting discussion on this topic:  &lt;a class="reference external" href="http://eavesdrop.openstack.org/meetings/cinder/2014/cinder.2014-05-28-16.00.log.html#l-104"&gt;http://eavesdrop.openstack.org/meetings/cinder/2014/cinder.2014-05-28-16.00.log.html#l-104&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 22 Jan 2015 00:00:00 </pubDate></item><item><title>Consistency Groups</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/juno/consistency-groups.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/consistency-groups"&gt;https://blueprints.launchpad.net/cinder/+spec/consistency-groups&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Today in Cinder, every operation happens at the volume level. Consistency
Groups (CGs) are needed for Data Protection (snapshots and backups) and
Disaster Recovery (remote replication). This blueprint will be introducing
Consistency Groups and discussing how it can be applied to snapshots.&lt;/p&gt;
&lt;p&gt;Remote replication is covered in a different blueprint and will not be
discussed here.
&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/volume-replication"&gt;https://blueprints.launchpad.net/cinder/+spec/volume-replication&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Consistency Group support will be added for snapshots in phase 1 (Juno).&lt;/p&gt;
&lt;p&gt;Future:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;After the Consistency Group is introduced and implemented for snapshots,
it may be applied to backups. That will be after phase 1.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify Consistency Group (adding existing volumes to CG and removing volumes
from CG after it is created) will be supported after phase 1.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Assumptions:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Cinder provides APIs that can be consumed by an orchestration layer.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The orchestration layer has knowledge of what volumes should be grouped
together.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Volumes in a CG belong to the same backend.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Volumes in a CG can have different volume types.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;3 levels of quiesce:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Application level: Not in Cinder’s control&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Filesystem level: Cinder can call newly proposed Nova admin quiesce API
which uses QEMU guest agent to freeze the guest filesystem before taking a
snapshot of CG and thaw afterwards. However, this freeze feature in QEMU
guest agent was just added to libvirt recently, so we can’t rely on it yet.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Storage level: Arrays can freeze IO before taking a snapshot of CG.  We can
only rely on the storage level quiesce in phase 1 because the freeze feature
mentioned above is not ready yet.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Consistency Groups work flow&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create a CG, specifying volume types that can be supported by this CG.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Scheduler will figure out which backend can handle these volume types.
The backend (host) will be saved in the CG table in the db.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a volume and specify the CG.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;This step will be repeated until all volumes are created for the CG.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a snapshot of the CG.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Cinder API creates cgsnapshot and individual snapshot entries in the db
and sends request to Cinder volume node.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cinder manager calls novaclient which calls a new Nova admin API “quiesce”
that uses QEMU guest agent to freeze the guest filesystem. Can leverage
this work:
&lt;a class="reference external" href="https://wiki.openstack.org/wiki/Cinder/QuiescedSnapshotWithQemuGuestAgent"&gt;https://wiki.openstack.org/wiki/Cinder/QuiescedSnapshotWithQemuGuestAgent&lt;/a&gt;
(Note: This step will be on hold for now because the freeze feature is not
reliable yet.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cinder manager calls Cinder driver.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cinder driver communicates with backend array to create a point-in-time
consistency snapshot of the CG.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cinder manager calls novaclient which calls a new Nova admin API
“unquiesce” that uses QEMU guest agent to thaw the guest filesystem.
(Note: This step will be on hold for now.)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;One alternative is to not implement CG in Cinder, but rather implementing it
at the orchestration layer.  However, in that case, Cinder wouldn’t know which
volumes are belonging to a CG.  As a result, user can delete a volume belonging
to the CG using Cinder CLI or Horizon without knowing the consequences.&lt;/p&gt;
&lt;p&gt;Another alternative is not to implement CG at all.  User will be able to
operate at individual volume level, but can’t provide crash consistent data
protection of multiple volumes in the same application.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;DB Schema Changes&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;A new consistencygroups table will be created.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A new cgsnapshots table will be created.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Volume entries in volumes tables will have a foreign key of the
consistencygroup uuid that they belong to.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;cgsnapshot entries in cgsnapshots table will have a foreign key of the
consistencygroup uuid.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;snapshot entries in snapshots table will have a foreign key of the
cgsnapshot uuid.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;mysql&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;desc&lt;/span&gt; &lt;span class="n"&gt;cgsnapshots&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;+---------------------+--------------+------+-----+---------+-------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Field&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Type&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Null&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Key&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Default&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Extra&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+---------------------+--------------+------+-----+---------+-------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;created_at&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;YES&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;updated_at&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;YES&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;deleted_at&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;YES&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;deleted&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;tinyint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;YES&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;varchar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NO&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;PRI&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;consistencygroup_id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;varchar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;YES&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;varchar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;YES&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;project_id&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;varchar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;YES&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;varchar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;YES&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;varchar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;YES&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;varchar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;YES&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+---------------------+--------------+------+-----+---------+-------+&lt;/span&gt;
&lt;span class="mi"&gt;11&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.00&lt;/span&gt; &lt;span class="n"&gt;sec&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;mysql&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;desc&lt;/span&gt; &lt;span class="n"&gt;consistencygroups&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;+-------------------+--------------+------+-----+---------+-------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Field&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Type&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Null&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Key&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Default&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Extra&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+-------------------+--------------+------+-----+---------+-------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;created_at&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;YES&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;updated_at&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;YES&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;deleted_at&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;YES&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;deleted&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;tinyint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;YES&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;varchar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NO&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;PRI&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;varchar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;YES&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;project_id&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;varchar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;YES&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;host&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;varchar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;YES&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;availability_zone&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;varchar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;YES&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;varchar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;YES&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;varchar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;YES&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;varchar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;YES&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+-------------------+--------------+------+-----+---------+-------+&lt;/span&gt;
&lt;span class="mi"&gt;12&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.00&lt;/span&gt; &lt;span class="n"&gt;sec&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Alternatives:&lt;/p&gt;
&lt;p&gt;Instead of adding a cgsnapshots table, add a label to the snapshots.
This label will be the cgsnapshot name. That means we need to make sure
the name is provided when creating a snapshot of the CG and it must be unique.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;Consistency Groups&lt;/p&gt;
&lt;p&gt;Add V2 API extensions consistencygroups&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Create consistency group API&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Create a consistency group.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Method type: POST&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Normal Response Code: 202&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Expected error http response code(s): TBD
* 404: type group not found&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;V2/&amp;lt;tenant id&amp;gt;/consistencygroups&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;JSON schema definition for V2:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"consistencygroup"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"my_cg"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"My consistency group"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"volume_types"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;type1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;type2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s2"&gt;"availability_zone"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"zone1:host1"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete consistency group API&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Delete a consistency group.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Method type: DELETE&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Normal Response Code: 202&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Expected error http response code(s):
* 404: consistency group not found
* 403: consistency group in use&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;V2/&amp;lt;tenant id&amp;gt;/consistencygroups/&amp;lt;cg uuid&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This API has no body.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;List consistency group API&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;This API lists summary information for all consistency groups.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Method type: GET&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Normal Response Code: 200&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Expected error http response code(s): TBD&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;V2/&amp;lt;tenant id&amp;gt;/consistencygroups&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This API has no body.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;List consistency groups (detailed) API&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;This API lists detailed information for all consistency groups.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Method type: GET&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Normal Response Code: 200&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Expected error http response code(s): TBD&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;V2/&amp;lt;tenant id&amp;gt;/consistencygroups/detail&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This API has no body.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Show consistency group API&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;This API shows information about a specified consistency group.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Method type: GET&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Normal Response Code: 200&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Expected error http response code(s)
* 404: consistency group not found&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;V2/&amp;lt;tenant id&amp;gt;/consistencygroups/&amp;lt;cg uuid&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This API has no body.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify consistency group API (adding existing volumes to or removing
volumes from the CG) will be addressed after phase 1.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create volume API will have “consistencygroup_id” added:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"volume"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="o"&gt;........&lt;/span&gt;
        &lt;span class="o"&gt;........&lt;/span&gt;
        &lt;span class="s2"&gt;"consistencygroup_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"consistency group uuid"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="o"&gt;........&lt;/span&gt;
        &lt;span class="o"&gt;........&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Snapshots&lt;/p&gt;
&lt;p&gt;Add V2 API extensions for snapshots of consistency group&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Create snapshot API&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Create a consistency group.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Method type: POST&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Normal Response Code: 202&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Expected error http response code(s): TBD
* 404: snapshot not found&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;V2/&amp;lt;tenant id&amp;gt;/consistencygroups/&amp;lt;cg uuid&amp;gt;/snapshots&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;JSON schema definition for V2:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"snapshot"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"my_cg_snapshot"&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Snapshot of my consistency group"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete snapshot API&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Delete a snapshot of a consistency group.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Method type: DELETE&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Normal Response Code: 202&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Expected error http response code(s)
* 404: snapshot not found&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;V2/&amp;lt;tenant id&amp;gt;/consistencygroups/&amp;lt;cg uuid&amp;gt;/snapshots/&amp;lt;snapshot id&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;JSON schema definition for V2: None&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Should not be able to delete individual volume snapshot if part of a
consistency group.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;List snapshots API&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;This API lists summary information for all snapshots of a
consistency group.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Method type: GET&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Normal Response Code: 200&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Expected error http response code(s): TBD&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;V2/&amp;lt;tenant id&amp;gt;/consistencygroups/&amp;lt;cg uuid&amp;gt;/snapshots&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This API has no body.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;List consistency groups (detailed) API&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;This API lists detailed information for all snapshots of a
consistency group.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Method type: GET&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Normal Response Code: 200&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Expected error http response code(s): TBD&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;V2/&amp;lt;tenant id&amp;gt;/consistencygroups/&amp;lt;cg uuid&amp;gt;/snapshots/detail&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This API has no body.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Show snapshot API&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;This API shows information about a specified snapshot of a
consistency group.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Method type: GET&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Normal Response Code: 200&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Expected error http response code(s)
* 404: snapshot of the consistency group not found&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;V2/&amp;lt;tenant id&amp;gt;/consistencygroups/&amp;lt;cg uuid&amp;gt;/snapshots/&amp;lt;snapshot id&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This API has no body.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Driver API additions&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;def create_consistencygroup(self, context, consistencygroup, volumes)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;def delete_consistencygroup(self, context, consistencygroup)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;def create_cgsnapshot(self, context, cgsnapshot)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;def delete_cgsnapshot(self, context, cgsnapshot)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;Add event notifications.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;Add a quota for maximum number of CGs per tenant.&lt;/p&gt;
&lt;p&gt;python-cinderclient needs to be changed to support CG.  The following CLI
will be added.&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;To list all consistency groups:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;cinder consistencygroup-list&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;To create a consistency group:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;cinder consistencygroup-create –name &amp;lt;name&amp;gt; –description &amp;lt;description&amp;gt;
–volume_type &amp;lt;type1,type2,…&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Example:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;cinder consistencygroup-create –name mycg –description “My CG”
–volume_type lvm-1,lvm-2&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;To create a new volume and add it to the consistency group:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;cinder create –volume_type &amp;lt;type&amp;gt; –consistencygroup &amp;lt;cg uuid or name&amp;gt; &amp;lt;size&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;To delete one or more consistency groups:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;cinder consistencygroup-delete &amp;lt;cg uuid or name&amp;gt; [&amp;lt;cg uuid or name&amp;gt; …]&lt;/p&gt;
&lt;p&gt;cinder consistencygroup-show &amp;lt;cg uuid or name&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;python-cinderclient needs to be changed to support snapshots.&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;To list snapshots of a consistency group:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;cinder consistencygroup-snapshot-list &amp;lt;cg uuid or name&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;To create a snapshot of a consistency group:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;cinder consistencygroup-snapshot-create &amp;lt;cg uuid or name&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;To show a snapshot of a consistency group:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;cinder consistencygroup-snapshot-show &amp;lt;cgsnapshot uuid or name&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;To delete one or more snapshots:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;cinder consistencygroup-snapshot-delete &amp;lt;cgsnapshot uuid or name&amp;gt;
[&amp;lt;cgsnapshot uuid or name&amp;gt; …]&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;This will add CG support to Cinder.  Other drivers can implement the proposed
driver APIs to support this feature.  This is not required.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;xing-yang (&lt;a class="reference external" href="mailto:xing.yang%40emc.com"&gt;xing&lt;span&gt;.&lt;/span&gt;yang&lt;span&gt;@&lt;/span&gt;emc&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;)&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;None&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add Cinder APIs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make db schema changes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Driver API changes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement driver changes for LVM.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tempest tests.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;In order to test this feature, tests need to be added to Tempest to support
all new APIs.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Need to document the new APIs.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Juno design session:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://etherpad.openstack.org/p/juno-cinder-cinder-consistency-groups"&gt;https://etherpad.openstack.org/p/juno-cinder-cinder-consistency-groups&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 22 Jan 2015 00:00:00 </pubDate></item><item><title>Remove Translation from Debug Messages</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/juno/debug-translation-removal.html</link><description>

&lt;p&gt;Include the URL of your launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/debug-translation-removal"&gt;https://blueprints.launchpad.net/cinder/+spec/debug-translation-removal&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Including translation of debug messages for OpenStack creates more
work for the translators than can be contained.  It has been decided
to reduce the workload for translators and to ensure that the most
important log messages are translated properly, we remove
translation of debug messages.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;We have currently been doing Cinder development under the assumption
that all messages should be translated.  As described above, it has
been decided that this is not the case.  In order to bring Cinder in
line with other OpenStack components we need to remove translation
from debug level log messages.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;The change proposed is simply to remove _() from around any debug
level log messages.  While the change is simple, the changes touch
many, if not all, files in Cinder which requires careful coordination
of the implementation of the change.&lt;/p&gt;
&lt;p&gt;The proposed implementation of this change is to have volume driver
owners take responsibility to implement changes in each of the
directories, (cinder/volume/drivers/&lt;em&gt;) to start with, as individual
commits.  We will then work backwards and split up making changes
across the remaining top level directories (cinder/&lt;/em&gt;).  Each TLD will
be handled as its own commit.&lt;/p&gt;
&lt;p&gt;Note that this spec and associated blueprint are not to address the
integration of _LI(), _LW(), _LE() and _LC() functions.  That work is
being addressed by the following spec/blueprint:
&lt;a class="reference external" href="https://review.openstack.org/#/c/99853/"&gt;https://review.openstack.org/#/c/99853/&lt;/a&gt;&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;We could not go back and remove  from existing log messages.  This,
however, seems like a poor decision given that we would not be consistent
with other OpenStack projects and it would be confusing and ugly as we
go forward given that some debug messages would have  around them while
others would not.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;End users will no longer be able to see debug output in locale’s
aside from English.  This, however, was deemed necessary to allow
the translation team to be able to focus on translation of other
log levels.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;Deployers who previously have seen debug messages translated will
need to be aware that this change has been implemented.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Developers should no longer translate debug level messages.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;jsbryant (&lt;a class="reference external" href="mailto:jsbryant%40us.ibm.com"&gt;jsbryant&lt;span&gt;@&lt;/span&gt;us&lt;span&gt;.&lt;/span&gt;ibm&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt; and jungleboyj on IRC)&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;There will be numerous other contributors to this Blueprint
as it is anticipated that the work will be split across
multiple members of the Cinder development team.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;Remove _() from all debug messages in Cinder.
Add a HACKING check to ensure that new cases of this are not added.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit test for this change is not required.  A HACKING check, however,
should be added to test for developers attempting to translate debug
messages in the future.  The check should make sure that any LOG.debug
messages do not have a _() around the text contained in the message.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;The fact that debug messages shouldn’t be translated is already
documented here:  &lt;a class="reference external" href="https://wiki.openstack.org/wiki/LoggingStandards"&gt;https://wiki.openstack.org/wiki/LoggingStandards&lt;/a&gt;
Further documentation should be required.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Logging Standards documentation:
&lt;a class="reference external" href="https://wiki.openstack.org/wiki/LoggingStandards"&gt;https://wiki.openstack.org/wiki/LoggingStandards&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This issue was discussed in the 6/11/14 Weekly Cinder Meeting:
&lt;a class="reference external" href="http://eavesdrop.openstack.org/meetings/cinder/2014/cinder.2014-06-11-16.03.log.html"&gt;http://eavesdrop.openstack.org/meetings/cinder/2014/cinder.2014-06-11-16.03.log.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Thu, 22 Jan 2015 00:00:00 </pubDate></item><item><title>Deprecate Cinder V1 API</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/juno/deprecate_v1_api.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/deprecate-v1-api"&gt;https://blueprints.launchpad.net/cinder/+spec/deprecate-v1-api&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The Cinder V1 API should be deprecated as v2 has been developed back in
Grizzly and stable. Newer features are being developed to v2, that v1 will
never have.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;The v2 API switch involves some changes from clients to make things more
consistent like &lt;cite&gt;display_name&lt;/cite&gt; becoming &lt;cite&gt;name&lt;/cite&gt; and &lt;cite&gt;display_description&lt;/cite&gt; and
&lt;cite&gt;description&lt;/cite&gt;. This is done on both volume and snapshot controllers. It is
assumed there are many clients out there still supporting v1, as well as many
deployed clouds still using v1 that would need to make some changes to ease the
switch.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Leave v1 enabled for Juno, give a warning for enabling it though in Cinder API
service startup. Both /v1 and /v2 can work at the same time which can allow
time to switch clients over in the user’s pace. In K, turn off v1.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;n/a&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;n/a&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;/v1 will continue to work as normal and serve incoming requests.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;n/a&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;n/a&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;/v1 will continue to work as normal and serve incoming requests. If the end
user hits &amp;lt;ip&amp;gt;:8776/ they will see v2 listed as current and v1 listed as
deprecated.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;n/a&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;The deployer will have to make sure they have enable_v1_api=true in their
cinder.conf. In versions older than Juno, enable_v1_api was default to true,
but Juno will have this option set to false by default.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;n/a&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&amp;lt;thingee&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Have devstack set enable_v1_api=true in lib/cinder.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add changes to grenade to set enable_v1_api=true.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add v2 support to Nova when using Cinder client, but to also support v1 if
still enabled.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add deprecation warnings to Cinder API for enabling v1 API, and set
enable_v1_api to default to false.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update documentation API ref/spec pages. Update the ops guide where
appropriate.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Devstack support for Cinder v2: &lt;a class="reference external" href="https://review.openstack.org/#/c/22489/"&gt;https://review.openstack.org/#/c/22489/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Nova support for Cinder for v2: &lt;a class="reference external" href="https://review.openstack.org/#/c/43986/"&gt;https://review.openstack.org/#/c/43986/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Devstack defaulting to enable_v1_api=true:
&lt;a class="reference external" href="https://review.openstack.org/#/c/102568"&gt;https://review.openstack.org/#/c/102568&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make sure greneade tests still pass.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit tests for v1 will still exist. Tempest will still do v1 tests in Juno.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;V1 Cinder documentation will mention it’s deprecated where it’s appropriate.
Instructions for upgrade and keeping v1 enabled can also be provided. This
includes the reference, spec, and ops docs.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;n/a&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 22 Jan 2015 00:00:00 </pubDate></item><item><title>EMC VMAX Driver Update</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/juno/emc-vmax-driver-juno-update.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/emc-vmax-driver-juno-update"&gt;https://blueprints.launchpad.net/cinder/+spec/emc-vmax-driver-juno-update&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This driver is an enhancement of the EMC SMI-S driver for VMAX. In Juno,
the support for VNX will be removed from the SMI-S driver. Moving forward,
this driver will support VMAX only. Some new features will be added for
VMAX.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;The existing EMC SMI-S iSCSI and FC driver has some missing features
for VMAX.  In previous release, support for Extend Volume and Create
Volume from Snapshot were only implemented for VNX. In Juno, these
features will be added for VMAX.&lt;/p&gt;
&lt;p&gt;In previous release, masking view, storage group, and initiator group
need to be created ahead of time. In Juno, this will be automated.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;The following features will be added to the SMI-S based driver to support
VMAX:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Extend volume&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create volume from snapshot&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Dynamically creating masking views, storage groups, and initiator groups&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Striped volumes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FAST policies&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;User will be able to use the new features.  The feature that dynamically
creates masking views, storage groups, and initiator groups will greatly
improve user experience.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;xing-yang&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;None&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Extend volume&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create volume from snapshot&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create masking views, storage groups, and initiator groups dynamically&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Striped volumes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FAST policies&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;New features need to be tested.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Need to document the changes in the block storage manual.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 22 Jan 2015 00:00:00 </pubDate></item><item><title>EMC VNX Direct Driver Update</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/juno/emc-vnx-direct-driver-juno-update.html</link><description>

&lt;p&gt;Include the URL of your launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/emc-vnx-direct-driver-juno-update"&gt;https://blueprints.launchpad.net/cinder/+spec/emc-vnx-direct-driver-juno-update&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Add more functionalities into EMC VNX Direct Driver.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;The following new functionalities will be added in this update:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;FC Support&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FC Auto Zoning Support&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Read-only Volume Support&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;External Volume Management Suppport&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;Advance LUN Features&lt;/dt&gt;&lt;dd&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Compression Support&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Deduplication Support&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FAST VP Support&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FAST Cache Support&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Initiator Auto Registration&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Storage Group Auto Deletion&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;iSCSI Target Portal Selection&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Multiple Authentication Type Support&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Security File Support&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Storage-Assisted Retype&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Storage-Assisted Volume Migration&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;SP Toggle for HA&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;FC Support&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Add a new driver class.&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;FC Auto Zoning Support&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Add logic in intialize_connection() and terminate_connection() according
to blueprint
&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/cinder-fc-zone-manager"&gt;https://blueprints.launchpad.net/cinder/+spec/cinder-fc-zone-manager&lt;/a&gt; and
the fix for bug &lt;a class="reference external" href="https://bugs.launchpad.net/cinder/+bug/1308318"&gt;https://bugs.launchpad.net/cinder/+bug/1308318&lt;/a&gt;.&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Read-only Volume Support&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Add logic in intialize_connection() according to blueprint
&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/read-only-volumes"&gt;https://blueprints.launchpad.net/cinder/+spec/read-only-volumes&lt;/a&gt;.&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;External Volume Management Suppport&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Implement driver API according to blueprint
&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/add-export-import-volumes"&gt;https://blueprints.launchpad.net/cinder/+spec/add-export-import-volumes&lt;/a&gt;.&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Advance LUN Features&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Add logic to support more extra spec key-value pairs&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Initiator Auto Registration&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Do logic in intialize_connection() to do EMC-specific initiator
registration.&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Storage Group Auto Deletion&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Add resource recycling logic in intialize_connection()&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;iSCSI Target Portal Selection&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Add logic in intialize_connection() to select target portal that is
pingable from the initiator.&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Multiple Authentication Type Support&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Add new option in configuration file so that the driver can use different
authentication types that have been supported by VNX arrays.&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Security File Support&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Add a new option in configuration file so that encrypted credentials can
be used instead of credentials in plain text.&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Storage-Assisted Retype&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Implement driver API according to blueprint
&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/volume-retype"&gt;https://blueprints.launchpad.net/cinder/+spec/volume-retype&lt;/a&gt;.&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Storage-Assisted Volume Migration&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Implement migrate_volume() so that VNX native LUN Migration is leveraged.&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;SP Toggle for HA&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Original implementation only send management requests to one SP. Since VNX
arrays have dual SPs, the driver is enhanced to send requests to the other
SP is one is down.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;jeegn-chen&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;None&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Implement driver changes&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;NaviSecCLI (a.k.a. Navisphere CLI)&lt;/dt&gt;&lt;dd&gt;&lt;ul&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;For Ubuntu x64, DEB is available in&lt;/dt&gt;&lt;dd&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;EMC OpenStack Github: &lt;a class="reference external" href="https://github.com/emc-openstack/naviseccli"&gt;https://github.com/emc-openstack/naviseccli&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;For all other variants of Linux, Navisphere CLI is available at&lt;/dt&gt;&lt;dd&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Downloads for VNX2 Series:
&lt;a class="reference external" href="https://support.emc.com/downloads/36656_VNX2-Series"&gt;https://support.emc.com/downloads/36656_VNX2-Series&lt;/a&gt; or&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Downloads for VNX1 Series:
&lt;a class="reference external" href="https://support.emc.com/downloads/12781_VNX1-Series"&gt;https://support.emc.com/downloads/12781_VNX1-Series&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Tempest test will used to qualify the driver update.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Need to update EMC VNX Direct Driver section of OpenStack Configuration
Reference.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 22 Jan 2015 00:00:00 </pubDate></item><item><title>Windows SMB Volume Driver</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/juno/hyper-v-smbfs-volume-driver.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/hyper-v-smbfs-volume-driver"&gt;https://blueprints.launchpad.net/cinder/+spec/hyper-v-smbfs-volume-driver&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Currently, there are Cinder volume drivers which make use of network-attached
storage file systems such as GlusterFS of NFS. The purpose of this blueprint
is adding a volume driver supporting SMB based volume backends.&lt;/p&gt;
&lt;p&gt;This driver will support Windows Server 2012 (R2 included).&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;SMB is a widely used protocol, especially in the Microsoft world. Its
simplicity along with the big improvements that were introduced in SMB 3
make this type of volume backend a very good alternative.&lt;/p&gt;
&lt;p&gt;SMB 3 brings features such as transparent failover, multichanneling using
multiple NICs, encrypted communication, and RDMA.&lt;/p&gt;
&lt;p&gt;This driver will be backwards compatible, supporting older versions of SMB.
It will support using any type of SMB share, including:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;from Scale-Out file servers to basic Windows shares;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Linux Samba shares;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;vendor specific hardware exporting SMB shares.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;This driver will include all the features required by the Juno release. It
will have a similar flow with other netowrk attached file system drivers,
managing images regarded as volumes while hosted on SMB shares.&lt;/p&gt;
&lt;p&gt;It will include support for vhd and vhdx images, which will be hosted on
SMB shares. The driver will support password based authentication for
mounting the SMB shares.&lt;/p&gt;
&lt;p&gt;The snapshot management will be done in a similar way as the Gluster driver,
using an additional “.info” file containing mappings between snapshot ids and
their actual paths. This is required as the path can change in time (for
example when deleting a snapshot from the chain, the backing file will be
changed). Differencing vhd/vhdx images will be used as backing files.&lt;/p&gt;
&lt;p&gt;This driver will be based on the SMB volume driver which will be available
for Linux distributions.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;The driver will periodically ensure that the chosen shares are mounted and also
retrieve informations such as free space or total allocated space.&lt;/p&gt;
&lt;p&gt;Certain volume related operations will require to be synchronized.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;The user will provide a list of SMB shares on which volumes may reside. This
list will be placed in a file located at a path configured in the cinder config
file.  This share list may contain SMB mount options such as flags or
credentials.&lt;/p&gt;
&lt;p&gt;The config file will also contain the path to the Samba config file. Oversubmit
and used space ratios may also be configured.&lt;/p&gt;
&lt;p&gt;The user will be able to choose whether to use vhd or vhdx images. The volume
type may be parsed as extra spec when creating a volume.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&amp;lt;&lt;a class="reference external" href="mailto:lpetrut%40cloudbasesolutions.com"&gt;lpetrut&lt;span&gt;@&lt;/span&gt;cloudbasesolutions&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;Provide volume related operations support using images hosted on SMB shares.&lt;/p&gt;
&lt;p&gt;Override the Linux SMB volume driver methods that are platform specific.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Libvirt smbfs volume driver blueprint:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/nova/+spec/libvirt-smbfs-volume-support"&gt;https://blueprints.launchpad.net/nova/+spec/libvirt-smbfs-volume-support&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Hyper-V smbfs volume driver blueprint:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/nova/+spec/hyper-v-smbfs-volume-support"&gt;https://blueprints.launchpad.net/nova/+spec/hyper-v-smbfs-volume-support&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Linux smbfs volume driver blueprint:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/smbfs-volume-driver"&gt;https://blueprints.launchpad.net/cinder/+spec/smbfs-volume-driver&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;A Cinder CI will be testing the SMB related features.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Using the SMB backend will be documented.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 22 Jan 2015 00:00:00 </pubDate></item><item><title>i18n Enablement for Cinder</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/juno/i18n-enablement.html</link><description>

&lt;p&gt;Include the URL of your launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/i18n-enablement"&gt;https://blueprints.launchpad.net/cinder/+spec/i18n-enablement&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This BluePrint/Spec proposes completing the enablement of i18n
(internationalization) support for Cinder.&lt;/p&gt;
&lt;p&gt;Internationalization implementation has been an on-going effort in OpenStack
during recent releases.  During the Icehouse release, much of the support
for internationalization was already merged into Cinder.  Specifically
the update of Oslo’s gettextutils (commit
1553a1e78ec262b044ce99b418103c91b7b580f6) completed much of
the process.  Removal of the use of str() in exceptions and messages
was the other major piece of work that was implemented: (commit
cbe1d5f5e22e5f792128643e4cdd6afb2ff2b5bf).&lt;/p&gt;
&lt;p&gt;To finalize this work in Juno we need to enable “lazy” translation.
Enablement of lazy translation will allow end users to not only have
logs produced in multiple languages, but adds the ability for REST
API messages to also be returned in the language chosen by the user.
This functionality is important to support the use of OpenStack by the
international community.&lt;/p&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently, Cinder does not have the all the code in place to support
lazy translation.  The code associated with this blueprint will add
the appropriate code and enable translation of REST API responses.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;The code for this change will add ‘gettextutils.enable_lazy() to each of
the binaries in bin.&lt;/p&gt;
&lt;p&gt;It will also remove the use of gettextutils.install() in each of the
binary files.  Instead it will add the explicit import of _() in all
files that are not already importing the _() function.  The need for
the change to explicitly import _() is documented
in bug &lt;a class="reference external" href="https://bugs.launchpad.net/cinder/+bug/1306275"&gt;https://bugs.launchpad.net/cinder/+bug/1306275&lt;/a&gt; .&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;There is no additional changes to the REST API other than the fact
that the change enables the customer to specify the language they
wish REST API responses to be returned in using the Accept-Language
option.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;Once merged this feature is immediately available to users.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;The developer impacts have already been in place for some time.  Developers
have been using _() around messages that need translation.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&amp;lt;&lt;a class="reference external" href="mailto:jsbryant%40us.ibm.com"&gt;jsbryant&lt;span&gt;@&lt;/span&gt;us&lt;span&gt;.&lt;/span&gt;ibm&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt; (Jungleboyj)&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&amp;lt;&lt;a class="reference external" href="mailto:jecarey%40us.ibm.com"&gt;jecarey&lt;span&gt;@&lt;/span&gt;us&lt;span&gt;.&lt;/span&gt;ibm&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;I am planning to implement this as two patches.  The first will be the
patch to ensure that _() is being explicitly imported.  The dependent
patch will then set enable_lazy().&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;There will be a tempest test added for Cinder that will ensure that
lazy translation is working properly.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 22 Jan 2015 00:00:00 </pubDate></item><item><title>Limit Bandwidth of Volume Copy</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/juno/limit-volume-copy-bandwidth.html</link><description>

&lt;p&gt;Include the URL of your launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/limit-volume-copy-bandwidth"&gt;https://blueprints.launchpad.net/cinder/+spec/limit-volume-copy-bandwidth&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This proposes adding a new config to limit bandwidth for volume copy to
mitigate interference to other instance performance during:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;new volume creation from a image&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;backup&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;volume deletion (when dd if=/dev/zero etc. is chosen to wipe)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently, volume copy operations consumes disk I/O bandwidth heavily and may
slow down the other guest instances.&lt;/p&gt;
&lt;p&gt;“ionice” option is already implemented in some cases, but it is not always
usable. e.g. When instances directly access to the storage and doesn’t go
through I/O scheduler of cinder control node, ionice cannot control I/O
priority and instances access may slow down.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;A new config named ‘volume_copy_bps_limit’ will be added to determine max
bandwidth (byte per second) consumed by volume copy.&lt;/p&gt;
&lt;p&gt;When CONF.volume_copy_bps_limit is zero (default), no limitation is applied,
and no cgroup is created.&lt;/p&gt;
&lt;p&gt;Otherwise, bandwidth limitation is applied to volume copy. For example, if the
volume copy is done by ‘dd’ command, it can be implemented by putting ‘dd’
into blkio cgroup for throttling.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;When volume copy commands have an option for I/O throttling, the usage of such
options are preferable.
Putting whole cinder-volume processes into blkio cgroups could also be a
solution for this, though it is required to provide a way to set rate limit to
newly added block devices when new volume is created.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;When volume copy I/O bandwidth is limited, it takes more time to complete
volume copy. Users are required to balance between volume copy performance
and interference to instances performance.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;This feature is disabled by default. Users who want to use this feature need
to set ‘volume_copy_bps_limit’ in cinder.conf.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;tomoki-sekiyama-g&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Implement cgroup blkio setup functions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement I/O rate limit for volume_utils.copy_volume&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement I/O rate limit for other image format such as qcow&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;The cinder client documentation will need to be updated to reflect the new
config.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 22 Jan 2015 00:00:00 </pubDate></item><item><title>Pool-aware Scheduler Support</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/juno/pool-aware-cinder-scheduler.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/pool-aware-cinder-scheduler"&gt;https://blueprints.launchpad.net/cinder/+spec/pool-aware-cinder-scheduler&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Cinder currently see each volume backend as a whole, even if the backend
is consists of several smaller pools with totally different capabilities
and capacities.  Such gap can cause strange issue - a backend appears
to have enough capacity to create a copy of a volume but the backend fails
to do so.  Extending Cinder to support storage pools within volume backend
will not only solve issues like that, it can also make Cinder scheduling
decision smarter as it now knows full set of capabilities of a backend.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Cinder has been designed to take look each volume backend as a whole since
day 1. The provisioning decisions are based on the statistics reported by
backends. Any backend is assumed to be a single discrete unit with a set
of capabilities and single capacity.  In reality this assumption is not
true for many storage providers and as their storage can be further divided
or partitioned into pools to offer completely different set of capabilities
and capacities. That is there are storage backends are a combination of
storage pools rather than one big single homogenous entity. Usually
volumes/snapshots cannot be placed across pools on such backends. As a result,
there are obvious problems when using them with current Cinder:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;A volume/snapshot that is larger than any sub-pool of the target backend
be schedule the backend would fail;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A sub pool may not have enough space to serve consecutive request (e.g.
volume clones, snapshots) while the entire backend appears to have
sufficient capacity;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;These issues are very confusing and result in inconsistent user experience.
Therefore it is important to extend Cinder so that it is aware of storage
pools within backend and also use them as finest granularity for resource
placement.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;We would like to introduces pool-aware scheduler to address the need for
supporting multiple pools from one storage controller.&lt;/p&gt;
&lt;section id="terminology"&gt;
&lt;h3&gt;Terminology&lt;/h3&gt;
&lt;p&gt;Pool - A logical concept to describe a set of storage resource that
can be used to serve core Cinder requests, e.g. volumes/snapshots.
This notion is almost identical to Cinder Volume Backend, for it
has simliar attributes (capacity, capability).  The main difference
is Pool couldnot exist on its own, it must reside in a Volume
Backend.  One Volume Backend can have mulitple Pools but Pools
do not have sub-Pools (meaning even they have, sub-Pools do not get
to exposed to Cinder, yet).  Pool has a uniqueue name in backend
namespace, which means Volume Backend cannot have two pools using
same name.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="design"&gt;
&lt;h3&gt;Design&lt;/h3&gt;
&lt;p&gt;The workflow in this change is simple:
1) Volume Backends reports how many pools and what those pools
look like and are capable of to scheduler;
2) When request comes in, scheduler picks a pool that fits the need
most to serve the request, it passes the request to the backend
where the target pool resides in;
3) Volume driver gets the message and let the target pool to serve
the request as scheduler instructed.&lt;/p&gt;
&lt;p&gt;To support placing resources (volume/snapshot) onto a pool, these
changes will be made to specific components of Cinder:
1. Volume Backends reporting capacity/capabilities at pool level;
2. Scheduler filtering/weighing based on pool capacity/capability
and placing volumes/snapshots to a pool of certain backend;
3. Record which pool a resource is located on a backend and passes
between scheduler and volume backend.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Rather than changing scheduler, Navneet Singh has proposed an alterntive
change to make changes to Volume Manger/Driver code.  In his approach,
each sub-pool of a backend will be exposed as a service entity (e.g.
a greenthread inside of a python process), which listens to its own
RPC channel, reports its own stats to scheduler.&lt;/p&gt;
&lt;p&gt;Related bp for this alternative:
&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/multiple-service-pools"&gt;https://blueprints.launchpad.net/cinder/+spec/multiple-service-pools&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;No DB schema change involved, however, the host field of Volumes table
will now include pool information but no DB migration is needed.&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Original host field of Volumes:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="mailto:HostX%40BackendY"&gt;HostX&lt;span&gt;@&lt;/span&gt;BackendY&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;With this change:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="mailto:HostX%40Backend"&gt;HostX&lt;span&gt;@&lt;/span&gt;Backend&lt;/a&gt;:pool0&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;Host attribute of volumes now includes pool information in it, consumer
of notification can now extend to extract pool information if needed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;No impact visible to end user.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;The size of RPC message for each volume stats report will be bigger than
before (linear to # of pools a backend has).  It should not really impact
the RPC facility in terms of performance and even if it did, pure text
compression should easily mitigate this problem.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;No special requirement for deployer to deploy new version of Cinder as
it is mostly transparent changes even to deployer.  The only visible change
is the additional pool info encoded into host attribute of volume records.&lt;/p&gt;
&lt;p&gt;Scheduler is better to be updated/deployed &lt;em&gt;piror&lt;/em&gt; volume services, but this
order is not mandatory.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;For those volume backends would like expose internal pools to Cinder for more
flexibility, developer should update their drivers to include all sub-pool
capacities and capabilities in the volume stats it reports to scheduler.
Below is an example of new stats message:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'volume_backend_name'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'Local iSCSI'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;#\&lt;/span&gt;
    &lt;span class="s1"&gt;'vendor_name'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'OpenStack'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;           &lt;span class="c1"&gt;#  backend level&lt;/span&gt;
    &lt;span class="s1"&gt;'driver_version'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'1.0'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;              &lt;span class="c1"&gt;#  mandatory/fixed&lt;/span&gt;
    &lt;span class="s1"&gt;'storage_protocol'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'iSCSI'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;          &lt;span class="c1"&gt;#- stats&amp;amp;capabilities&lt;/span&gt;

    &lt;span class="s1"&gt;'active_volumes'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;                 &lt;span class="c1"&gt;#\&lt;/span&gt;
    &lt;span class="s1"&gt;'IOPS_provisioned'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;30000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;            &lt;span class="c1"&gt;#  optional custom&lt;/span&gt;
    &lt;span class="s1"&gt;'fancy_capability_1'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'eat'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;          &lt;span class="c1"&gt;#  stats &amp;amp; capabilities&lt;/span&gt;
    &lt;span class="s1"&gt;'fancy_capability_2'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'drink'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;        &lt;span class="c1"&gt;#/&lt;/span&gt;

    &lt;span class="s1"&gt;'pools'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'pool_name'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'1st pool'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;         &lt;span class="c1"&gt;#\&lt;/span&gt;
         &lt;span class="s1"&gt;'total_capacity_gb'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;        &lt;span class="c1"&gt;#  mandatory stats for&lt;/span&gt;
         &lt;span class="s1"&gt;'free_capacity_gb'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;230&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;         &lt;span class="c1"&gt;#  pools&lt;/span&gt;
         &lt;span class="s1"&gt;'allocated_capacity_gb'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;270&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;    &lt;span class="c1"&gt;# |&lt;/span&gt;
         &lt;span class="s1"&gt;'QoS_support'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'False'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;          &lt;span class="c1"&gt;# |&lt;/span&gt;
         &lt;span class="s1"&gt;'reserved_percentage'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;        &lt;span class="c1"&gt;#/&lt;/span&gt;

         &lt;span class="s1"&gt;'dying_disks'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;              &lt;span class="c1"&gt;#\&lt;/span&gt;
         &lt;span class="s1"&gt;'super_hero_1'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'spider-man'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;    &lt;span class="c1"&gt;#  optional custom&lt;/span&gt;
         &lt;span class="s1"&gt;'super_hero_2'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'flash'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;         &lt;span class="c1"&gt;#  stats &amp;amp; capabilities&lt;/span&gt;
         &lt;span class="s1"&gt;'super_hero_3'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'neoncat'&lt;/span&gt;        &lt;span class="c1"&gt;#/&lt;/span&gt;
         &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'pool_name'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'2nd pool'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s1"&gt;'total_capacity_gb'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s1"&gt;'free_capacity_gb'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s1"&gt;'allocated_capacity_gb'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s1"&gt;'QoS_support'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'False'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s1"&gt;'reserved_percentage'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

         &lt;span class="s1"&gt;'dying_disks'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s1"&gt;'super_hero_1'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'superman'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s1"&gt;'super_hero_2'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s1"&gt;'super_hero_2'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'Hulk'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;zhiteng-huang (winston-d)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;There are two parts of changes needed for this proposal: changes to Cinder
itself (scheduler, volume manager) and changes to Cinder drivers for those
backends which would like to expose pools to scheduler.&lt;/p&gt;
&lt;p&gt;But even without Cinder drivers changes, it will work fine as usual without
problem since first part of change has taken compatibility in to account.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;A complete set of testing environment will need following scenarios:&lt;/p&gt;
&lt;p&gt;1) Cinder uses backend does not support pool (only exposes single pool for
entire backend);
2) Cinder uses backend supports pools (with updated driver);
3) Cinder uses mixed backends;&lt;/p&gt;
&lt;p&gt;Create a few volumes/snapshots on the backends prior upgrades, this is for
compatibility tests.&lt;/p&gt;
&lt;p&gt;For each scenario, tests should be done in 3 steps:&lt;/p&gt;
&lt;p&gt;1) Update cinder-scheduler (or cinder-volume), test create volume clones,
snapshots of existing volumes or delete existing volumes;
2) Test create new volumes;
3) Update the rest part of Cinder (if cinder-scheduler is updated in step 1,
update cinder-volume now, or vise versa), test create volume, create clones,
snapshots of existing volumes or delete existing volumes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;No documentation impact for changes in Cinder itself.  But drivers changes
may introduce new configure options which leads to DocImpact.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;/section&gt;
</description><pubDate>Thu, 22 Jan 2015 00:00:00 </pubDate></item><item><title>Cinder volume driver for Pure Storage FlashArray</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/juno/pure-iscsi-volume-driver.html</link><description>

&lt;p&gt;Include the URL of your launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/pure-iscsi-volume-driver"&gt;https://blueprints.launchpad.net/cinder/+spec/pure-iscsi-volume-driver&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The purpose of this spec is to add a Cinder volume driver for Pure Storage
FlashArray. It will support the iSCSI protocol and will include at least the
minimum set of features required by the Juno release. We will also set up
automated CI testing on an OpenStack cluster maintained by Pure Storage in
accordance with the third party CI requirement policy.&lt;/p&gt;
&lt;p&gt;Pure Storage builds all-flash storage arrays. The active/active controller
architecture is based on the Purity Operating Environment and providing an
adaptive metadata fabric that is scalable, granular to 512B, and protected.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently, the Pure Storage FlashArray cannot be used a block storage backend
in an OpenStack environment.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Add a Pure Storage FlashArray Cinder driver to the OpenStack Cinder package.&lt;/p&gt;
&lt;p&gt;The Pure Storage driver will leverage a thin Python REST client library.
The client library interacts with the REST service hosted on the FlashArray
to perform array management and satisfy Cinder driver API requirements.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Control&lt;/span&gt; &lt;span class="n"&gt;Flow&lt;/span&gt;

                   &lt;span class="o"&gt;+------------------+&lt;/span&gt;
                   &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="n"&gt;Cinder&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;
                   &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="n"&gt;Cinder&lt;/span&gt; &lt;span class="n"&gt;Volume&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;
                   &lt;span class="o"&gt;+--------+---------+&lt;/span&gt;
                            &lt;span class="o"&gt;|&lt;/span&gt;
                            &lt;span class="n"&gt;v&lt;/span&gt;
                   &lt;span class="o"&gt;+------------------+&lt;/span&gt;
                   &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="n"&gt;Pure&lt;/span&gt; &lt;span class="n"&gt;Driver&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;
                   &lt;span class="o"&gt;|&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt;
                   &lt;span class="o"&gt;+--------+---------+&lt;/span&gt;
                            &lt;span class="o"&gt;|&lt;/span&gt;
                            &lt;span class="n"&gt;v&lt;/span&gt;
                   &lt;span class="o"&gt;+------------------+&lt;/span&gt;
                   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Pure&lt;/span&gt; &lt;span class="n"&gt;REST&lt;/span&gt; &lt;span class="n"&gt;Client&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
                   &lt;span class="o"&gt;|&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt;
                   &lt;span class="o"&gt;+--------+---------+&lt;/span&gt;
                            &lt;span class="o"&gt;|&lt;/span&gt;
                            &lt;span class="n"&gt;v&lt;/span&gt;
                   &lt;span class="o"&gt;+------------------+&lt;/span&gt;
                   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Pure&lt;/span&gt; &lt;span class="n"&gt;REST&lt;/span&gt; &lt;span class="n"&gt;Server&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
                   &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FlashArray&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;
                   &lt;span class="o"&gt;+------------------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The Cinder driver will make use of REST client APIs to support:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Volume Create/Delete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Volume Attach/Detach&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Snapshot Create/Delete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create Volume from Snapshot&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Get Volume Stats&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Copy Image to Volume&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Copy Volume to Image&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Clone Volume&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Extend Volume&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In addition to the delivery of the driver implementation, the proposed change
includes the addition of unit tests for the driver. Pure Storage will create
dedicated Jenkins jobs to support CI and Tempest test execution on a Devstack
virtual machine to continuously prove functionality of the driver.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;The only security related aspect is that an API token is required by the
driver to leverage the REST client and authenticate against the REST API.&lt;/p&gt;
&lt;p&gt;The API token must be specified in the cinder.conf configuration file.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;The impact of this change is that OpenStack Cinder will have support for
using a Pure Storage FlashArray as a backing block storage device.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;The configuration needed to leverage the Pure Storage driver includes:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;volume_driver - Specifies the Pure Storage FlashArray driver module.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;pure_target - The address of the FlashArray storage target.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;pure_api_token - An API token created on the FlashArray to authenticate
REST clients, which the driver will make use of.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And optionally:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;pure_host_name - The name of a host object on the FlashArray to associate
with IQNs and volume connections. This defaults to the name “OpenStack” if
not provided.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;victor-ying &amp;lt;&lt;a class="reference external" href="mailto:victor.ying%40purestorage.com"&gt;victor&lt;span&gt;.&lt;/span&gt;ying&lt;span&gt;@&lt;/span&gt;purestorage&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;wes-w &amp;lt;&lt;a class="reference external" href="mailto:wes%40purestorage.com"&gt;wes&lt;span&gt;@&lt;/span&gt;purestorage&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;
zach-olstein &amp;lt;&lt;a class="reference external" href="mailto:zach.olstein%40purestorage.com"&gt;zach&lt;span&gt;.&lt;/span&gt;olstein&lt;span&gt;@&lt;/span&gt;purestorage&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Complete Cinder Pure Storage driver implementation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Complete Cinder Pure Storage driver unit tests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pass automated Tempest tests to prove functionality.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Integrate Devstack VM and Jenkins job into Pure Storage Jenkins system.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;The driver has a dependency on a REST client library provided by Pure Storage
that allows developers to easily build Python applications built on REST API
functionality.&lt;/p&gt;
&lt;p&gt;The library is currently not available as a pip-installable Python package,
so the library module will be committed along with the driver implementation.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;As mentioned in work items, the delivery of the driver will be accompanied
by a suite of unit tests for the driver (that use Mock to isolate driver
code from the FlashArray). Additionally, continuous integration through
Jenkins and automated Tempest test runs are required for the driver to be
accepted.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Pure Storage should be listed as having a supported Cinder driver on the
CinderSupportMatrix:
&lt;a class="reference external" href="https://wiki.openstack.org/wiki/CinderSupportMatrix"&gt;https://wiki.openstack.org/wiki/CinderSupportMatrix&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 22 Jan 2015 00:00:00 </pubDate></item><item><title>SMB Volume Driver</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/juno/smbfs-volume-driver.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/smbfs-volume-driver"&gt;https://blueprints.launchpad.net/cinder/+spec/smbfs-volume-driver&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Currently, there are Cinder volume drivers which make use of network-attached
storage file systems such as GlusterFS of NFS. The purpose of this blueprint
is adding a volume driver supporting SMB based volume backends.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;SMB is a widely used protocol, especially in the Microsoft world. Its
simplicity along with the big improvements that were introduced in SMB 3
make this type of volume backend a very good alternative.&lt;/p&gt;
&lt;p&gt;SMB 3 brings features such as transparent failover, multichanneling using
multiple NICs, encrypted communication, and RDMA.&lt;/p&gt;
&lt;p&gt;Recent versions of Samba got improved support of the SMB 3 protocol, as well
as Active Directory integration.&lt;/p&gt;
&lt;p&gt;This driver will be backwards compatible, supporting older versions of SMB.
It will support using any type of SMB share, including:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;from Scale-Out file servers to basic Windows shares;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Linux Samba shares;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;vendor specific hardware exporting SMB shares.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;The proposed driver will make use of Samba in order to mount and make use of
SMB shares in a secure way, supporting Active Directory based authentication.&lt;/p&gt;
&lt;p&gt;This driver will include all the features required by the Juno release. It
will have a similar flow with other netowrk attached file system drivers,
managing images regarded as volumes while hosted on SMB shares.&lt;/p&gt;
&lt;p&gt;It will include support for raw, qcow2, vhd and vhdx images. Even so, because
it will use qemu-img for image related operations, it will not support yet
snapshots for vhd and vhdx formats because of qemu-img’s limitations.&lt;/p&gt;
&lt;p&gt;The snapshot management will be done in a similar way as the Gluster driver,
using an additional “.info” file containing mappings between snapshot ids and
their actual paths. This is required as the path can change in time (for
example when deleting a snapshot from the chain, the backing file will be
changed).&lt;/p&gt;
&lt;p&gt;Another driver based on this will be proposed for Windows environments, having
full vhd/vhdx support.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;The driver will periodically ensure that the chosen shares are mounted and also
retrieve informations such as free space or total allocated space.&lt;/p&gt;
&lt;p&gt;Certain volume related operations will require to be synchronized.&lt;/p&gt;
&lt;p&gt;In order to use local shares, the share paths will be read from the Samba
config file.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;The user will provide a list of SMB shares on which volumes may reside. This
list will be placed in a file located at a path configured in the cinder config
file.  This share list may contain SMB mount options such as flags or
credentials.&lt;/p&gt;
&lt;p&gt;The config file will also contain the path to the Samba config file. Oversubmit
and used space ratios may also be configured.&lt;/p&gt;
&lt;p&gt;The user will be able to choose the volume type that will be used as well as
choosing whether to use sparsed or qcow2 files instead of raw files. Depending
on the available qemu-img version, vhd and vhdx formats may also be used.&lt;/p&gt;
&lt;p&gt;The volume type may be parsed as extra spec when creating a volume.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&amp;lt;&lt;a class="reference external" href="mailto:lpetrut%40cloudbasesolutions.com"&gt;lpetrut&lt;span&gt;@&lt;/span&gt;cloudbasesolutions&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&amp;lt;&lt;a class="reference external" href="mailto:gsamfira%40cloudbasesoltions.com"&gt;gsamfira&lt;span&gt;@&lt;/span&gt;cloudbasesoltions&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;Provide support for mounting SMB shares in the remotefs client and also using
local shares.&lt;/p&gt;
&lt;p&gt;Get SMB share status such as free space or allocated space.&lt;/p&gt;
&lt;p&gt;Provide volume related operations support using images hosted on SMB shares.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;Libvirt smbfs volume driver blueprint:
&lt;a class="reference external" href="https://blueprints.launchpad.net/nova/+spec/libvirt-smbfs-volume-support"&gt;https://blueprints.launchpad.net/nova/+spec/libvirt-smbfs-volume-support&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Hyper-V smbfs volume driver blueprint:
&lt;a class="reference external" href="https://blueprints.launchpad.net/nova/+spec/hyper-v-smbfs-volume-support"&gt;https://blueprints.launchpad.net/nova/+spec/hyper-v-smbfs-volume-support&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;A Cinder CI will be testing the SMB related features.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Using the SMB backend will be documented.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;Samba wiki page:
&lt;a class="reference external" href="https://wiki.samba.org/index.php/Main_Page"&gt;https://wiki.samba.org/index.php/Main_Page&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 22 Jan 2015 00:00:00 </pubDate></item><item><title>Support volume backup for qcow2</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/juno/support-volume-backup-for-qcow2.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/support-volume-backup-for-qcow2"&gt;https://blueprints.launchpad.net/cinder/+spec/support-volume-backup-for-qcow2&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Currently, cinder-backup doesn’t support qcow2 format disk. Add the support
for it will make drivers which use qcow2 as volume, such as glusterfs etc,
work together with cinder-backup, and can also make nfs driver use qcow2 as
volume be possible.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently, cinder-backup doesn’t support qcow2 format disk because the backup
code assumes the source volume is a raw volume. The destination (i.e. swift,
rbd) should absolutely remain universal across all volume back-ends.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add qemu-nbd support to cinder-backup. Qemu-nbd can mount qcow2 volume as
a raw device to the host&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The backup_volume method in base class of remotefs driver (cinder.volume.
drivers.nfs.RemoteFsDriver:backup_volume) will mount qcow2 volume as nbd
device before call backup_service’s backup method&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;Storage node which running cinder-volume will contains nbd kernel module.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Trump.Zhang &amp;lt;&lt;a class="reference external" href="mailto:zhangleiqiang%40huawei.com"&gt;zhangleiqiang&lt;span&gt;@&lt;/span&gt;huawei&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add qemu-nbd support to cinder-backup. Qemu-nbd can mount qcow2 volume as
a raw device to the host&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The backup_volume method in base class of remotefs driver (cinder.volume.
drivers.nfs.RemoteFsDriver:backup_volume) will mount qcow2 volume as nbd
device before call backup_service’s backup method&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 22 Jan 2015 00:00:00 </pubDate></item><item><title>Cinder task logging improvements</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/juno/task-log.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/task-logging"&gt;https://blueprints.launchpad.net/cinder/+spec/task-logging&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;To improve the usefulness of the usage of tasks &amp;amp; flows in cinder in the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;create_volume&lt;/span&gt;&lt;/code&gt; workflow (with more workflows to come later) we need to
improve the level of awareness and usage of the interconnect
between &lt;a class="reference external" href="http://docs.openstack.org/developer/taskflow/"&gt;taskflow&lt;/a&gt; and cinder. This will help track a single workflow while
it runs (allowing for introspection into what is occurring or what has
occurred). It will help for operators, for developers and others to have this
information available for usage.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Current taskflow usage does not take advantage of the taskflow &lt;a class="reference external" href="http://docs.openstack.org/developer/taskflow/engines.html"&gt;engine&lt;/a&gt;
internals event/notification mechanism. This makes it hard to determine
what is happening internally to taskflow and how to debug it when things
start to fail (which they inevitably do). It would be better to have this
information exposed in a more easier to use and understandable manner for
future use as well (but we first have to get the basics working in the
first place).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;To start we need to hook into the &lt;a class="reference external" href="http://docs.openstack.org/developer/taskflow/notifications.html"&gt;notification&lt;/a&gt; system that taskflow engines
provide/emit. This will solve the issue of having a useful set of information
being emitted by the taskflow engines used in cinder and will help in
debugging the state-transitions &amp;amp; activity of tasks and flows ran there-in.
This will help solve the issue of debuggability and tracking of the internals
of taskflow; making the lives of operators, developers, and users much easier.&lt;/p&gt;
&lt;p&gt;Part of the proposed change and one that needs more feedback is the location of
this log (is it a log at all?). Using the &lt;a class="reference external" href="http://docs.openstack.org/developer/taskflow/notifications.html#printing-and-logging-listeners"&gt;log listener&lt;/a&gt; that taskflow
provides we can plug in any type of logging compatible object (typically
a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;LOG&lt;/span&gt;&lt;/code&gt; from the python logging module) as the receiver of these events. In
the cinder case this should be a oslo incubator &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;LOG&lt;/span&gt;&lt;/code&gt; object (as is typically
used in cinder and elsewhere in openstack). The question becomes where should
this &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;LOG&lt;/span&gt;&lt;/code&gt; output the task and flow events to.&lt;/p&gt;
&lt;p&gt;The following suggestion seems to be agreed upon:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;A log location for task/flow events, provided by a new configuration
option &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;task_log_file&lt;/span&gt;&lt;/code&gt; (the configuration option name can be changed as
needed, this was just a example and may not be the best name for this usage)
that would be set in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cinder.conf&lt;/span&gt;&lt;/code&gt; that would specify where this data would
be written to. If this location is not set then it will default to the main
cinder log (this will allow the log to be separated out for those that
desire to do this).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;Not currently.&lt;/p&gt;
&lt;p&gt;Some ideas that could be useful in the future:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Provide the same information (or a reduced set of this information) to end
users of the cinder api so that they can gain insight into what is occurring
with there request inside cinder. This would involve saving the same event
stream into something not a log file but some more appropriate structure that
can be given back to the user in a nice format (json or other). This is
similar to providing a &lt;em&gt;task log&lt;/em&gt; back to the user of cinder that other
OpenStack projects are also currently exploring/implementing.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;More log data would mean a rotation mechanism would need to be setup if it was
not setup previously. Since these log files can contain a lot of information
they would need to be rotated at a faster rate than log files that only
contain &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ERROR&lt;/span&gt;&lt;/code&gt; or &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;WARNING&lt;/span&gt;&lt;/code&gt; information.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;An optional configuration setting to enable a new log file location. If a
log file location is added then it would involve a new log file rotation and
associated policy and this is something operators would need to be aware of
and correctly configure to avoid filling up a servers hard drive. The goal is
that this new configuration option would default to the existing main cinder
log (so that this impact would be minimal for most operators).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Primary assignee: harlowja&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create new config options for cinder for event stream target location.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use event stream in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;create_volume&lt;/span&gt;&lt;/code&gt; usage of &lt;a class="reference external" href="http://docs.openstack.org/developer/taskflow/"&gt;taskflow&lt;/a&gt; task/flows and
engines.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;It should be feasible to replace the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;LOG&lt;/span&gt;&lt;/code&gt; or notification mechanism being
used in cinder with taskflow with a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;mock&lt;/span&gt;&lt;/code&gt; object that can also gather the
same event stream and allow it to be used in a test to verify that the event
stream contains the desired events (likely we should be selective in the test
and only verify that certain &lt;em&gt;key&lt;/em&gt; events were emitted, since taskflow could
add new events in the future).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;Summit discussion:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://etherpad.openstack.org/p/juno-cinder-state-and-workflow-management"&gt;https://etherpad.openstack.org/p/juno-cinder-state-and-workflow-management&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Thu, 22 Jan 2015 00:00:00 </pubDate></item><item><title>United Policy.json In Cinder</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/juno/united-policy.json-in-cinder.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/united-policy-in-cinder"&gt;https://blueprints.launchpad.net/cinder/+spec/united-policy-in-cinder&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Currently, there is two policy.json files in cinder. One for cinder code,
one for unit test code. It’s not convenient for the developer and easy to
miss one. This blueprint is aim to united them. Then unit test code will
use the policy.json in the code.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently, there is two policy.json files in cinder. One for cinder code,
one for unit test code. It’s not convenient for the developer and easy to
miss one.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Delete the policy.json under the test&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify the unittest to use the file /etc/cinder/policy.json&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;xiaoding &amp;lt;&lt;a class="reference external" href="mailto:xiaoding1%40huawei.com"&gt;xiaoding1&lt;span&gt;@&lt;/span&gt;huawei&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Delete policy.json in the test&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify the unittest to use /etc/cinder/policy.json&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 22 Jan 2015 00:00:00 </pubDate></item><item><title>Support backup and restore of volumes created by VMDK driver</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/juno/vmdk-backup.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/vmdk-backup"&gt;https://blueprints.launchpad.net/cinder/+spec/vmdk-backup&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The volumes created by the VMDK driver are virtual disks stored in datastores
managed by ESX or vCenter server. Currently, the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;backup-create&lt;/span&gt;&lt;/code&gt; and
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;backup-restore&lt;/span&gt;&lt;/code&gt; operations are not supported for these volumes. This
blueprint proposes adding support for these operations in VMDK driver.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;The default implementation of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;backup-create&lt;/span&gt;&lt;/code&gt;\ &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;backup-restore&lt;/span&gt;&lt;/code&gt; does the
following steps:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Attach the volume as a block device or file.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Backup\restore the file by calling backup service.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Detach the volume.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It uses  an instance of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;InitiatorConnector&lt;/span&gt;&lt;/code&gt; (determined by the back-end
driver protocol) to do the actual\detach. There is no  &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;InitiatorConnector&lt;/span&gt;&lt;/code&gt;
for the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vmdk&lt;/span&gt;&lt;/code&gt; protocol and hence the attach\detach fails for volumes
created by the VMDK driver. This blueprint proposes adding support for
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;backup-create&lt;/span&gt;&lt;/code&gt;\ &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;backup-restore&lt;/span&gt;&lt;/code&gt; for these volumes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;The change involves overriding the default implementations of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;backup_volume&lt;/span&gt;&lt;/code&gt;
and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;restore_backup&lt;/span&gt;&lt;/code&gt; methods in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;VMwareEsxVmdkDriver&lt;/span&gt;&lt;/code&gt;. The steps in
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;backup_volume&lt;/span&gt;&lt;/code&gt; are listed below:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create the backing VM if it not found.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Download the stream-optimized version of the virtual disk corresponding to
the volume to a temporary directory.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Call &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;backup_service.backup()&lt;/span&gt;&lt;/code&gt; method to backup the stream-optimized
virtual disk file.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete the temporary file.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Following are the steps in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;restore_backup&lt;/span&gt;&lt;/code&gt;:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Call &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;backup_service.restore()&lt;/span&gt;&lt;/code&gt; to download the stream-optimized virtual
disk file to a temporary directory.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If the backing VM doesn’t exist (in the case of restoring the backup to
create a new volume), import the stream-optimized virtual disk file to create
a new backing VM.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If the backing VM exists, import the stream-optimized virtual disk file to
create a temporary VM and reconfigure the backing VM to replace its virtual
disk with that of the temporary VM.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete the temporary file and temporary VM.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;HTTP read/write&lt;/strong&gt;: It is possible to create an HTTP connection to read/write
from/to a virtual disk file in vCenter/ESX and an adapter can be written for
this connection to support some of the file operations required by the backup
drivers. This implementation works for both Swift and Ceph backup drivers. But
the TSM backup driver raises &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;InvalidBackup&lt;/span&gt;&lt;/code&gt; exception if the volume to be
backed up is not a block device or regular file.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;vbala &amp;lt;&lt;a class="reference external" href="mailto:vbala%40vmware.com"&gt;vbala&lt;span&gt;@&lt;/span&gt;vmware&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;None&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;backup_volume&lt;/span&gt;&lt;/code&gt; method&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;restore_backup&lt;/span&gt;&lt;/code&gt; method&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 22 Jan 2015 00:00:00 </pubDate></item><item><title>Backup Notification</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/kilo/backup-notification.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/backup-notification"&gt;https://blueprints.launchpad.net/cinder/+spec/backup-notification&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This blueprint proposes to add the notification support to the backup
service in Cinder, so that cinder can report the usage status to Ceilometer
in backup create, delete and restore.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Cinder is supposed to send the notifications to ceilometer to report the
resource usage status. This notification support has been implemented for
the volume and the volume snapshot, but not the backup.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Create backup notification:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Send a notification to inform the Ceilometer the backup create begins.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Send a notification to inform the Ceilometer the backup create ends.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Delete backup notification:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Send a notification to inform the Ceilometer the backup delete begins.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Send a notification to inform the Ceilometer the backup delete ends.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Restore backup notification:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Send a notification to inform the Ceilometer the backup restore begins.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Send a notification to inform the Ceilometer the backup restore ends.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Progress notification:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;It is possible that some drivers can send a create.progress notifications
periodically. We make it configurable if the backup driver supports to
send periodic notifications.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The backup information sent to Ceilometer includes backup id, project id,
user id, available zone, host, display name, creation time, status, volume
id, size, service metadata, service and fail reason.&lt;/p&gt;
&lt;p&gt;For the progress notification, an additional data indicating the percentage
of the backup progress will be sent as well.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;This blueprint will add the notification support for the backup service.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The configuration option backup_object_number_per_notification has
been added to indicate how many chunks or objects have been sent
to the Ceilometer. It applies to the object or chunk based backup
service, e.g. Swift, Ceph.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Vincent Hou&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;None&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add the notification for the backup usage when creating a backup&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the notification for the backup usage when deleting a backup&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the notification for the backup usage when restoring a backup&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the progress notification for the backup usage when talking an object
store as the backup service.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit tests will be added for the backup notification calls.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The configuration option to configure the progress notifications
needs to be added for the backup driver, which supports to send
this type of notification.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Backup notification blueprint and bug replication design session
&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/backup-notification"&gt;https://blueprints.launchpad.net/cinder/+spec/backup-notification&lt;/a&gt;
&lt;a class="reference external" href="https://bugs.launchpad.net/cinder/+bug/1326431"&gt;https://bugs.launchpad.net/cinder/+bug/1326431&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Thu, 22 Jan 2015 00:00:00 </pubDate></item><item><title>Cinder Objects</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/kilo/cinder-objects.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/cinder-objects"&gt;https://blueprints.launchpad.net/cinder/+spec/cinder-objects&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The goal of this spec is to introduce objects into cinder.  An object is used
to bundle data with methods that can operate on them.  By implementing this
spec, we would be able to pass rich objects over RPC and decouple the
database schema implementation from SQLAlchemy, enabling support for NoSQL
databases.  Database schema independence is the biggest gain with this
proposal.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;There are a few problems that exists today in cinder:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The database implementation is directly tied to SQLAlchemy.  This limits
support for NoSQL databases.  It is a major reason behind this proposal.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cinder sends ids over RPC (e.g. volume id, snapshot id, consistency group
id, or backup id).  These ids are used to query the SQLAlchemy objects,
resulting in a database hit.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There are multiple places where database calls are made in cinder, and this
could result in race conditions.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;There is an approved proposal to put nova.objects into oslo as
oslo.versionedobjects (&lt;a class="reference external" href="https://review.openstack.org/#/c/127532/"&gt;https://review.openstack.org/#/c/127532/&lt;/a&gt;), which would
abstract versionable internal objects for use with RPC.  The plan is to adopt
oslo.versionedobjects and abstract volumes, snapshots, backups, consistency
groups, and quotas.&lt;/p&gt;
&lt;p&gt;Since it will take some time before versionedobjects goes into the oslo
library, the plan is to sync up with dansmith to get an early version of it
for cinder and transition to oslo.versionedobjects when it is ready.&lt;/p&gt;
&lt;p&gt;The proposed changes are:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Objects will be database schema independent.  The type of database
connection can be determined from the value of “connection” in cinder.conf,
which could be mysql, mongodb, db2, etc.  Depending on the type of
connection, the appropriate objects (e.g. cinder.objects.volume or
cinder.objects.nosql.volume) would be imported when objects.register_all()
is called.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Objects will be sent over RPC instead of ids, reducing the additional
database hits to query the SQLAlchemy objects.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Objects will be versioned, allowing older objects to be detected and taking
appropriate actions when the objects are incompatible, i.e. fail gracefully
or emulate older behavior.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To handle cases where the underlying volume, snapshot, backup, consistency
group, or quota could have been changed when the object is in flight,
additional arguments (e.g. expected_volume_state and expected_task_state)
would be included in the object save method, which would check against the
in-database copy of the volume, snapshot, backup, consistency group, or
quota before updates are made and fail gracefully or appropriately sync up
the data.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The work will be done incrementally in stages, as follows.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Obtain an early version of oslo.versionedobjects to be used in cinder.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Abstract volume snapshot into versionedobject.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Abstract volume backup into versionedobject.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Iteratively convert cinder internals to use volume snapshot object.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The goal is to have oslo.versionedobjects code base in by the end of kilo-2,
and the abstraction of a few cinder internals, e.g. volume snapshots and
backups, by that time also.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Cinder could continue to be tightly tied to SQLAlchemy, limiting support to
only SQL databases.  Also, the existing implementation of sending ids over RPC
can be left as-is.&lt;/p&gt;
&lt;p&gt;There are proposals for state machine/state enforcement and RPC versioning,
which would help with rolling upgrades and improve the stability of cinder.
However, you would still take an additional database hit when the volume,
snapshot, backup, or consistency group ids are used to query the SQLAlchemy
objects.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None.  Cinder objects provides an abstraction layer in cinder, allowing for
database schema independence.  These objects are a replacement for SQLAlchemy
objects that are being used to represent service, volume, volume type,
snapshot, quota, backup, consistency group and consistency group snapshot
throughout cinder internals.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Unknown.  There might be a minor hit in performance since SQLAlchemy objects
are abstracted into cinder objects.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Today, direct database calls are made to create, read, update, and delete
volumes, volume types, snapshots, quotas, backups, consistency groups and
consistency group snapshots, and others.  With the switch to an object model,
these calls will be made against the appropriate object methods.  It will take
some time to convert cinder internals over to the object model, so the
existing convention of direct database calls should be accepted until all
object models are in place.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;thang-pham&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Any help is welcome&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Obtain an early version of oslo.versionedobjects to be used in cinder.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Abstract volume snapshot into versionedobject.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Abstract volume backup into versionedobject.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Iteratively convert cinder internals to use volume snapshot object.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;By introducing objects, we are not changing the end user facing API or
functionality of cinder.  We are passing objects over RPC instead of ids.
Given this, no new tempest tests will be created.  However, relevant unit
tests will be created to test the new object code base.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;cinder-specs: &lt;a class="reference external" href="https://review.openstack.org/#/c/130044/"&gt;https://review.openstack.org/#/c/130044/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;oslo-specs: &lt;a class="reference external" href="https://review.openstack.org/#/c/127532/"&gt;https://review.openstack.org/#/c/127532/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Proof of concept: &lt;a class="reference external" href="https://review.openstack.org/#/c/131873/"&gt;https://review.openstack.org/#/c/131873/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Thu, 22 Jan 2015 00:00:00 </pubDate></item><item><title>Generic filter support for volume queries</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/kilo/db-volume-filtering.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/db-volume-filtering"&gt;https://blueprints.launchpad.net/cinder/+spec/db-volume-filtering&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The filtering support of the volume DB APIs is inconsistent. For example,
filtering is supported when querying all volumes and when querying volumes
by project. However, filtering is not supported when querying volumes by host
or by group.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;DB functions exist to get all volumes, to get all volumes in a particular
project, to get all volumes in a particular group, and to get all volumes
hosted on a particular host. See the following functions in the DB API:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;volume_get_all&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;volume_get_all_by_project&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;volume_get_all_by_group&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;volume_get_all_by_host&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Only the queries that get all volumes and that get all volumes by project
support additional filtering.&lt;/p&gt;
&lt;p&gt;The purpose of this blueprint is to make the filtering support consistent
across these APIs.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;The current Volume filtering logic is already encapsulated in the common
_generate_paginate_query function. The filtering needs to be moved into
a common function (something like _process_volume_filters) that would
update a model query object with the filter information.&lt;/p&gt;
&lt;p&gt;Then, for example, the volume_get_all_by_host could utilize it as follows:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;volume_get_all_by_host&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;filters&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="sd"&gt;"""Retrieves all volumes hosted on a host."""&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;host&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="nb"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;basestring&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_session&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;begin&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
            &lt;span class="n"&gt;host_attr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;getattr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Volume&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'host'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;conditions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;host_attr&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                          &lt;span class="n"&gt;host_attr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;op&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'LIKE'&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s1"&gt;'#%'&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
            &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_volume_get_query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;or_&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;conditions&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;filters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_process_volume_filters&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;filters&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Instead of adding filter support to the other volume APIs, a caller could
simply invoke the volume_get_all API with a filter that defines the host or
the group information. The downside of this approach is that is requires the
caller to understand how to form that query; this is especially problematic
for the host API since the filter is actually an OR of:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;A exact string match for the given host&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A REGEX match where the host matches a value in the form of “&amp;lt;host&amp;gt;#&amp;lt;pool&amp;gt;”&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Complicated DB filters could affect query performance; however, this already
exists for the volume_get_all and the volume_get_all_by_project APIs.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Steven Kaufer (kaufer)&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;None&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Refactor Volume filter logic in the sqlalchemy DB API into a common function
and invoke it from the existing _generate_paginate_query function&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update the functions to get volumes by host and by group to use the common
filtering function&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Since common filter processing will be used for all volume DB queries, the
existing test coverage is sufficient.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 22 Jan 2015 00:00:00 </pubDate></item><item><title>Filtering and weighing backends with driver supplied functions</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/kilo/filtering-weighing-with-driver-supplied-functions.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/filtering-weighing-with-driver-supplied-functions"&gt;https://blueprints.launchpad.net/cinder/+spec/filtering-weighing-with-driver-supplied-functions&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Cinder currently uses a filter scheduler to filter out unqualified backends
during volume operations.  The default filters and weigher do a good job of
filtering out the unqualified backends but there are occasions when they work
less than ideally.  For example, due to thin-provisioning or other advanced
data manipulation mechanisms backends may have, properties such as
“free capacity” will no longer be as useful when determing the best backend
to use.  A potential solution to this issue is to incorporate filtering and
weighing (goodness) functions that can be specified for each backend as part
of the scheduler decision making.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;The default filters and weighers being used by the Cinder scheduler are not
determining the most qualified backends to use in some cases.  If a backend
is using an advanced data manipulation mechanism such as thin-provisioning the
“free capacity” property, which is used by the default filters, will not be as
useful or accurate when determining an ideal backend.&lt;/p&gt;
&lt;p&gt;Another problem is that different backends use different metrics and only the
manufacturer really knows what they are.  This makes it hard/almost impossible
to create a global filter for these metrics.  An example of this would be if
there was a backend array with an absolute maximum capacity of 1000 volumes.
The performance of this array degrades if more than 75% of total space is
actually used.  There is also a maximum volume size of 500 GB.  These details
can be highly variable between vendors and even within different backend
arrays from the same vendor.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;The proposed solution for the above problem is to add two new properties to
the statistics that drivers support.  These two new properties will be a
filter and goodness function.  The details for the two new properties are
described here:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;filter_function&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt; &lt;span class="n"&gt;An&lt;/span&gt; &lt;span class="n"&gt;equation&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="n"&gt;that&lt;/span&gt; &lt;span class="n"&gt;when&lt;/span&gt; &lt;span class="n"&gt;evaluated&lt;/span&gt; &lt;span class="n"&gt;using&lt;/span&gt;
                     &lt;span class="n"&gt;PyParsing&lt;/span&gt; &lt;span class="n"&gt;will&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;  &lt;span class="n"&gt;Used&lt;/span&gt; &lt;span class="n"&gt;by&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;filter&lt;/span&gt;
                     &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;determine&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;backend&lt;/span&gt; &lt;span class="n"&gt;should&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;considered&lt;/span&gt; &lt;span class="n"&gt;by&lt;/span&gt;
                     &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;scheduler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;

&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;goodness_function&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt; &lt;span class="n"&gt;An&lt;/span&gt; &lt;span class="n"&gt;equation&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="n"&gt;that&lt;/span&gt; &lt;span class="n"&gt;when&lt;/span&gt; &lt;span class="n"&gt;evaluated&lt;/span&gt; &lt;span class="n"&gt;using&lt;/span&gt;
                       &lt;span class="n"&gt;PyParsing&lt;/span&gt; &lt;span class="n"&gt;will&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="n"&gt;between&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="mf"&gt;100.&lt;/span&gt;  &lt;span class="n"&gt;Used&lt;/span&gt;
                       &lt;span class="n"&gt;by&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;filter&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;which&lt;/span&gt; &lt;span class="n"&gt;valid&lt;/span&gt; &lt;span class="n"&gt;backend&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;best&lt;/span&gt;
                       &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;scheduler&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;use&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;An equation can be made up of any of the following operators as long as the
equation is valid:&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Operations&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;+, -, *, /, ^&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;standard math&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;not, and, or, &amp;amp;, |, !&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;logic&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;&amp;gt;, &amp;gt;=, &amp;lt;, &amp;lt;=, =, ==, &amp;lt;&amp;gt;, !=&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;equality&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;+, -&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;sign&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;x ? a : b&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;ternary&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;abs(x), max(x, y), min(x, y)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;math helper functions&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;New operators could be added in the future, if desired.  These ones should
cover the majority of equations an admin would need.&lt;/p&gt;
&lt;p&gt;When the scheduler attempts to find the best host it gets the stats for each
backend’s driver.  The backend(s) with the top goodness rating will be
returned to the scheduler.  There is a possibility of multiple backends because
there can be ties (three backends with goodness of 100).  Depending on the
weigher that an admin has chosen, such as capacity, random choice, etc, any
potential tie can be resolved and the winning backend will be chosen.&lt;/p&gt;
&lt;p&gt;If a backend’s driver does not return both filter_function and
goodness_function properties during stat reporting the new filter will default
to passing that backend and give it a goodness of 0.  When it comes time for
the schedueler to pick the best host a 0 would convert to a “use as a
last resort” rating.&lt;/p&gt;
&lt;p&gt;If a driver chooses not to implement the new properties it will return the
standard stats during reporting with no changes.  Example:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"volume_backend_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"array_one"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"pools"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s2"&gt;"pool_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"my_pool"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"percent_capacity_used"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"free_space"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"n_vols"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="o"&gt;...&lt;/span&gt;
      &lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="o"&gt;...&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Drivers that do choose to implement the new properties will need to report
the two new properties back during stat reporting.  An example is here:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"volume_backend_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"array_one"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"pools"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s2"&gt;"pool_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"my_pool"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"filter_function"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"(stats.n_vols &amp;lt; 1000) and (volume.size &amp;lt; 5)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"goodness_function"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"stats.percent_capacity_used &amp;lt; 75 ? 100 : 25"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"percent_capacity_used"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"free_space"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"n_vols"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="o"&gt;...&lt;/span&gt;
      &lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="o"&gt;...&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;When a driver’s get_volumes_stats method is called it is up to the driver to
determine how to generate the equations for both the filter and goodness
function properties.  Some choices a driver has are to use values defined in
cinder.conf, hard-code the values in the driver or not implement the
properties at all.  Drivers can implement other ways of achieving this, too, as
long as the requirements for the filter_function and goodness_function
properties are met.&lt;/p&gt;
&lt;p&gt;Here is an example of an implementation of how using cinder.conf values
would work.  An admin can setup the filter and goodness function properties
for each backend.  Example:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;foo_1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="n"&gt;filter_function&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"volume.size &amp;gt; 10 and volume.size &amp;lt;= 500"&lt;/span&gt;
&lt;span class="n"&gt;goodness_function&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"50"&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;foo_2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="n"&gt;filter_function&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"volume.size &amp;gt; 500"&lt;/span&gt;
&lt;span class="n"&gt;goodness_function&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"90"&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The new filter will only focus on filtering based on the filter/weighing
functions provided by a driver.  If an admin desires filtering capabilities,
such as for capacity, the other scheduling filters available in Cinder can be
used along with this one.&lt;/p&gt;
&lt;p&gt;In summary, implementing a new scheduling filter that allows for more
control over the filtering process with a filter and goodness function will
allow the best backend for a volume to be chosen correctly more often.  There
two potential downside to this solution.  First, the equations for the filter
and goodness functions are not validated until they are used by the scheduler.
If there is a typo or syntax error in either equation it will not be known
until the scheduler fails during evaluation.  In the future some form of
startup validation could be added to detect invalid equations.  A simpler
solution to implement for now would be to have the scheduler default to
assuming an invalid filter function is passing.  The goodness function would
have a default of 0 incase there is an invalid equation detected in the filter
or goodness functions.  The second downside is that the equations that
PyParsing will evaluate will require adequate documentation showing examples
of how the operators work, syntax , etc.  However, it should not be too hard
to document this.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;One alternative solution is to have two functions located in a file in a
known location (possibly the driver itself).  One function generates the
filter_function result and the other generates the goodness_function
result.  The backend driver would still return two new stat properties,
but they would now contain the import path for the needed functions.
The new filter will then import the needed functions and use them during
the filtering process.  There could also be default base functions incase
of a driver not implementing the new properties. Similar to the proposed
solution, a default of a pass and goodness of 0 would be given to those
backends using those drivers.  Selection of backends with tieing goodness
rating will be resolved in the same way as the proposed solution.&lt;/p&gt;
&lt;p&gt;Example of custom defined filter and goodness functions:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;def filter_function(stats, volume, qos_specs, extra_specs, **kwargs):
    # Return True or False
    return bool(evaluate((stats.n_vols &amp;lt; 1000) and (volume.size &amp;lt; 5)))

def goodness_function(stats, volume, qos_specs, extra_specs, **kwargs):
    # Return 0 to 100
    return clamp(evaluate(stats.percent_capacity_used &amp;lt; 75 ? 100 : 25))
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The returned stats from a driver would now look like this:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"volume_backend_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"array_one"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"pools"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s2"&gt;"pool_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"my_pool"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"filter_function"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"path.to.my.custom.module.filter_function"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"goodness_function"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"path.to.my.custom.module.goodness_function"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"percent_capacity_used"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"free_space"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"n_vols"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="o"&gt;...&lt;/span&gt;
      &lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="o"&gt;...&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Benefits of this solution are that the equations can be checked for typos and
syntax errors more easily since it will be Python code.  It would also be
possible to check for these errors on startup more easily than the proposed
solution.  Unit tests can be developed and maintained by an adminfor the
custom functions so that after an upgrade and an admin can ensure everything
is working still.&lt;/p&gt;
&lt;p&gt;Another benefit is that Python is a well documented language.  The PyParsing
operators used by admins to create equations will have to have documentation
written to explain how to use the various operators.&lt;/p&gt;
&lt;p&gt;A downside would be that admins would need to know how to work with python
functions.  Deciding how to maintain all the functions is another potential
downside depending on where they are placed.&lt;/p&gt;
&lt;p&gt;Another downside to this solution is that the functions are not coming from
the driver directly.  They will not be updated by or with the driver if an
admin is the one creating them.  Values returned by a driver can potentially
change over time, e.g. a backend getting many small volumes can use the
goodness value to lean towards wanting bigger volumes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;Filtering and goodness function equations can be optionally set in
cinder.conf by an admin.  The equations for each function will be strings
that are parsed using pyparsing.  An admin can enter anything they want for
the string.  Pyparsing should be able to filter out and throw an exception
for any dangerous strings that an admin may enter.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;Admins will be able to optionally set filtering and goodness function
equations in cinder.conf for backends if implemented by a driver.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Depending on the complexity of a given filtering or goodness function
equation there may be a slight performance decrease when it is evaluated
with PyParsing.  Simple equations will have minimal performance impact.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;A backend’s host stats, extra specs, volume info and qos specs will be
available to use in the filter and goodness functions.  Possibly more can be
exposed in the future.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;leeantho&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;kmartin&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Implement evaluator code using pyparsing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement a new driver filter for scheduler that will use the evaluator.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update driver code to return filter and goodness function properties during
stat reporting for a backend.  This only needs to occur if a driver wants
to implement support for this new filter.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;The pyparsing module (2.0.1 or later).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit tests can be used to validate the evaluator and filter code so new
Tempest tests are not needed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Documentation will be needed to detail what driver properties are exposed
for use in the filter/goodness functions.  Each driver would need to
provide their own documentation for what properties they have.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation will be needed to explain the syntax for the filter and
goodness function equations.  Samples of using each operator would be
good, too.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;Pyparsing :: &lt;a class="reference external" href="http://pyparsing.wikispaces.com/"&gt;http://pyparsing.wikispaces.com/&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 22 Jan 2015 00:00:00 </pubDate></item><item><title>Attach a single volume to multiple hosts</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/kilo/multi-attach-volume.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/multi-attach-volume"&gt;https://blueprints.launchpad.net/cinder/+spec/multi-attach-volume&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Currently, Cinder only allows a volume to be attached to a single
host or instance.  There are times when a user may want to be able
to attach the same volume to multiple instances.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently, Cinder only allows a volume to be attached to one instance
and or host at a time.  Nova makes an assumption in a number of places
that assumes the limitation of a single volume to a single instance.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;cinderclient only has volume as a parameter to the detach() call.  This
makes the assumption that a volume is only attached once.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;nova assumes that if a volume is attached, it can’t be attached again.
see nova/volume/cinder.py: check_attach()&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;Allow users to share volumes between multiple guests using either
read-write or read-only attachments. Clustered applications
with two nodes where one is active and one is passive. Both
require access to the same volume although only one accesses
actively. When the active one goes down, the passive one can take
over quickly and has access to the data.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;To enable the ability to attach a volume to multiple hosts or instances,
first we need a new volume_attachment table that tracks each attachment
for cinder volumes.   We will migrate the existing columns from the volume
table (attached_host, instance_uuid, mountpoint, attach_time, attach_mode).
The volume_attachment table will have an id (known as the attachment_id) that
tracks individual attachment records for each volume.  The existing cinder
volume object that is returned in the API calls has a list of attachments.
This attachment list will now also contain the attachment_id for each of the
attachments.&lt;/p&gt;
&lt;p&gt;That attachment_id is what nova will pass into cinder during detach API calls,
so that cinder knows which attachment to detach.   The cinder API will support
a default attachment_id of None, which will try to do a detach if there is only
a single attachment.&lt;/p&gt;
&lt;p&gt;If cinder doesn’t get the attachment_id, and the volume only has 1 attachment,
then the detach will work.  If the volume has more than one attachment, then
cinder will return an error saying that the volume has more than one attachment
and needs the attachment_id.&lt;/p&gt;
&lt;p&gt;The volume table will be updated to include a new column called ‘multiattach’,
which is a boolean flag to signal cinder that the volume can/can’t be attached
more than once.  The cinder API and cinderclient will be updated to support
setting the multiattach flag at volume attach time.  We can add support to
updating a volume record to enable the multiattach flag as well, or as a
follow up patch.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;The only alternative is for a user to clone a volume and attach the clone
to the second instance.   The downside to this is that any changes to the
original volume don’t show up in the mounted clone.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;The volume table will be modified to remove certain columns as they will be
migrated to the new volume_attachments table.&lt;/p&gt;
&lt;p&gt;A new volume_attachments table will be created to track all of the attachments
for volumes.&lt;/p&gt;
&lt;p&gt;Any existing attachments will be migrated to the new schema.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;The REST API will be changed in 2 ways.&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;A new multiattach flag can be passed for the create volume action.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The existing REST API already returns a list for attachments, even though
only one attachment is supported.  Now if a volume is multiattach enabled,
the attachments can return more than 1 entry.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Detach will accept an optional attachment_id to specify which attachment
to try and remove.   If the volume is attached to more than once host or
instance and the attachment_id is not passed in, the API will raise an
exception.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;When listing volumes, the multiattach flag will be shown from the command line
client.&lt;/p&gt;
&lt;p&gt;Also, the command line client will include an optional –allow-multiattach
to cinder create.  By default multiattach is False&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;A possible performance hit is the extra fetches to that volume_attachment
table at volume fetch time.  This is a simple foreign key table join, which
is indexed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Volume driver developers should ensure that they have their volumes attached
to more than one instance.   We should do a follow up patch on drivers to
add a ‘multiattach’ capability being reported.   We could update the
scheduler to filter out backends that can’t do multiattach.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;walter-boring (&lt;a class="reference external" href="mailto:walter.boring%40hp.com"&gt;walter&lt;span&gt;.&lt;/span&gt;boring&lt;span&gt;@&lt;/span&gt;hp&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Cinder needs to be updated to support the new API changes and to support
exporting a volume more than once.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cinderclient needs to be updated to support the new multiattach flag at
create time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cinderclient needs to be updated to support the new attachment_id being
passed at detach volume.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The nova-spec that is needed to support this, has already been approved.
&lt;a class="reference external" href="https://github.com/openstack/nova-specs/blob/master/specs/kilo/approved/multi-attach-volume.rst"&gt;https://github.com/openstack/nova-specs/blob/master/specs/kilo/approved/multi-attach-volume.rst&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;There will need to be new tempest tests in place to gate on multiattach.
That work is going on now as well.
&lt;a class="reference external" href="https://review.openstack.org/#/c/153038/"&gt;https://review.openstack.org/#/c/153038/&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Documentation should be updated to reflect the new API changes as well as the
new –allow-multiattach flag at volume create time.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Blueprints for all affected projects
&lt;a class="reference external" href="https://blueprints.launchpad.net/openstack/?searchtext=multi-attach-volume"&gt;https://blueprints.launchpad.net/openstack/?searchtext=multi-attach-volume&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Nova tests changes:
&lt;a class="reference external" href="https://review.openstack.org/#/c/153038/"&gt;https://review.openstack.org/#/c/153038/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cinder wiki page:
&lt;a class="reference external" href="https://wiki.openstack.org/wiki/Cinder/blueprints/multi-attach-volume"&gt;https://wiki.openstack.org/wiki/Cinder/blueprints/multi-attach-volume&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon work:
&lt;a class="reference external" href="https://blueprints.launchpad.net/horizon/+spec/cinder-multi-attach-volume"&gt;https://blueprints.launchpad.net/horizon/+spec/cinder-multi-attach-volume&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Thu, 22 Jan 2015 00:00:00 </pubDate></item><item><title>NFS backup driver for Cinder</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/kilo/nfs-backup.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/nfs-backup"&gt;https://blueprints.launchpad.net/cinder/+spec/nfs-backup&lt;/a&gt; [1]&lt;/p&gt;
&lt;p&gt;Currently, cinder-backup doesn’t support backup to an NFS-supplied
data repository.  This blueprint is for work to make this possible.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Currently backup of cinder volumes is available to  or Ceph
object stores, or via Tivoli Storage Manager.  These choices, while
appropriate for some, don’t address all OpenStack operators or
deployment scenarios.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Some OpenStack administrators who own NFS storage devices or scalable
NFS storage clusters want to leverage these to provide backup
for their cinder volumes, irrespective of whether NFS is used as
a cinder volume backend.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Some backend providers need dynamic mount management from OpenStack
as in the NFS volume drivers in order to better manage backup data
security, to provide a more deterministic environment for support
and service contracts, and to minimize dependencies external to
OpenStack distributions and automation packages.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The NFS backup driver should not replicate functionality provided
by the POSIX filesystem driver (currently in review, see [3]
and [4]).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;The following proposal presupposes a context in which the POSIX
filesystem driver ([3] and [4]) has been merged upstream and that
the POSIX filesystem driver, in turn, extends a “chunking” base
class that abstracts common functionality previously only in the
Swift backup driver (see [5] and [6]).&lt;/p&gt;
&lt;p&gt;We propose to implement a NFSBackupDriver class under the
POSIX filesystem BackupDriver class:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;                &lt;span class="o"&gt;+----------------------+&lt;/span&gt;
                &lt;span class="o"&gt;|&lt;/span&gt;                      &lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="o"&gt;+--------&amp;gt;|&lt;/span&gt;     &lt;span class="n"&gt;BackupDriver&lt;/span&gt;     &lt;span class="o"&gt;|&amp;lt;-----+&lt;/span&gt;
      &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;                      &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="o"&gt;+----------^-----------+&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="o"&gt;|&lt;/span&gt;                    &lt;span class="o"&gt;|&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="o"&gt;|&lt;/span&gt;                    &lt;span class="o"&gt;|&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+-----+------+&lt;/span&gt; &lt;span class="o"&gt;+-----------+---------+&lt;/span&gt; &lt;span class="o"&gt;+------+-----+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="n"&gt;TSM&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="n"&gt;Chunking&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="n"&gt;Ceph&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;BkupDriver&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="n"&gt;BkupDriver&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;BkupDriver&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="n"&gt;Base&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+------------+&lt;/span&gt; &lt;span class="o"&gt;+---^--------------+--+&lt;/span&gt; &lt;span class="o"&gt;+------------+&lt;/span&gt;
                   &lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;
                   &lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;
             &lt;span class="o"&gt;+-----+-----+&lt;/span&gt;  &lt;span class="o"&gt;+-----+------+&lt;/span&gt;
             &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="n"&gt;Swift&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="n"&gt;POSIX&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
             &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;BkupDriver&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;BkupDriver&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
             &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
             &lt;span class="o"&gt;+-----------+&lt;/span&gt;  &lt;span class="o"&gt;+-----^------+&lt;/span&gt;
                                  &lt;span class="o"&gt;|&lt;/span&gt;
                                  &lt;span class="o"&gt;|&lt;/span&gt;
                            &lt;span class="o"&gt;+-----+------+&lt;/span&gt;
                            &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="n"&gt;NFS&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;
                            &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;BkupDriver&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
                            &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
                            &lt;span class="o"&gt;+------------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The NFS Backup Driver will override the parent POSIX file system
driver’s __init__() method in order to do dynamic mount management
using “brick” code shared with the volume driver for this purpose, as
in [2].  With this extension, it will connect to an externally
provisioned NFS share at initialization.&lt;/p&gt;
&lt;p&gt;This generic NFS Backup Driver will otherwise just inherit methods
to create, delete, and restore from backups from its parent.&lt;/p&gt;
&lt;p&gt;Backend vendors who can add value by, e.g. data transfer techniques
that avoid or reduce transfer operations between the cinder node and
the backend storage array can themselves extend the generic NFS Backup
Driver. To this end, we have agreed that the POSIX backup driver will
explicitly implement a generic data transfer method which subclasses
can override, or will inherit this generic method from the Chunking
Base Class. Moreover, while this generic data transfer method can
implement compression as an option, it is critical that it be only an
option since backends may choose to implement compression or
deduplication themselves.&lt;/p&gt;
&lt;p&gt;A benefit of the approach presented here is that a user should be able
to switch between posix, NFS, and vendor-specific extensions of the
NFS backup driver, and backup operations will continue to work even
though they use different data transfer mechanisms.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;In the diagram, the common code shared by Swift and POSIX is
implemented via inheritance and an “is-a” relationship.  A “has-a”
relationship to a library would also work for this proposal.&lt;/p&gt;
&lt;p&gt;If other NAS drivers (GlusterFS, SMB, etc.) elect to also implement
dynamic mount management, we can abstract out a RemoteFS Backup Driver
as their common parent and interpolate it between the NFS backup
driver (and other NAS drivers) and the POSIX filesystem driver.  Or we
may be able to just share most configuration options and promote the
original NFS Backup Driver implementation to the RemoteFS driver role.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;NFS backups will run as a non-root user and the proposed driver will
not elevate user privileges except when it mounts the backup
repository.  When it does the mount, it will invoke brick code to do
so.  Thus the only privilege elevation from this driver will be in a
common library.  That library has been audited and tweaked as
part of recent NFS security enhancements [7], addressing the NFS side
of launchpad bug 1260679 [8].&lt;/p&gt;
&lt;p&gt;Because the backup driver runs as a regular user it works with secure
NAS environments in which root squash is enabled.&lt;/p&gt;
&lt;p&gt;The backup driver will chmod ‘660’ actual backup data and metadata
and chmod ‘770’ directories in the path to same.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Backup service can in general have performance impact.  Future
enhancements to or extensions of this driver class could seek to
reduce data transfer bandwidth during backup and restore or pursue
differential backup strategies to reduce the amount of work involved
in typical backups.&lt;/p&gt;
&lt;p&gt;POSIX path backups can potentially produce directories containing
a large number of backup files, such that directory operations could
be very costly.  We should implement some directory hierarchy to keep
directories sized well.  See [2] for one way to do this.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;p&gt;Backup data and metadata will be written to the repository at unique
paths that are a function of the backup ID.  That path will be stored
in the backup record service_metatdata so that it can be used to
navigate to the backup data and metadata for restore and delete
operations.&lt;/p&gt;
&lt;p&gt;Backup and restore operations will share a common method for transfer
of data from volume to backup and vice versa.  This method will be
initially implemented as a naive block copy but will allow for
enhancement or extension to e.g. reduce or eliminate data movement
between the cinder node and the NFS server for the backup repository.&lt;/p&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Tom Barron (tbarron)&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Kevin Fox (kfox1111) - POSIX filesystem driver and Chunking Base class&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Appropriate unit tests will be added.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Existing tests with backup_driver option in cinder.conf set
for the NFS driver rather than for Swift will provide tempest coverage.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Update the backup section of the OpenStack Configuration Reference to indicate
how to perform volume backups using an NFS server.  Specifically, document:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;New value for cinder.conf backup_driver option: cinder.backup.drivers.nfs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;New cinder.conf option ‘backup_nfs_share’ with default value None and values
in one of the following formats:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;fqdn&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;posix&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ipv4addr&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;posix&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ipv6addr&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;posix&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;New cinder.conf option ‘backup_nfs_mount_options’ with default value None
and values as specified in NFS man pages and as used in the NFS volume
driver.  Note: it may make sense to set the default to values tuned for
backup performance rather than leaving the default None if we can agree
on such values for NFS common.  Otherwise, different NFS backends will
likely want to extend this class and set optimal backend-specific default
options.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;[1]: &lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/nfs-backup"&gt;https://blueprints.launchpad.net/cinder/+spec/nfs-backup&lt;/a&gt;
[2]: &lt;a class="reference external" href="https://review.openstack.org/#/c/138234"&gt;https://review.openstack.org/#/c/138234&lt;/a&gt;
[3]: &lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/add-backup-driver-nas-storage"&gt;https://blueprints.launchpad.net/cinder/+spec/add-backup-driver-nas-storage&lt;/a&gt;
[4]: &lt;a class="reference external" href="https://review.openstack.org/#/c/82996"&gt;https://review.openstack.org/#/c/82996&lt;/a&gt;
[5]: &lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/chunked-backup-base-class"&gt;https://blueprints.launchpad.net/cinder/+spec/chunked-backup-base-class&lt;/a&gt;
[6]: &lt;a class="reference external" href="https://review.openstack.org/#/c/139737/"&gt;https://review.openstack.org/#/c/139737/&lt;/a&gt;
[7]: &lt;a class="reference external" href="https://review.openstack.org/#/c/107693"&gt;https://review.openstack.org/#/c/107693&lt;/a&gt;
[8]: &lt;a class="reference external" href="https://bugs.launchpad.net/cinder/+bug/1260679"&gt;https://bugs.launchpad.net/cinder/+bug/1260679&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 22 Jan 2015 00:00:00 </pubDate></item><item><title>Private Volume Types</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/kilo/private-volume-types.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/private-volume-types"&gt;https://blueprints.launchpad.net/cinder/+spec/private-volume-types&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Cinder volume types are visible to all users, regardless of their project.&lt;/p&gt;
&lt;p&gt;This blueprint suggests the introduction of private volume types.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Some volume types should only be restricted. Examples are test volume types
where a new technology is being tried out or ultra high performance volumes
for special needs where most users should not be able to select these volumes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Similar approaches are taken with the is_public flag on flavors in Nova.
We should leverage the work done in Nova and port it for Cinder volume types.&lt;/p&gt;
&lt;p&gt;Volume types currently do not have an owner associated to them. This feature
does not suggest the introduction of an owner for various reasons, one being
that it is impossible to find the original owner of an existing volume type.&lt;/p&gt;
&lt;p&gt;The proposed approach is the one already in place in Nova:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Volume types are public by default&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Private volume types can be created by setting the is_public boolean field
to False at creation time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Access to a private volume type can be controlled by adding or removing
a project from it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Private volume types without projects are only visible by users
with the admin role/context.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;There is no known alternative ways to restrict access to a volume type.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;Database schema changes:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;A new is_public boolean column will be added to the volume_types table.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A new volume_type_projects table will be created for projects having access
to a particular volume types. There will be one entry in volume_type_projects
table for every volume_type_id and project_id combination.
It will be a many-to-many relationship.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;mysql&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;DESC&lt;/span&gt; &lt;span class="n"&gt;volume_types&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;+--------------+--------------+------+-----+---------+-------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Field&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Type&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Null&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Key&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Default&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Extra&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+--------------+--------------+------+-----+---------+-------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;created_at&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;YES&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;updated_at&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;YES&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;deleted_at&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;YES&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;deleted&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;tinyint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;YES&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;varchar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NO&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;PRI&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;varchar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;YES&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;qos_specs_id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;varchar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;YES&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;MUL&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;is_public&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;tinyint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;YES&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+--------------+--------------+------+-----+---------+-------+&lt;/span&gt;
&lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.00&lt;/span&gt; &lt;span class="n"&gt;sec&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;mysql&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;DESC&lt;/span&gt; &lt;span class="n"&gt;volume_type_projects&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;+----------------+--------------+------+-----+---------+----------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Field&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Type&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Null&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Key&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Default&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Extra&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+----------------+--------------+------+-----+---------+----------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NO&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;PRI&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;auto_increment&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;created_at&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;YES&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;updated_at&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;YES&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;deleted_at&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;YES&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;volume_type_id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;varchar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;YES&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;MUL&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;project_id&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;varchar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;YES&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;deleted&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;tinyint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;YES&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+----------------+--------------+------+-----+---------+----------------+&lt;/span&gt;
&lt;span class="mi"&gt;7&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.00&lt;/span&gt; &lt;span class="n"&gt;sec&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Database data migration:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Existing volume types will be marked as public (is_public=1)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Extend volume type creation response to include is_public field&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Extend volume type list to include is_public field&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Extend volume type detail to include is_public field&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add ability to list projects having access to a specific volume type&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add ability to add/remove access for a project to a specific volume type&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add policy for the new extension&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;This change introduces the concept of private volume types.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Horizon should be updated to support this new extension.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;python-cinderclient should be updated to allow the use of this new extension.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Proposed python-cinderclient shell interface:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;access&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;volume&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
   &lt;span class="n"&gt;Add&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="n"&gt;access&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;given&lt;/span&gt; &lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;

&lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;access&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;list&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;volume&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
   &lt;span class="n"&gt;Print&lt;/span&gt; &lt;span class="n"&gt;access&lt;/span&gt; &lt;span class="n"&gt;information&lt;/span&gt; &lt;span class="n"&gt;about&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;given&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;

&lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;access&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;remove&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;volume&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
   &lt;span class="n"&gt;Remove&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="n"&gt;access&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;given&lt;/span&gt; &lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;The extension adds an is_public field to all returned volumes.&lt;/p&gt;
&lt;p&gt;Special care should be taken to not generate N requests per volume list.
This can easily be addressed by a caching mechanism at the API layer.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;mgagne&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;None&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Implement os-volume-type-access Cinder extension&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add support for os-volume-type-access extension to python-cinderclient&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add support for os-volume-type-access extension to Horizon&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit tests already in place in Nova for flavors will be ported
for Cinder volume types.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use cases should be added to Tempest.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Need to document the new os-volume-type-access Cinder extension.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://lists.openstack.org/pipermail/openstack-operators/2014-June/004561.html"&gt;http://lists.openstack.org/pipermail/openstack-operators/2014-June/004561.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Thu, 22 Jan 2015 00:00:00 </pubDate></item><item><title>Support iSER driver within the ISCSIDriver flow</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/kilo/support-iscsi-driver.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/support-iscsi-driver"&gt;https://blueprints.launchpad.net/cinder/+spec/support-iscsi-driver&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This purpose of this BP is to avoid code duplications of classes and
parameters, and to prevent instability in the iSER driver flow,
for the TGT and LIO cases.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Currently the iSER driver is supported over TGT only, without LIO support.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There are a couple of iSER classes that inherit from iSCSI driver/target
classes, but most of their functionality is the same as the iSCSI classes.
This code duplication causes instability in the iSER driver code, when new
features or changes are added to the iSCSI driver flow.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;These two problems can be solved by adding a small fix, which includes a new
enable_iser parameter within iSCSI Tgt/LIO classes.&lt;/p&gt;
&lt;p&gt;All that is needed for RDMA support over iSER, in the Tgt and LIO cases, is
to set just one extra parameter in the volume creation stage.&lt;/p&gt;
&lt;p&gt;A deprecation alert will be added to ISERTgtAdm, since This change will act as
a replacement to the current iSER Tgt code.&lt;/p&gt;
&lt;p&gt;The Nova part of this spec is specified at:
&lt;a class="reference external" href="https://review.openstack.org/#/c/130721/"&gt;https://review.openstack.org/#/c/130721/&lt;/a&gt;&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Leaving ISERTgtAdm, LVMISERDriver, ISERDriver and iser_opts the way they are,
or just deprecating a part of them (but it will miss the purpose of this code
refactoring).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;Adding a new “enable_iser” parameter, set to “False” by default.
This parameter will be used in TGT or LIO volume creation for setting
RDMA based portals.&lt;/p&gt;
&lt;p&gt;This single parameter will deprecate all iser_opts parameters, that are
a duplication from iscsi parameters.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;This change will simplify the maintanance of the iSER driver flow, since no
extra classes or duplicated parameters will be used.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Aviram Bar-Haim &amp;lt;&lt;a class="reference external" href="mailto:aviramb%40mellanox.com"&gt;aviramb&lt;span&gt;@&lt;/span&gt;mellanox&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Fix bug &lt;a class="reference external" href="https://bugs.launchpad.net/cinder/+bug/1396265"&gt;https://bugs.launchpad.net/cinder/+bug/1396265&lt;/a&gt; and add the correct
driver parameter, with a configurable value to VOLUME_CONF and
VOLUME_CONF_WITH_CHAP_AUTH.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a new “enable_iser” parameter that is set to false by default.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set the driver parameter at the VOLUME_CONFs template in TgtAdm for the
TGT case.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add _set_iser(1) on the network portal object in rtslib for the LIO case,
according to “enable_iser” value.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set ISCSIDriver’s “driver_volume_type” to “iscsi” or “iser” value, according
to the “enable_iser” value.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;HW that supports RDMA is required in order to test volume attachment over
iSER.&lt;/p&gt;
&lt;p&gt;A new unit test will be added with the new enable_iser parameter over
iSCSI volume driver.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;After adding the new enable_iser parameter, An updated iSER configuration
guidelines will be added to:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://wiki.openstack.org/wiki/Mellanox-Cinder"&gt;https://wiki.openstack.org/wiki/Mellanox-Cinder&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/juno/config-reference/content/lvm-volume-driver.html"&gt;http://docs.openstack.org/juno/config-reference/content/lvm-volume-driver.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://community.mellanox.com/docs/DOC-1462"&gt;http://community.mellanox.com/docs/DOC-1462&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 22 Jan 2015 00:00:00 </pubDate></item><item><title>Support Volume Backup Quota</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/kilo/support-volume-backup-quota.html</link><description>

&lt;p&gt;Include the URL of your launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/support-volume-backup-quota"&gt;https://blueprints.launchpad.net/cinder/+spec/support-volume-backup-quota&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Provide a mean to control volume backup’s quota.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Since quota take volumes, snapshots and gigabytes into account, it also needs
to take backup into account:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Currently Backup create API is not an admin API, users of projects could
create any number of backups.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If some evil users create many more big backups to exhaust the free space
of backup storage back-end, it would cause cinder-backup in the state of
rejecting service.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;By supporting volume backup quota, we need to do the following changes.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Add the default quota of backup number quota item and backup gigabytes quota
item.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cinder quota update API support backup number quota and backup gigabytes
quota create and update operation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cinder quota show/defaults API support displaying backup quota info.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Quota Engine support processing with backup quota item.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Class&lt;/span&gt; &lt;span class="n"&gt;QuotaEngine&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;Class&lt;/span&gt; &lt;span class="n"&gt;VolumeTypeQuotaEngine&lt;/span&gt; &lt;span class="n"&gt;support&lt;/span&gt; &lt;span class="n"&gt;processing&lt;/span&gt;
&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;backup&lt;/span&gt; &lt;span class="n"&gt;quota&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;Add&lt;/span&gt; &lt;span class="n"&gt;_sync_backups&lt;/span&gt; &lt;span class="n"&gt;function&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="n"&gt;one&lt;/span&gt; &lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="s1"&gt;'s backup number.&lt;/span&gt;
&lt;span class="n"&gt;Add&lt;/span&gt; &lt;span class="n"&gt;_sync_backup_gigabytes&lt;/span&gt; &lt;span class="n"&gt;function&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="n"&gt;one&lt;/span&gt; &lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="s1"&gt;'s backup&lt;/span&gt;
&lt;span class="n"&gt;gigabytes&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;Add&lt;/span&gt; &lt;span class="n"&gt;configuration&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="n"&gt;no_backup_gb_quota&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;which&lt;/span&gt; &lt;span class="n"&gt;indicates&lt;/span&gt; &lt;span class="n"&gt;whether&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt;
&lt;span class="n"&gt;take&lt;/span&gt; &lt;span class="n"&gt;backup&lt;/span&gt;&lt;span class="s1"&gt;'s size into account with backup gigabytes quota.&lt;/span&gt;
&lt;span class="n"&gt;Add&lt;/span&gt; &lt;span class="s1"&gt;'_sync_backup'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;_sync_backups&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;QUOTA_SYNC_FUNCTIONS&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;Add&lt;/span&gt; &lt;span class="s1"&gt;'_sync_backup_gigabytes'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;_sync_backup_gigabytes&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt;
&lt;span class="n"&gt;QUOTA_SYNC_FUNCTIONS&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Backup create/delete routine support dealing with backup number quota and
backup gigabytes quota.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Limits API support displaying one project’s current used number and maximum
number of backup number and backup gigabytes info.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;Change the following APIs’ return value.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Cinder quota show/defaults API&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Current return value:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"quota_set"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"gigabytes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"snapshots"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"volumes_rbd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"volumes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"gigabytes_rbd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"snapshots_rbd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"bb2ec78e61d3493da61449f3c69db3f3"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;New return value:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"quota_set"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"gigabytes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"snapshots"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"volumes_rbd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"volumes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"snapshots_rbd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"gigabytes_rbd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"backups"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;          &lt;span class="c1"&gt;# new add return item&lt;/span&gt;
        &lt;span class="s2"&gt;"backup_gigabytes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# new add return item&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"bb2ec78e61d3493da61449f3c69db3f3"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Limit index API return value&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Current return value:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"limits"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"rate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
        &lt;span class="s2"&gt;"absolute"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"totalSnapshotsUsed"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"maxTotalVolumeGigabytes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"totalGigabytesUsed"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"maxTotalSnapshots"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"totalVolumesUsed"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;    &lt;span class="c1"&gt;#new add return item&lt;/span&gt;
            &lt;span class="s2"&gt;"maxTotalVolumes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;     &lt;span class="c1"&gt;# new add return item&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;New return value:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"limits"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"rate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
        &lt;span class="s2"&gt;"absolute"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"totalSnapshotsUsed"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"maxTotalVolumeGigabytes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"totalGigabytesUsed"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"maxTotalSnapshots"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"totalVolumesUsed"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"maxTotalVolumes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"totalBackupsUsed"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;       &lt;span class="c1"&gt;# new add return item&lt;/span&gt;
            &lt;span class="s2"&gt;"maxBackupsUsed"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;        &lt;span class="c1"&gt;# new add return item&lt;/span&gt;
            &lt;span class="s2"&gt;"totalBackupGigabytesUsed"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# new add return item&lt;/span&gt;
            &lt;span class="s2"&gt;"maxTotalBackupGigabytes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# new add return item&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;DoS via resource exhaustion of backup resources is prevented.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;The return values of Cinder quota show/defaults API and limits API
have changed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;ling-yun&amp;lt;&lt;a class="reference external" href="mailto:zengyunling%40huawei.com"&gt;zengyunling&lt;span&gt;@&lt;/span&gt;huawei&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Implement code that mentioned in “Proposed change”.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add change API doc.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Both unit and Tempest tests need to be created to cover the code change that
mentioned in “Proposed change” and ensure that Cinder Quota feature works well
while adding support for volume backup.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;The cinder API documentation will need to be updated to reflect the REST API
changes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 22 Jan 2015 00:00:00 </pubDate></item><item><title>Unit test cases for cinder scripts</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/kilo/unit-test-cases-for-cinder-scripts.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/unit-test-cases-for-cinder-scripts"&gt;https://blueprints.launchpad.net/cinder/+spec/unit-test-cases-for-cinder-scripts&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Currently, there are no unit tests to test
bin/cinder-{all, api, backup, manage, rtstool, scheduler, volume}.
Adding unit tests for these scripts can help prevent issues similar to
&lt;a class="reference external" href="https://review.openstack.org/#/c/79791/"&gt;https://review.openstack.org/#/c/79791/&lt;/a&gt;, as well as increase test coverage.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;There are no unit tests to test
bin/cinder-{all, api, backup, manage, rtstool, scheduler, volume}.  Adding unit
tests for these scripts can help prevent issues similar to
&lt;a class="reference external" href="https://review.openstack.org/#/c/79791/"&gt;https://review.openstack.org/#/c/79791/&lt;/a&gt;, where a non-existent module was
imported.  Furthermore, it increases the test coverage for each cinder script.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;In order to create unit tests for
bin/cinder-{all, api, backup, manage, rtstool, scheduler, volume}, we have to
move them into cinder/cmd, and use pbr to setup the correct console scripts,
which will call the respective main function of each script under cinder/cmd.
It will allow us to import from cinder.cmd and individually test each command.&lt;/p&gt;
&lt;p&gt;nova already have their scripts under nova/cmd and uses pbr to setup the
correct console scripts.  It is also the same with glance, where it has
unit tests similar to the one proposed, i.e.
glance/tests/unit/api/test_cmd.py.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;The existing setup can be left as-is and no modifications made.  However, this
alternative opens up the possibility of more issues similar to
&lt;a class="reference external" href="https://review.openstack.org/#/c/79791/"&gt;https://review.openstack.org/#/c/79791/&lt;/a&gt; being introduced into the cinder code.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;thangp&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;eharney&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Move bin/cinder-{all, api, backup, manage, rtstool, scheduler, volume} into
cinder/cmd/cinder_{all, api, backup, manage, rtstool, scheduler, volume}.py.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use pbr entry_points to manage the cinder scripts.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create positive and negative unit test cases for each cinder command under
cinder/cmd, i.e.
cinder_{all, api, backup, manage, rtstool, scheduler, volume}.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;The goal is to create positive and negative unit tests cases for each cinder
script that is currently under bin/.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Packagers should be aware of the following changes to setup.cfg.&lt;/p&gt;
&lt;p&gt;cinder uses pbr to handle packaging.  The cinder scripts that is under the
[files] section will be moved to the [entry_points] section of setup.cfg.
More specifically, this proposal adds console_scripts to the [entry_points]
section of setup.cfg as follows:&lt;/p&gt;
&lt;div class="highlight-ini notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;[entry_points]&lt;/span&gt;
&lt;span class="na"&gt;console_scripts&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;
&lt;span class="na"&gt;cinder-all&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;cinder.cmd.cinder_all:main&lt;/span&gt;
&lt;span class="na"&gt;cinder-api&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;cinder.cmd.api:main&lt;/span&gt;
&lt;span class="na"&gt;cinder-backup&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;cinder.cmd.backup:main&lt;/span&gt;
&lt;span class="na"&gt;cinder-manage&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;cinder.cmd.manage:main&lt;/span&gt;
&lt;span class="na"&gt;cinder-rtstool&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;cinder.cmd.rtstool:main&lt;/span&gt;
&lt;span class="na"&gt;cinder-scheduler&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;cinder.cmd.scheduler:main&lt;/span&gt;
&lt;span class="na"&gt;cinder-volume&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;cinder.cmd.volume:main&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This will cause each console script to be installed that executes the main
functions found in cinder.cmd.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Original code proposed by eharney: &lt;a class="reference external" href="https://review.openstack.org/#/c/52229/"&gt;https://review.openstack.org/#/c/52229/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Original issue: &lt;a class="reference external" href="https://review.openstack.org/#/c/79791/"&gt;https://review.openstack.org/#/c/79791/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Thu, 22 Jan 2015 00:00:00 </pubDate></item><item><title>Integrate VMDK driver with oslo.vmware library</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/kilo/vmdk-oslo.vmware.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/vmdk-oslo.vmware"&gt;https://blueprints.launchpad.net/cinder/+spec/vmdk-oslo.vmware&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The common code between various VMware drivers was moved to the oslo.vmware
library during Icehouse release. The VMDK driver should be updated to use
this library.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;The oslo.vmware library (&lt;a class="reference external" href="https://github.com/openstack/oslo.vmware"&gt;https://github.com/openstack/oslo.vmware&lt;/a&gt;) contains
code for invoking VIM/SPBM APIs, session management, API retry and
upload/download of virtual disks. The VMware drivers for nova, glance and
ceilometer have already integrated with oslo.vmware. This spec proposes
the integration of VMDK driver with oslo.vmware.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Changes are mostly replacing import statements for the following modules:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Replace api with oslo.vmware.api&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Replace vim with oslo.vmware.vim&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Replace pbm with oslo.vmware.pbm&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Replace io_util with oslo.vmware.image_transfer&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Replace vmware_images with oslo.vmware.image_transfer&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Replace read_write_util with oslo.vmware.rw_handles&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Remove duplicate exceptions in error_util and use oslo.vmware.exceptions&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;The oslo.vmware version mentioned in the requirements file needs to be
installed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;vbala &amp;lt;&lt;a class="reference external" href="mailto:vbala%40vmware.com"&gt;vbala&lt;span&gt;@&lt;/span&gt;vmware&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;None&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add dependency on oslo.vmware and replace import statements&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Remove duplicate exceptions and use the ones defined in oslo.vmware&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete unused modules including their unit tests&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit tests for the duplicate modules will be removed. There won’t be any new
tests as the changes are purely code reorganization.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 22 Jan 2015 00:00:00 </pubDate></item><item><title>Volume Type Description</title><link>http://specs.openstack.org/openstack/cinder-specs/specs/kilo/volume-type-description.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/cinder/+spec/volume-type-description"&gt;https://blueprints.launchpad.net/cinder/+spec/volume-type-description&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This blueprint proposes to add the description information for a volume type
and allow user to find out what is the default volume type.
Volume type description and default volume type can help a user make an
informed decision when the user creates a volume.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Cinder volume types only have abstract names like gold, silver and bronze
or whatever the Openstack administrator comes up with. When a user creates
a volume and chooses which volume type to use, currently it is difficult
for a user to find out what the volume type means.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When a user creates a volume without specifying a volume type, once the
volume gets created, the volume type assigned to that volume could be a
default volume type or None. There is no way for a user to find out
what is the default volume type.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="use-cases"&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;When an administrator creates a volume type, allows him/her to enter some
descriptions for the volume type. The length of the description should be
between 0 - 255. It should be in the form of a string.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Administrator can also update the descriptions of an existing volume type.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;User should be able to get all the descriptions of all the volume
types.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;User should be able to get the descriptions of a volume type.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;User should be able to find out what is the default volume type.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;Database schema changes:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;A new description column will be added to the volume_types table.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;mysql&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;DESC&lt;/span&gt; &lt;span class="n"&gt;volume_types&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;+--------------+--------------+------+-----+---------+-------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Field&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Type&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Null&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Key&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Default&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Extra&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+--------------+--------------+------+-----+---------+-------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;created_at&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;YES&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;updated_at&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;YES&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;deleted_at&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;YES&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;deleted&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;tinyint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;YES&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;varchar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NO&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;PRI&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;varchar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;YES&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;qos_specs_id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;varchar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;YES&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;MUL&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;varchar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;YES&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+--------------+--------------+------+-----+---------+-------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Database data migration:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Existing volume types will have description empty.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Update “create volume type” REST request to to include description field.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update “list volume types” REST response to include description field for
each volume type&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update “show volume type information” REST response to include description
field.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add “update volume type” REST API to update an existing volume type.
* PUT /v2/{tenant_id}/types/{volume_type_id}&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;JSON request schema definition:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="s1"&gt;'volume_type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'gold'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'description'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'gold means very important'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;JSON response schema definition:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="s1"&gt;'volume_type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'4b502fcb-1f26-45f8-9fe5-3b9a0a52eaf2'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'gold'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'description'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'gold means very important'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'extra_specs'&lt;/span&gt;&lt;span class="p"&gt;:{}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Normal http response code: 200&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Expected error http response code: 400, 404, 500, 409&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add “get default volume type” REST API&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;GET /v2/{tenant_id}/types/default&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;JSON response schema definition:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="s1"&gt;'volume_type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'4b502fcb-1f26-45f8-9fe5-3b9a0a52eaf2'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'bronze'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'description'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'bronze means limited storage'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'extra_specs'&lt;/span&gt;&lt;span class="p"&gt;:{}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Normal http response code: 200&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Expected error http response code: 404&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;Creating or updating volume type description is usually only allowed for an
administrator user.&lt;/p&gt;
&lt;p&gt;Regular user should be able to get a volume type, list volume types and get
the default volume type.&lt;/p&gt;
&lt;p&gt;The APIs accesses will be controlled by security policy.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;Volume type creation has already sent a notification when creation ends or
has errors. Will send a notification when updating a volume type ends or has
errors.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;python-cinderclient will be changed to reflect the API changes.&lt;/p&gt;
&lt;p&gt;volume_types.create will be updated to include description.
volume_types.get_default will be added to show the default volume type.
volume_types.update will be added to update the description of the volume
type.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon will have corresponding UI changes to deal with the descriptions for
a volume type after python-cinderclient implementation.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Adding another db column in the volume type field means that each fetch of a
volume type will pull the description. It is a minimal impact for individual
volume type reads. It is doubtful if there will be a significant number of
volume types created with lots of descriptions. So, the performance impact
should be minimal.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;DB volume_types table migration and associated volume service restart will
require orchestration and a short service downtime. Transient API errors might
happen between the schema migration and the deployment of the new code
(which ever order they are done in).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;gloria-gu&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;None&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Implement Cinder API changes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement DB schema changes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement DB migration script changes.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;cinder/db/sqlalchemy/migrate_repo/versions&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement python-cinderclient changes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cinder API unit Tests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DB migration unit test changes.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;cinder/tests/test_migrations.py&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;Horizon blueprint will depend on this spec:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/horizon/+spec/volume-type-description"&gt;https://blueprints.launchpad.net/horizon/+spec/volume-type-description&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Update the unit tests to reflect the API changes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update the DB migration tests.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The Cinder API documentation will need to be updated to reflect the API
changes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Cinder client documentation will be need to be updated to reflect the
changes.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 22 Jan 2015 00:00:00 </pubDate></item></channel></rss>