Merge "Delete doc/source in code/daisy"

This commit is contained in:
Jenkins 2016-10-10 06:47:35 +00:00 committed by Gerrit Code Review
commit 5727ae2c0a
88 changed files with 0 additions and 7700 deletions

View File

@ -1,52 +0,0 @@
# Copyright 2014 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from oslo_log import log as logging
from daisy.common.scripts.image_import import main as image_import
from daisy import i18n
_LI = i18n._LI
_LE = i18n._LE
LOG = logging.getLogger(__name__)
def run_task(task_id, task_type, context,
task_repo=None, image_repo=None, image_factory=None):
# TODO(nikhil): if task_repo is None get new task repo
# TODO(nikhil): if image_repo is None get new image repo
# TODO(nikhil): if image_factory is None get new image factory
LOG.info(_LI("Loading known task scripts for task_id %(task_id)s "
"of type %(task_type)s"), {'task_id': task_id,
'task_type': task_type})
if task_type == 'import':
image_import.run(task_id, context, task_repo,
image_repo, image_factory)
else:
msg = _LE("This task type %(task_type)s is not supported by the "
"current deployment of daisy. Please refer the "
"documentation provided by OpenStack or your operator "
"for more information.") % {'task_type': task_type}
LOG.error(msg)
task = task_repo.get(task_id)
task.fail(msg)
if task_repo:
task_repo.save(task)
else:
LOG.error(_LE("Failed to save task %(task_id)s in DB as task_repo "
"is %(task_repo)s"), {"task_id": task_id,
"task_repo": task_repo})

View File

@ -1,134 +0,0 @@
# Copyright 2014 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import urllib2
from oslo_log import log as logging
from daisy.common import exception
from daisy import i18n
__all__ = [
'get_task',
'unpack_task_input',
'set_base_image_properties',
'validate_location_uri',
'get_image_data_iter',
]
LOG = logging.getLogger(__name__)
_ = i18n._
_LE = i18n._LE
def get_task(task_repo, task_id):
"""Gets a TaskProxy object.
:param task_repo: TaskRepo object used to perform DB operations
:param task_id: ID of the Task
"""
task = None
try:
task = task_repo.get(task_id)
except exception.NotFound:
msg = _LE('Task not found for task_id %s') % task_id
LOG.exception(msg)
return task
def unpack_task_input(task):
"""Verifies and returns valid task input dictionary.
:param task: Task domain object
"""
task_input = task.task_input
# NOTE: until we support multiple task types, we just check for
# input fields related to 'import task'.
for key in ["import_from", "import_from_format", "image_properties"]:
if key not in task_input:
msg = _("Input does not contain '%(key)s' field") % {"key": key}
raise exception.Invalid(msg)
return task_input
def set_base_image_properties(properties=None):
"""Sets optional base properties for creating Image.
:param properties: Input dict to set some base properties
"""
if isinstance(properties, dict) and len(properties) == 0:
# TODO(nikhil): We can make these properties configurable while
# implementing the pipeline logic for the scripts. The below shown
# are placeholders to show that the scripts work on 'devstack'
# environment.
properties['disk_format'] = 'qcow2'
properties['container_format'] = 'bare'
def validate_location_uri(location):
"""Validate location uri into acceptable format.
:param location: Location uri to be validated
"""
if not location:
raise exception.BadStoreUri(_('Invalid location: %s') % location)
elif location.startswith(('http://', 'https://')):
return location
# NOTE: file type uri is being avoided for security reasons,
# see LP bug #942118 #1400966.
elif location.startswith(("file:///", "filesystem:///")):
msg = _("File based imports are not allowed. Please use a non-local "
"source of image data.")
# NOTE: raise Exception and let the encompassing block save
# the error msg in the task.message.
raise Exception(msg)
else:
# TODO(nikhil): add other supported uris
supported = ['http', ]
msg = _("The given uri is not valid. Please specify a "
"valid uri from the following list of supported uri "
"%(supported)s") % {'supported': supported}
raise urllib2.URLError(msg)
def get_image_data_iter(uri):
"""Returns iterable object either for local file or uri
:param uri: uri (remote or local) to the datasource we want to iterate
Validation/sanitization of the uri is expected to happen before we get
here.
"""
# NOTE(flaper87): This is safe because the input uri is already
# verified before the task is created.
if uri.startswith("file://"):
uri = uri.split("file://")[-1]
# NOTE(flaper87): The caller of this function expects to have
# an iterable object. FileObjects in python are iterable, therefore
# we are returning it as is.
# The file descriptor will be eventually cleaned up by the garbage
# collector once its ref-count is dropped to 0. That is, when there
# wont be any references pointing to this file.
#
# We're not using StringIO or other tools to avoid reading everything
# into memory. Some images may be quite heavy.
return open(uri, "r")
return urllib2.urlopen(uri)

View File

@ -1,145 +0,0 @@
# Copyright (c) 2015 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import semantic_version
from daisy.common import exception
from daisy import i18n
MAX_COMPONENT_LENGTH = pow(2, 16) - 1
MAX_NUMERIC_PRERELEASE_LENGTH = 6
_ = i18n._
class DBVersion(object):
def __init__(self, components_long, prerelease, build):
"""
Creates a DBVersion object out of 3 component fields. This initializer
is supposed to be called from SQLAlchemy if 3 database columns are
mapped to this composite field.
:param components_long: a 64-bit long value, containing numeric
components of the version
:param prerelease: a prerelease label of the version, optionally
preformatted with leading zeroes in numeric-only parts of the label
:param build: a build label of the version
"""
version_string = '%s.%s.%s' % _long_to_components(components_long)
if prerelease:
version_string += '-' + _strip_leading_zeroes_from_prerelease(
prerelease)
if build:
version_string += '+' + build
self.version = semantic_version.Version(version_string)
def __repr__(self):
return str(self.version)
def __eq__(self, other):
return (isinstance(other, DBVersion) and
other.version == self.version)
def __ne__(self, other):
return (not isinstance(other, DBVersion) or
self.version != other.version)
def __composite_values__(self):
long_version = _version_to_long(self.version)
prerelease = _add_leading_zeroes_to_prerelease(self.version.prerelease)
build = '.'.join(self.version.build) if self.version.build else None
return long_version, prerelease, build
def parse(version_string):
version = semantic_version.Version.coerce(version_string)
return DBVersion(_version_to_long(version),
'.'.join(version.prerelease),
'.'.join(version.build))
def _check_limit(value):
if value > MAX_COMPONENT_LENGTH:
reason = _("Version component is too "
"large (%d max)") % MAX_COMPONENT_LENGTH
raise exception.InvalidVersion(reason=reason)
def _version_to_long(version):
"""
Converts the numeric part of the semver version into the 64-bit long value
using the following logic:
* major version is stored in first 16 bits of the value
* minor version is stored in next 16 bits
* patch version is stored in following 16 bits
* next 2 bits are used to store the flag: if the version has pre-release
label then these bits are 00, otherwise they are 11. Intermediate values
of the flag (01 and 10) are reserved for future usage.
* last 14 bits of the value are reserved fo future usage
The numeric components of version are checked so their value do not exceed
16 bits.
:param version: a semantic_version.Version object
"""
_check_limit(version.major)
_check_limit(version.minor)
_check_limit(version.patch)
major = version.major << 48
minor = version.minor << 32
patch = version.patch << 16
flag = 0 if version.prerelease else 2
flag <<= 14
return major | minor | patch | flag
def _long_to_components(value):
major = value >> 48
minor = (value - (major << 48)) >> 32
patch = (value - (major << 48) - (minor << 32)) >> 16
return str(major), str(minor), str(patch)
def _add_leading_zeroes_to_prerelease(label_tuple):
if label_tuple is None:
return None
res = []
for component in label_tuple:
if component.isdigit():
if len(component) > MAX_NUMERIC_PRERELEASE_LENGTH:
reason = _("Prerelease numeric component is too large "
"(%d characters "
"max)") % MAX_NUMERIC_PRERELEASE_LENGTH
raise exception.InvalidVersion(reason=reason)
res.append(component.rjust(MAX_NUMERIC_PRERELEASE_LENGTH, '0'))
else:
res.append(component)
return '.'.join(res)
def _strip_leading_zeroes_from_prerelease(string_value):
res = []
for component in string_value.split('.'):
if component.isdigit():
val = component.lstrip('0')
if len(val) == 0: # Corner case: when the component is just '0'
val = '0' # it will be stripped completely, so restore it
res.append(val)
else:
res.append(component)
return '.'.join(res)

View File

@ -1,104 +0,0 @@
# Copyright 2014 Rackspace
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import ConfigParser
try:
from collections import OrderedDict
except ImportError:
from ordereddict import OrderedDict
from oslo_config import cfg
from oslo_log import log as logging
from daisy.common import exception
from daisy import i18n
_ = i18n._
_LE = i18n._LE
swift_opts = [
cfg.StrOpt('default_swift_reference',
default="ref1",
help=_('The reference to the default swift account/backing '
'store parameters to use for adding new images.')),
cfg.StrOpt('swift_store_auth_address',
help=_('The address where the Swift authentication service '
'is listening.(deprecated)')),
cfg.StrOpt('swift_store_user', secret=True,
help=_('The user to authenticate against the Swift '
'authentication service (deprecated)')),
cfg.StrOpt('swift_store_key', secret=True,
help=_('Auth key for the user authenticating against the '
'Swift authentication service. (deprecated)')),
cfg.StrOpt('swift_store_config_file', secret=True,
help=_('The config file that has the swift account(s)'
'configs.')),
]
# NOTE(bourke): The default dict_type is collections.OrderedDict in py27, but
# we must set manually for compatibility with py26
CONFIG = ConfigParser.SafeConfigParser(dict_type=OrderedDict)
LOG = logging.getLogger(__name__)
CONF = cfg.CONF
CONF.register_opts(swift_opts)
def is_multiple_swift_store_accounts_enabled():
if CONF.swift_store_config_file is None:
return False
return True
class SwiftParams(object):
def __init__(self):
if is_multiple_swift_store_accounts_enabled():
self.params = self._load_config()
else:
self.params = self._form_default_params()
def _form_default_params(self):
default = {}
if (CONF.swift_store_user and CONF.swift_store_key and
CONF.swift_store_auth_address):
default['user'] = CONF.swift_store_user
default['key'] = CONF.swift_store_key
default['auth_address'] = CONF.swift_store_auth_address
return {CONF.default_swift_reference: default}
return {}
def _load_config(self):
try:
conf_file = CONF.find_file(CONF.swift_store_config_file)
CONFIG.read(conf_file)
except Exception as e:
msg = (_LE("swift config file %(conf_file)s:%(exc)s not found") %
{'conf_file': CONF.swift_store_config_file, 'exc': e})
LOG.error(msg)
raise exception.InvalidSwiftStoreConfiguration()
account_params = {}
account_references = CONFIG.sections()
for ref in account_references:
reference = {}
try:
reference['auth_address'] = CONFIG.get(ref, 'auth_address')
reference['user'] = CONFIG.get(ref, 'user')
reference['key'] = CONFIG.get(ref, 'key')
account_params[ref] = reference
except (ValueError, SyntaxError, ConfigParser.NoOptionError) as e:
LOG.exception(_LE("Invalid format of swift store config "
"cfg"))
return account_params

View File

@ -1,70 +0,0 @@
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from datetime import datetime
from oslo_utils import timeutils
from wsme import types as wsme_types
class WSMEModelTransformer(object):
def to_dict(self):
# Return the wsme_attributes names:values as a dict
my_dict = {}
for attribute in self._wsme_attributes:
value = getattr(self, attribute.name)
if value is not wsme_types.Unset:
my_dict.update({attribute.name: value})
return my_dict
@classmethod
def to_wsme_model(model, db_entity, self_link=None, schema=None):
# Return the wsme_attributes names:values as a dict
names = []
for attribute in model._wsme_attributes:
names.append(attribute.name)
values = {}
for name in names:
value = getattr(db_entity, name, None)
if value is not None:
if isinstance(value, datetime):
iso_datetime_value = timeutils.isotime(value)
values.update({name: iso_datetime_value})
else:
values.update({name: value})
if schema:
values['schema'] = schema
model_object = model(**values)
# 'self' kwarg is used in wsme.types.Base.__init__(self, ..) and
# conflicts during initialization. self_link is a proxy field to self.
if self_link:
model_object.self = self_link
return model_object
@classmethod
def get_mandatory_attrs(cls):
return [attr.name for attr in cls._wsme_attributes if attr.mandatory]
def _get_value(obj):
if obj is not wsme_types.Unset:
return obj
else:
return None

View File

@ -1,58 +0,0 @@
..
Copyright 2015 OpenStack Foundation
All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may
not use this file except in compliance with the License. You may obtain
a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations
under the License.
==================
Basic architecture
==================
OpenStack Glance has a client-server architecture and provides a user
REST API through which requests to the server are performed.
Internal server operations are managed by a Glance Domain Controller
divided into layers. Each layer implements its own task.
All the files operations are performed using glance_store library
which is responsible for interaction with external storage back ends or
local filesystem, and provides a uniform interface to access.
Glance uses an sql-based central database (Glance DB) that is shared
with all the components in the system.
.. figure:: /images/architecture.png
:figwidth: 100%
:align: center
:alt: OpenStack Glance Architecture
.. centered:: Image 1. OpenStack Glance Architecture
The Glance architecture consists of several components:
* **A client** — any application that uses Glance server.
* **REST API** — exposes Glance functionality via REST.
* **Database Abstraction Layer (DAL)** — an application programming interface
which unifies the communication between Glance and databases.
* **Glance Domain Controller** — middleware that implements the main
Glance functionalities: authorization, notifications, policies,
database connections.
* **Glance Store** — organizes interactions between Glance and various
data stores.
* **Registry Layer** — optional layer organizing secure communication between
the domain and the DAL by using a separate service.

View File

@ -1,107 +0,0 @@
..
Copyright 2010 OpenStack Foundation
All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may
not use this file except in compliance with the License. You may obtain
a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations
under the License.
Authentication With Keystone
============================
Glance may optionally be integrated with Keystone. Setting this up is
relatively straightforward, as the Keystone distribution includes the
necessary middleware. Once you have installed Keystone
and edited your configuration files, newly created images will have
their `owner` attribute set to the tenant of the authenticated users,
and the `is_public` attribute will cause access to those images for
which it is `false` to be restricted to only the owner, users with
admin context, or tenants/users with whom the image has been shared.
Configuring the Glance servers to use Keystone
----------------------------------------------
Keystone is integrated with Glance through the use of middleware. The
default configuration files for both the Glance API and the Glance
Registry use a single piece of middleware called ``unauthenticated-context``,
which generates a request context containing blank authentication
information. In order to configure Glance to use Keystone, the
``authtoken`` and ``context`` middlewares must be deployed in place of the
``unauthenticated-context`` middleware. The ``authtoken`` middleware performs
the authentication token validation and retrieves actual user authentication
information. It can be found in the Keystone distribution.
Configuring Glance API to use Keystone
--------------------------------------
Configuring Glance API to use Keystone is relatively straight
forward. The first step is to ensure that declarations for the two
pieces of middleware exist in the ``glance-api-paste.ini``. Here is
an example for ``authtoken``::
[filter:authtoken]
paste.filter_factory = keystonemiddleware.auth_token:filter_factory
identity_uri = http://127.0.0.1:35357
admin_user = glance_admin
admin_tenant_name = service_admins
admin_password = password1234
The actual values for these variables will need to be set depending on
your situation. For more information, please refer to the Keystone
documentation on the ``auth_token`` middleware, but in short:
* The ``identity_uri`` variable points to the Keystone Admin service.
This information is used by the middleware to actually query Keystone about
the validity of the authentication tokens.
* The admin auth credentials (``admin_user``, ``admin_tenant_name``,
``admin_password``) will be used to retrieve an admin token. That
token will be used to authorize user tokens behind the scenes.
Finally, to actually enable using Keystone authentication, the
application pipeline must be modified. By default, it looks like::
[pipeline:glance-api]
pipeline = versionnegotiation unauthenticated-context apiv1app
Your particular pipeline may vary depending on other options, such as
the image cache. This must be changed by replacing ``unauthenticated-context``
with ``authtoken`` and ``context``::
[pipeline:glance-api]
pipeline = versionnegotiation authtoken context apiv1app
Configuring Glance Registry to use Keystone
-------------------------------------------
Configuring Glance Registry to use Keystone is also relatively
straight forward. The same middleware needs to be added
to ``glance-registry-paste.ini`` as was needed by Glance API;
see above for an example of the ``authtoken`` configuration.
Again, to enable using Keystone authentication, the appropriate
application pipeline must be selected. By default, it looks like::
[pipeline:glance-registry-keystone]
pipeline = authtoken context registryapp
To enable the above application pipeline, in your main ``glance-registry.conf``
configuration file, select the appropriate deployment flavor by adding a
``flavor`` attribute in the ``paste_deploy`` group::
[paste_deploy]
flavor = keystone
.. note::
If your authentication service uses a role other than ``admin`` to identify
which users should be granted admin-level privileges, you must define it
in the ``admin_role`` config attribute in both ``glance-registry.conf`` and
``glance-api.conf``.

View File

@ -1,130 +0,0 @@
..
Copyright 2011 OpenStack Foundation
All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may
not use this file except in compliance with the License. You may obtain
a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations
under the License.
The Glance Image Cache
======================
The Glance API server may be configured to have an optional local image cache.
A local image cache stores a copy of image files, essentially enabling multiple
API servers to serve the same image file, resulting in an increase in
scalability due to an increased number of endpoints serving an image file.
This local image cache is transparent to the end user -- in other words, the
end user doesn't know that the Glance API is streaming an image file from
its local cache or from the actual backend storage system.
Managing the Glance Image Cache
-------------------------------
While image files are automatically placed in the image cache on successful
requests to ``GET /images/<IMAGE_ID>``, the image cache is not automatically
managed. Here, we describe the basics of how to manage the local image cache
on Glance API servers and how to automate this cache management.
Controlling the Growth of the Image Cache
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The image cache has a configurable maximum size (the ``image_cache_max_size``
configuration file option). The ``image_cache_max_size`` is an upper limit
beyond which pruner, if running, starts cleaning the images cache.
However, when images are successfully returned from a call to
``GET /images/<IMAGE_ID>``, the image cache automatically writes the image
file to its cache, regardless of whether the resulting write would make the
image cache's size exceed the value of ``image_cache_max_size``.
In order to keep the image cache at or below this maximum cache size,
you need to run the ``glance-cache-pruner`` executable.
The recommended practice is to use ``cron`` to fire ``glance-cache-pruner``
at a regular interval.
Cleaning the Image Cache
~~~~~~~~~~~~~~~~~~~~~~~~
Over time, the image cache can accumulate image files that are either in
a stalled or invalid state. Stalled image files are the result of an image
cache write failing to complete. Invalid image files are the result of an
image file not being written properly to disk.
To remove these types of files, you run the ``glance-cache-cleaner``
executable.
The recommended practice is to use ``cron`` to fire ``glance-cache-cleaner``
at a semi-regular interval.
Prefetching Images into the Image Cache
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Some installations have base (sometimes called "golden") images that are
very commonly used to boot virtual machines. When spinning up a new API
server, administrators may wish to prefetch these image files into the
local image cache to ensure that reads of those popular image files come
from a local cache.
To queue an image for prefetching, you can use one of the following methods:
* If the ``cache_manage`` middleware is enabled in the application pipeline,
you may call ``PUT /queued-images/<IMAGE_ID>`` to queue the image with
identifier ``<IMAGE_ID>``
Alternately, you can use the ``glance-cache-manage`` program to queue the
image. This program may be run from a different host than the host
containing the image cache. Example usage::
$> glance-cache-manage --host=<HOST> queue-image <IMAGE_ID>
This will queue the image with identifier ``<IMAGE_ID>`` for prefetching
Once you have queued the images you wish to prefetch, call the
``glance-cache-prefetcher`` executable, which will prefetch all queued images
concurrently, logging the results of the fetch for each image.
Finding Which Images are in the Image Cache
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can find out which images are in the image cache using one of the
following methods:
* If the ``cachemanage`` middleware is enabled in the application pipeline,
you may call ``GET /cached-images`` to see a JSON-serialized list of
mappings that show cached images, the number of cache hits on each image,
the size of the image, and the times they were last accessed.
Alternately, you can use the ``glance-cache-manage`` program. This program
may be run from a different host than the host containing the image cache.
Example usage::
$> glance-cache-manage --host=<HOST> list-cached
* You can issue the following call on \*nix systems (on the host that contains
the image cache)::
$> ls -lhR $IMAGE_CACHE_DIR
where ``$IMAGE_CACHE_DIR`` is the value of the ``image_cache_dir``
configuration variable.
Note that the image's cache hit is not shown using this method.
Manually Removing Images from the Image Cache
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If the ``cachemanage`` middleware is enabled, you may call
``DELETE /cached-images/<IMAGE_ID>`` to remove the image file for image
with identifier ``<IMAGE_ID>`` from the cache.
Alternately, you can use the ``glance-cache-manage`` program. Example usage::
$> glance-cache-manage --host=<HOST> delete-cached-image <IMAGE_ID>

View File

@ -1,227 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2010 OpenStack Foundation.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Glance documentation build configuration file, created by
# sphinx-quickstart on Tue May 18 13:50:15 2010.
#
# This file is execfile()'d with the current directory set to its containing
# dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
import os
import sys
from daisy.version import version_info as daisy_version
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
sys.path = [os.path.abspath('../..'), os.path.abspath('../../bin')] + sys.path
# -- General configuration ---------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = ['sphinx.ext.coverage',
'sphinx.ext.ifconfig',
'sphinx.ext.pngmath',
'sphinx.ext.graphviz',
'oslosphinx',
]
# Add any paths that contain templates here, relative to this directory.
# templates_path = []
# The suffix of source filenames.
source_suffix = '.rst'
# The encoding of source files.
# source_encoding = 'utf-8'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'Glance'
copyright = u'2010-2014, OpenStack Foundation.'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
# The full version, including alpha/beta/rc tags.
release = daisy_version.version_string_with_vcs()
# The short X.Y version.
version = daisy_version.canonical_version_string()
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
# language = None
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
# today = ''
# Else, today_fmt is used as the format for a strftime call.
# today_fmt = '%B %d, %Y'
# List of documents that shouldn't be included in the build.
# unused_docs = []
# List of directories, relative to source directory, that shouldn't be searched
# for source files.
exclude_trees = ['api']
# The reST default role (for this markup: `text`) to use for all documents.
# default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
# add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
# add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
show_authors = True
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# A list of ignored prefixes for module index sorting.
modindex_common_prefix = ['glance.']
# -- Options for man page output --------------------------------------------
# Grouping the document tree for man pages.
# List of tuples 'sourcefile', 'target', u'title', u'Authors name', 'manual'
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. Major themes that come with
# Sphinx are currently 'default' and 'sphinxdoc'.
# html_theme_path = ["."]
# html_theme = '_theme'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
# html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory.
# html_theme_path = ['_theme']
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
# html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
# html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
# html_logo = None
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
# html_favicon = None
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
# html_last_updated_fmt = '%b %d, %Y'
git_cmd = "git log --pretty=format:'%ad, commit %h' --date=local -n1"
html_last_updated_fmt = os.popen(git_cmd).read()
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
# html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
# html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
# html_additional_pages = {}
# If false, no module index is generated.
html_use_modindex = False
# If false, no index is generated.
html_use_index = False
# If true, the index is split into individual pages for each letter.
# html_split_index = False
# If true, links to the reST sources are added to the pages.
# html_show_sourcelink = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
# html_use_opensearch = ''
# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
# html_file_suffix = ''
# Output file base name for HTML help builder.
htmlhelp_basename = 'glancedoc'
# -- Options for LaTeX output ------------------------------------------------
# The paper size ('letter' or 'a4').
# latex_paper_size = 'letter'
# The font size ('10pt', '11pt' or '12pt').
# latex_font_size = '10pt'
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author,
# documentclass [howto/manual]).
latex_documents = [
('index', 'Glance.tex', u'Glance Documentation',
u'Glance Team', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
# latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
# latex_use_parts = False
# Additional stuff for the LaTeX preamble.
# latex_preamble = ''
# Documents to append as an appendix to all manuals.
# latex_appendices = []
# If false, no module index is generated.
# latex_use_modindex = True

File diff suppressed because it is too large Load Diff

View File

@ -1,237 +0,0 @@
..
Copyright 2011 OpenStack Foundation
All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may
not use this file except in compliance with the License. You may obtain
a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations
under the License.
Controlling Glance Servers
==========================
This section describes the ways to start, stop, and reload Glance's server
programs.
Starting a server
-----------------
There are two ways to start a Glance server (either the API server or the
registry server):
* Manually calling the server program
* Using the ``glance-control`` server daemon wrapper program
We recommend using the second method.
Manually starting the server
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The first is by directly calling the server program, passing in command-line
options and a single argument for a ``paste.deploy`` configuration file to
use when configuring the server application.
.. note::
Glance ships with an ``etc/`` directory that contains sample ``paste.deploy``
configuration files that you can copy to a standard configuation directory and
adapt for your own uses. Specifically, bind_host must be set properly.
If you do `not` specify a configuration file on the command line, Glance will
do its best to locate a configuration file in one of the
following directories, stopping at the first config file it finds:
* ``$CWD``
* ``~/.glance``
* ``~/``
* ``/etc/glance``
* ``/etc``
The filename that is searched for depends on the server application name. So,
if you are starting up the API server, ``glance-api.conf`` is searched for,
otherwise ``glance-registry.conf``.
If no configuration file is found, you will see an error, like::
$> glance-api
ERROR: Unable to locate any configuration file. Cannot load application glance-api
Here is an example showing how you can manually start the ``glance-api`` server and ``glance-registry`` in a shell.::
$ sudo glance-api --config-file glance-api.conf --debug &
jsuh@mc-ats1:~$ 2011-04-13 14:50:12 DEBUG [glance-api] ********************************************************************************
2011-04-13 14:50:12 DEBUG [glance-api] Configuration options gathered from config file:
2011-04-13 14:50:12 DEBUG [glance-api] /home/jsuh/glance-api.conf
2011-04-13 14:50:12 DEBUG [glance-api] ================================================
2011-04-13 14:50:12 DEBUG [glance-api] bind_host 65.114.169.29
2011-04-13 14:50:12 DEBUG [glance-api] bind_port 9292
2011-04-13 14:50:12 DEBUG [glance-api] debug True
2011-04-13 14:50:12 DEBUG [glance-api] default_store file
2011-04-13 14:50:12 DEBUG [glance-api] filesystem_store_datadir /home/jsuh/images/
2011-04-13 14:50:12 DEBUG [glance-api] registry_host 65.114.169.29
2011-04-13 14:50:12 DEBUG [glance-api] registry_port 9191
2011-04-13 14:50:12 DEBUG [glance-api] verbose False
2011-04-13 14:50:12 DEBUG [glance-api] ********************************************************************************
2011-04-13 14:50:12 DEBUG [routes.middleware] Initialized with method overriding = True, and path info altering = True
2011-04-13 14:50:12 DEBUG [eventlet.wsgi.server] (21354) wsgi starting up on http://65.114.169.29:9292/
$ sudo glance-registry --config-file glance-registry.conf &
jsuh@mc-ats1:~$ 2011-04-13 14:51:16 INFO [sqlalchemy.engine.base.Engine.0x...feac] PRAGMA table_info("images")
2011-04-13 14:51:16 INFO [sqlalchemy.engine.base.Engine.0x...feac] ()
2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Col ('cid', 'name', 'type', 'notnull', 'dflt_value', 'pk')
2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (0, u'created_at', u'DATETIME', 1, None, 0)
2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (1, u'updated_at', u'DATETIME', 0, None, 0)
2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (2, u'deleted_at', u'DATETIME', 0, None, 0)
2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (3, u'deleted', u'BOOLEAN', 1, None, 0)
2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (4, u'id', u'INTEGER', 1, None, 1)
2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (5, u'name', u'VARCHAR(255)', 0, None, 0)
2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (6, u'disk_format', u'VARCHAR(20)', 0, None, 0)
2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (7, u'container_format', u'VARCHAR(20)', 0, None, 0)
2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (8, u'size', u'INTEGER', 0, None, 0)
2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (9, u'status', u'VARCHAR(30)', 1, None, 0)
2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (10, u'is_public', u'BOOLEAN', 1, None, 0)
2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (11, u'location', u'TEXT', 0, None, 0)
2011-04-13 14:51:16 INFO [sqlalchemy.engine.base.Engine.0x...feac] PRAGMA table_info("image_properties")
2011-04-13 14:51:16 INFO [sqlalchemy.engine.base.Engine.0x...feac] ()
2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Col ('cid', 'name', 'type', 'notnull', 'dflt_value', 'pk')
2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (0, u'created_at', u'DATETIME', 1, None, 0)
2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (1, u'updated_at', u'DATETIME', 0, None, 0)
2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (2, u'deleted_at', u'DATETIME', 0, None, 0)
2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (3, u'deleted', u'BOOLEAN', 1, None, 0)
2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (4, u'id', u'INTEGER', 1, None, 1)
2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (5, u'image_id', u'INTEGER', 1, None, 0)
2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (6, u'key', u'VARCHAR(255)', 1, None, 0)
2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (7, u'value', u'TEXT', 0, None, 0)
$ ps aux | grep glance
root 20009 0.7 0.1 12744 9148 pts/1 S 12:47 0:00 /usr/bin/python /usr/bin/glance-api glance-api.conf --debug
root 20012 2.0 0.1 25188 13356 pts/1 S 12:47 0:00 /usr/bin/python /usr/bin/glance-registry glance-registry.conf
jsuh 20017 0.0 0.0 3368 744 pts/1 S+ 12:47 0:00 grep glance
Simply supply the configuration file as the parameter to the ``--config-file`` option
(the ``etc/glance-api.conf`` and ``etc/glance-registry.conf`` sample configuration
files were used in the above example) and then any other options
you want to use. (``--debug`` was used above to show some of the debugging
output that the server shows when starting up. Call the server program
with ``--help`` to see all available options you can specify on the
command line.)
For more information on configuring the server via the ``paste.deploy``
configuration files, see the section entitled
:doc:`Configuring Glance servers <configuring>`
Note that the server `daemonizes` itself by using the standard
shell backgrounding indicator, ``&``, in the previous example. For most use cases, we recommend
using the ``glance-control`` server daemon wrapper for daemonizing. See below
for more details on daemonization with ``glance-control``.
Using the ``glance-control`` program to start the server
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The second way to start up a Glance server is to use the ``glance-control``
program. ``glance-control`` is a wrapper script that allows the user to
start, stop, restart, and reload the other Glance server programs in
a fashion that is more conducive to automation and scripting.
Servers started via the ``glance-control`` program are always `daemonized`,
meaning that the server program process runs in the background.
To start a Glance server with ``glance-control``, simply call
``glance-control`` with a server and the word "start", followed by
any command-line options you wish to provide. Start the server with ``glance-control``
in the following way::
$> sudo glance-control [OPTIONS] <SERVER> start [CONFPATH]
.. note::
You must use the ``sudo`` program to run ``glance-control`` currently, as the
pid files for the server programs are written to /var/run/glance/
Here is an example that shows how to start the ``glance-registry`` server
with the ``glance-control`` wrapper script. ::
$ sudo glance-control api start glance-api.conf
Starting glance-api with /home/jsuh/glance.conf
$ sudo glance-control registry start glance-registry.conf
Starting glance-registry with /home/jsuh/glance.conf
$ ps aux | grep glance
root 20038 4.0 0.1 12728 9116 ? Ss 12:51 0:00 /usr/bin/python /usr/bin/glance-api /home/jsuh/glance-api.conf
root 20039 6.0 0.1 25188 13356 ? Ss 12:51 0:00 /usr/bin/python /usr/bin/glance-registry /home/jsuh/glance-registry.conf
jsuh 20042 0.0 0.0 3368 744 pts/1 S+ 12:51 0:00 grep glance
The same configuration files are used by ``glance-control`` to start the
Glance server programs, and you can specify (as the example above shows)
a configuration file when starting the server.
In order for your launched glance service to be monitored for unexpected death
and respawned if necessary, use the following option:
$ sudo glance-control [service] start --respawn ...
Note that this will cause ``glance-control`` itself to remain running. Also note
that deliberately stopped services are not respawned, neither are rapidly bouncing
services (where process death occurred within one second of the last launch).
By default, output from glance services is discarded when launched with ``glance-control``.
In order to capture such output via syslog, use the following option:
$ sudo glance-control --capture-output ...
Stopping a server
-----------------
If you started a Glance server manually and did not use the ``&`` backgrounding
function, simply send a terminate signal to the server process by typing
``Ctrl-C``
If you started the Glance server using the ``glance-control`` program, you can
use the ``glance-control`` program to stop it. Simply do the following::
$> sudo glance-control <SERVER> stop
as this example shows::
$> sudo glance-control registry stop
Stopping glance-registry pid: 17602 signal: 15
Restarting a server
-------------------
You can restart a server with the ``glance-control`` program, as demonstrated
here::
$> sudo glance-control registry restart etc/glance-registry.conf
Stopping glance-registry pid: 17611 signal: 15
Starting glance-registry with /home/jpipes/repos/glance/trunk/etc/glance-registry.conf
Reloading a server
-------------------
You can reload a server with the ``glance-control`` program, as demonstrated
here::
$> sudo glance-control api reload
Reloading glance-api (pid 18506) with signal(1)
A reload sends a SIGHUP signal to the master process and causes new configuration
settings to be picked up without any interruption to the running service (provided
neither bind_host or bind_port has changed).

View File

@ -1,711 +0,0 @@
..
Copyright 2010 OpenStack Foundation
All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may
not use this file except in compliance with the License. You may obtain
a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations
under the License.
Using Glance's Image Public APIs
================================
Glance fully implements versions 1.0, 1.1 and 2.0 of the OpenStack Images API.
The Images API specification is developed alongside Glance, but is not
considered part of the Glance project.
Authentication
--------------
Glance depends on Keystone and the OpenStack Identity API to handle
authentication of clients. You must obtain an authentication token from
Keystone using and send it along with all API requests to Glance through
the ``X-Auth-Token`` header. Glance will communicate back to Keystone to
verify the token validity and obtain your identity credentials.
See :doc:`authentication` for more information on integrating with Keystone.
Using v1.X
----------
For the purpose of examples, assume there is a Glance API server running
at the URL ``http://glance.example.com`` on the default port 80.
List Available Images
*********************
We want to see a list of available images that the authenticated user has
access to. This includes images owned by the user, images shared with the user
and public images.
We issue a ``GET`` request to ``http://glance.example.com/v1/images`` to
retrieve this list of available images. The data is returned as a JSON-encoded
mapping in the following format::
{'images': [
{'uri': 'http://glance.example.com/v1/images/71c675ab-d94f-49cd-a114-e12490b328d9',
'name': 'Ubuntu 10.04 Plain',
'disk_format': 'vhd',
'container_format': 'ovf',
'size': '5368709120'}
...]}
List Available Images in More Detail
************************************
We want to see a more detailed list of available images that the authenticated
user has access to. This includes images owned by the user, images shared with
the user and public images.
We issue a ``GET`` request to ``http://glance.example.com/v1/images/detail`` to
retrieve this list of available images. The data is returned as a
JSON-encoded mapping in the following format::
{'images': [
{'uri': 'http://glance.example.com/v1/images/71c675ab-d94f-49cd-a114-e12490b328d9',
'name': 'Ubuntu 10.04 Plain 5GB',
'disk_format': 'vhd',
'container_format': 'ovf',
'size': '5368709120',
'checksum': 'c2e5db72bd7fd153f53ede5da5a06de3',
'created_at': '2010-02-03 09:34:01',
'updated_at': '2010-02-03 09:34:01',
'deleted_at': '',
'status': 'active',
'is_public': true,
'min_ram': 256,
'min_disk': 5,
'owner': null,
'properties': {'distro': 'Ubuntu 10.04 LTS'}},
...]}
.. note::
All timestamps returned are in UTC
The `updated_at` timestamp is the timestamp when an image's metadata
was last updated, not its image data, as all image data is immutable
once stored in Glance
The `properties` field is a mapping of free-form key/value pairs that
have been saved with the image metadata
The `checksum` field is an MD5 checksum of the image file data
The `is_public` field is a boolean indicating whether the image is
publicly available
The `min_ram` field is an integer specifying the minimum amount of
ram needed to run this image on an instance, in megabytes
The `min_disk` field is an integer specifying the minimum amount of
disk space needed to run this image on an instance, in gigabytes
The `owner` field is a string which may either be null or which will
indicate the owner of the image
Filtering Images Lists
**********************
Both the ``GET /v1/images`` and ``GET /v1/images/detail`` requests take query
parameters that serve to filter the returned list of images. The following
list details these query parameters.
* ``name=NAME``
Filters images having a ``name`` attribute matching ``NAME``.
* ``container_format=FORMAT``
Filters images having a ``container_format`` attribute matching ``FORMAT``
For more information, see :doc:`About Disk and Container Formats <formats>`
* ``disk_format=FORMAT``
Filters images having a ``disk_format`` attribute matching ``FORMAT``
For more information, see :doc:`About Disk and Container Formats <formats>`
* ``status=STATUS``
Filters images having a ``status`` attribute matching ``STATUS``
For more information, see :doc:`About Image Statuses <statuses>`
* ``size_min=BYTES``
Filters images having a ``size`` attribute greater than or equal to ``BYTES``
* ``size_max=BYTES``
Filters images having a ``size`` attribute less than or equal to ``BYTES``
These two resources also accept additional query parameters:
* ``sort_key=KEY``
Results will be ordered by the specified image attribute ``KEY``. Accepted
values include ``id``, ``name``, ``status``, ``disk_format``,
``container_format``, ``size``, ``created_at`` (default) and ``updated_at``.
* ``sort_dir=DIR``
Results will be sorted in the direction ``DIR``. Accepted values are ``asc``
for ascending or ``desc`` (default) for descending.
* ``marker=ID``
An image identifier marker may be specified. When present only images which
occur after the identifier ``ID`` will be listed, i.e. the images which have
a `sort_key` later than that of the marker ``ID`` in the `sort_dir` direction.
* ``limit=LIMIT``
When present the maximum number of results returned will not exceed ``LIMIT``.
.. note::
If the specified ``LIMIT`` exceeds the operator defined limit (api_limit_max)
then the number of results returned may be less than ``LIMIT``.
* ``is_public=PUBLIC``
An admin user may use the `is_public` parameter to control which results are
returned.
When the `is_public` parameter is absent or set to `True` the following images
will be listed: Images whose `is_public` field is `True`, owned images and
shared images.
When the `is_public` parameter is set to `False` the following images will be
listed: Images (owned, shared, or non-owned) whose `is_public` field is `False`.
When the `is_public` parameter is set to `None` all images will be listed
irrespective of owner, shared status or the `is_public` field.
.. note::
Use of the `is_public` parameter is restricted to admin users. For all other
users it will be ignored.
Retrieve Image Metadata
***********************
We want to see detailed information for a specific virtual machine image
that the Glance server knows about.
We have queried the Glance server for a list of images and the
data returned includes the `uri` field for each available image. This
`uri` field value contains the exact location needed to get the metadata
for a specific image.
Continuing the example from above, in order to get metadata about the
first image returned, we can issue a ``HEAD`` request to the Glance
server for the image's URI.
We issue a ``HEAD`` request to
``http://glance.example.com/v1/images/71c675ab-d94f-49cd-a114-e12490b328d9`` to
retrieve complete metadata for that image. The metadata is returned as a
set of HTTP headers that begin with the prefix ``x-image-meta-``. The
following shows an example of the HTTP headers returned from the above
``HEAD`` request::
x-image-meta-uri http://glance.example.com/v1/images/71c675ab-d94f-49cd-a114-e12490b328d9
x-image-meta-name Ubuntu 10.04 Plain 5GB
x-image-meta-disk_format vhd
x-image-meta-container_format ovf
x-image-meta-size 5368709120
x-image-meta-checksum c2e5db72bd7fd153f53ede5da5a06de3
x-image-meta-created_at 2010-02-03 09:34:01
x-image-meta-updated_at 2010-02-03 09:34:01
x-image-meta-deleted_at
x-image-meta-status available
x-image-meta-is_public true
x-image-meta-min_ram 256
x-image-meta-min_disk 0
x-image-meta-owner null
x-image-meta-property-distro Ubuntu 10.04 LTS
.. note::
All timestamps returned are in UTC
The `x-image-meta-updated_at` timestamp is the timestamp when an
image's metadata was last updated, not its image data, as all
image data is immutable once stored in Glance
There may be multiple headers that begin with the prefix
`x-image-meta-property-`. These headers are free-form key/value pairs
that have been saved with the image metadata. The key is the string
after `x-image-meta-property-` and the value is the value of the header
The response's `ETag` header will always be equal to the
`x-image-meta-checksum` value
The response's `x-image-meta-is_public` value is a boolean indicating
whether the image is publicly available
The response's `x-image-meta-owner` value is a string which may either
be null or which will indicate the owner of the image
Retrieve Raw Image Data
***********************
We want to retrieve that actual raw data for a specific virtual machine image
that the Glance server knows about.
We have queried the Glance server for a list of images and the
data returned includes the `uri` field for each available image. This
`uri` field value contains the exact location needed to get the metadata
for a specific image.
Continuing the example from above, in order to get metadata about the
first image returned, we can issue a ``HEAD`` request to the Glance
server for the image's URI.
We issue a ``GET`` request to
``http://glance.example.com/v1/images/71c675ab-d94f-49cd-a114-e12490b328d9`` to
retrieve metadata for that image as well as the image itself encoded
into the response body.
The metadata is returned as a set of HTTP headers that begin with the
prefix ``x-image-meta-``. The following shows an example of the HTTP headers
returned from the above ``GET`` request::
x-image-meta-uri http://glance.example.com/v1/images/71c675ab-d94f-49cd-a114-e12490b328d9
x-image-meta-name Ubuntu 10.04 Plain 5GB
x-image-meta-disk_format vhd
x-image-meta-container_format ovf
x-image-meta-size 5368709120
x-image-meta-checksum c2e5db72bd7fd153f53ede5da5a06de3
x-image-meta-created_at 2010-02-03 09:34:01
x-image-meta-updated_at 2010-02-03 09:34:01
x-image-meta-deleted_at
x-image-meta-status available
x-image-meta-is_public true
x-image-meta-min_ram 256
x-image-meta-min_disk 5
x-image-meta-owner null
x-image-meta-property-distro Ubuntu 10.04 LTS
.. note::
All timestamps returned are in UTC
The `x-image-meta-updated_at` timestamp is the timestamp when an
image's metadata was last updated, not its image data, as all
image data is immutable once stored in Glance
There may be multiple headers that begin with the prefix
`x-image-meta-property-`. These headers are free-form key/value pairs
that have been saved with the image metadata. The key is the string
after `x-image-meta-property-` and the value is the value of the header
The response's `Content-Length` header shall be equal to the value of
the `x-image-meta-size` header
The response's `ETag` header will always be equal to the
`x-image-meta-checksum` value
The response's `x-image-meta-is_public` value is a boolean indicating
whether the image is publicly available
The response's `x-image-meta-owner` value is a string which may either
be null or which will indicate the owner of the image
The image data itself will be the body of the HTTP response returned
from the request, which will have content-type of
`application/octet-stream`.
Add a New Image
***************
We have created a new virtual machine image in some way (created a
"golden image" or snapshotted/backed up an existing image) and we
wish to do two things:
* Store the disk image data in Glance
* Store metadata about this image in Glance
We can do the above two activities in a single call to the Glance API.
Assuming, like in the examples above, that a Glance API server is running
at ``glance.example.com``, we issue a ``POST`` request to add an image to
Glance::
POST http://glance.example.com/v1/images
The metadata about the image is sent to Glance in HTTP headers. The body
of the HTTP request to the Glance API will be the MIME-encoded disk
image data.
Reserve a New Image
*******************
We can also perform the activities described in `Add a New Image`_ using two
separate calls to the Image API; the first to register the image metadata, and
the second to add the image disk data. This is known as "reserving" an image.
The first call should be a ``POST`` to ``http://glance.example.com/v1/images``,
which will result in a new image id being registered with a status of
``queued``::
{"image":
{"status": "queued",
"id": "71c675ab-d94f-49cd-a114-e12490b328d9",
...}
...}
The image data can then be added using a ``PUT`` to
``http://glance.example.com/v1/images/71c675ab-d94f-49cd-a114-e12490b328d9``.
The image status will then be set to ``active`` by Glance.
**Image Metadata in HTTP Headers**
Glance will view as image metadata any HTTP header that it receives in a
``POST`` request where the header key is prefixed with the strings
``x-image-meta-`` and ``x-image-meta-property-``.
The list of metadata headers that Glance accepts are listed below.
* ``x-image-meta-name``
This header is required, unless reserving an image. Its value should be the
name of the image.
Note that the name of an image *is not unique to a Glance node*. It
would be an unrealistic expectation of users to know all the unique
names of all other user's images.
* ``x-image-meta-id``
This header is optional.
When present, Glance will use the supplied identifier for the image.
If the identifier already exists in that Glance node, then a
**409 Conflict** will be returned by Glance. The value of the header
must be an uuid in hexadecimal string notation
(i.e. 71c675ab-d94f-49cd-a114-e12490b328d9).
When this header is *not* present, Glance will generate an identifier
for the image and return this identifier in the response (see below)
* ``x-image-meta-store``
This header is optional. Valid values are one of ``file``, ``s3``, ``rbd``,
``swift``, ``cinder``, ``gridfs``, ``sheepdog`` or ``vsphere``
When present, Glance will attempt to store the disk image data in the
backing store indicated by the value of the header. If the Glance node
does not support the backing store, Glance will return a **400 Bad Request**.
When not present, Glance will store the disk image data in the backing
store that is marked default. See the configuration option ``default_store``
for more information.
* ``x-image-meta-disk_format``
This header is required, unless reserving an image. Valid values are one of
``aki``, ``ari``, ``ami``, ``raw``, ``iso``, ``vhd``, ``vdi``, ``qcow2``, or
``vmdk``.
For more information, see :doc:`About Disk and Container Formats <formats>`
* ``x-image-meta-container_format``
This header is required, unless reserving an image. Valid values are one of
``aki``, ``ari``, ``ami``, ``bare``, or ``ovf``.
For more information, see :doc:`About Disk and Container Formats <formats>`
* ``x-image-meta-size``
This header is optional.
When present, Glance assumes that the expected size of the request body
will be the value of this header. If the length in bytes of the request
body *does not match* the value of this header, Glance will return a
**400 Bad Request**.
When not present, Glance will calculate the image's size based on the size
of the request body.
* ``x-image-meta-checksum``
This header is optional. When present it shall be the expected **MD5**
checksum of the image file data.
When present, Glance will verify the checksum generated from the backend
store when storing your image against this value and return a
**400 Bad Request** if the values do not match.
* ``x-image-meta-is_public``
This header is optional.
When Glance finds the string "true" (case-insensitive), the image is marked as
a public image, meaning that any user may view its metadata and may read
the disk image from Glance.
When not present, the image is assumed to be *not public* and owned by
a user.
* ``x-image-meta-min_ram``
This header is optional. When present it shall be the expected minimum ram
required in megabytes to run this image on a server.
When not present, the image is assumed to have a minimum ram requirement of 0.
* ``x-image-meta-min_disk``
This header is optional. When present it shall be the expected minimum disk
space required in gigabytes to run this image on a server.
When not present, the image is assumed to have a minimum disk space requirement of 0.
* ``x-image-meta-owner``
This header is optional and only meaningful for admins.
Glance normally sets the owner of an image to be the tenant or user
(depending on the "owner_is_tenant" configuration option) of the
authenticated user issuing the request. However, if the authenticated user
has the Admin role, this default may be overridden by setting this header to
null or to a string identifying the owner of the image.
* ``x-image-meta-property-*``
When Glance receives any HTTP header whose key begins with the string prefix
``x-image-meta-property-``, Glance adds the key and value to a set of custom,
free-form image properties stored with the image. The key is the
lower-cased string following the prefix ``x-image-meta-property-`` with dashes
and punctuation replaced with underscores.
For example, if the following HTTP header were sent::
x-image-meta-property-distro Ubuntu 10.10
Then a key/value pair of "distro"/"Ubuntu 10.10" will be stored with the
image in Glance.
There is no limit on the number of free-form key/value attributes that can
be attached to the image. However, keep in mind that the 8K limit on the
size of all HTTP headers sent in a request will effectively limit the number
of image properties.
Update an Image
***************
Glance will view as image metadata any HTTP header that it receives in a
``PUT`` request where the header key is prefixed with the strings
``x-image-meta-`` and ``x-image-meta-property-``.
If an image was previously reserved, and thus is in the ``queued`` state, then
image data can be added by including it as the request body. If the image
already as data associated with it (e.g. not in the ``queued`` state), then
including a request body will result in a **409 Conflict** exception.
On success, the ``PUT`` request will return the image metadata encoded as HTTP
headers.
See more about image statuses here: :doc:`Image Statuses <statuses>`
List Image Memberships
**********************
We want to see a list of the other system tenants (or users, if
"owner_is_tenant" is False) that may access a given virtual machine image that
the Glance server knows about. We take the `uri` field of the image data,
append ``/members`` to it, and issue a ``GET`` request on the resulting URL.
Continuing from the example above, in order to get the memberships for the
first image returned, we can issue a ``GET`` request to the Glance
server for
``http://glance.example.com/v1/images/71c675ab-d94f-49cd-a114-e12490b328d9/members``
. What we will get back is JSON data such as the following::
{'members': [
{'member_id': 'tenant1',
'can_share': false}
...]}
The `member_id` field identifies a tenant with which the image is shared. If
that tenant is authorized to further share the image, the `can_share` field is
`true`.
List Shared Images
******************
We want to see a list of images which are shared with a given tenant. We issue
a ``GET`` request to ``http://glance.example.com/v1/shared-images/tenant1``. We
will get back JSON data such as the following::
{'shared_images': [
{'image_id': '71c675ab-d94f-49cd-a114-e12490b328d9',
'can_share': false}
...]}
The `image_id` field identifies an image shared with the tenant named by
*member_id*. If the tenant is authorized to further share the image, the
`can_share` field is `true`.
Add a Member to an Image
************************
We want to authorize a tenant to access a private image. We issue a ``PUT``
request to
``http://glance.example.com/v1/images/71c675ab-d94f-49cd-a114-e12490b328d9/members/tenant1``
. With no body, this will add the membership to the image, leaving existing
memberships unmodified and defaulting new memberships to have `can_share`
set to `false`. We may also optionally attach a body of the following form::
{'member':
{'can_share': true}
}
If such a body is provided, both existing and new memberships will have
`can_share` set to the provided value (either `true` or `false`). This query
will return a 204 ("No Content") status code.
Remove a Member from an Image
*****************************
We want to revoke a tenant's right to access a private image. We issue a
``DELETE`` request to ``http://glance.example.com/v1/images/1/members/tenant1``.
This query will return a 204 ("No Content") status code.
Replace a Membership List for an Image
**************************************
The full membership list for a given image may be replaced. We issue a ``PUT``
request to
``http://glance.example.com/v1/images/71c675ab-d94f-49cd-a114-e12490b328d9/members``
with a body of the following form::
{'memberships': [
{'member_id': 'tenant1',
'can_share': false}
...]}
All existing memberships which are not named in the replacement body are
removed, and those which are named have their `can_share` settings changed as
specified. (The `can_share` setting may be omitted, which will cause that
setting to remain unchanged in the existing memberships.) All new memberships
will be created, with `can_share` defaulting to `false` if it is not specified.
Image Membership Changes in Version 2.0
---------------------------------------
Version 2.0 of the Images API eliminates the ``can_share`` attribute of image
membership. In the version 2.0 model, image sharing is not transitive.
In version 2.0, image members have a ``status`` attribute that reflects how the
image should be treated with respect to that image member's image list.
* The ``status`` attribute may have one of three values: ``pending``,
``accepted``, or ``rejected``.
* By default, only those shared images with status ``accepted`` are included in
an image member's image-list.
* Only an image member may change his/her own membership status.
* Only an image owner may create members on an image. The status of a newly
created image member is ``pending``. The image owner cannot change the
status of a member.
Distinctions from Version 1.x API Calls
***************************************
* The response to a request to list the members of an image has changed.
call: ``GET`` on ``/v2/images/{imageId}/members``
response: see the JSON schema at ``/v2/schemas/members``
* The request body in the call to create an image member has changed.
call: ``POST`` to ``/v2/images/{imageId}/members``
request body::
{ "member": "<MEMBER_ID>" }
where the {memberId} is the tenant ID of the image member.
The member status of a newly created image member is ``pending``.
New API Calls
*************
* Change the status of an image member
call: ``PUT`` on ``/v2/images/{imageId}/members/{memberId}``
request body::
{ "status": "<STATUS_VALUE>" }
where <STATUS_VALUE> is one of ``pending``, ``accepted``, or ``rejected``.
The {memberId} is the tenant ID of the image member.
API Message Localization
---------------------------------------
Glance supports HTTP message localization. For example, an HTTP client can
receive API messages in Chinese even if the locale language of the server is
English.
How to use it
*************
To receive localized API messages, the HTTP client needs to specify the
**Accept-Language** header to indicate the language to use to translate the
message. For more info about Accept-Language, please refer http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
A typical curl API request will be like below::
curl -i -X GET -H 'Accept-Language: zh' -H 'Content-Type: application/json'
http://127.0.0.1:9292/v2/images/aaa
Then the response will be like the following::
HTTP/1.1 404 Not Found
Content-Length: 234
Content-Type: text/html; charset=UTF-8
X-Openstack-Request-Id: req-54d403a0-064e-4544-8faf-4aeef086f45a
Date: Sat, 22 Feb 2014 06:26:26 GMT
<html>
<head>
<title>404 Not Found</title>
</head>
<body>
<h1>404 Not Found</h1>
&#25214;&#19981;&#21040;&#20219;&#20309;&#20855;&#26377;&#26631;&#35782; aaa &#30340;&#26144;&#20687;<br /><br />
</body>
</html>
.. note::
Be sure there is the language package under /usr/share/locale-langpack/ on
the target Glance server.

View File

@ -1,26 +0,0 @@
..
Copyright 2011-2012 OpenStack Foundation
All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may
not use this file except in compliance with the License. You may obtain
a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations
under the License.
Using Glance's Client Tools
===========================
The command-line tool and python library for Glance are both installed
through the python-glanceclient project. Explore the following resources
for more information:
* `Official Docs <http://docs.openstack.org/developer/python-glanceclient/>`_
* `Pypi Page <http://pypi.python.org/pypi/python-glanceclient>`_
* `GitHub Project <http://github.com/openstack/python-glanceclient>`_

View File

@ -1,605 +0,0 @@
..
Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied.
See the License for the specific language governing permissions and
limitations under the License.
Using Glance's Metadata Definitions Catalog Public APIs
=======================================================
A common API hosted by the Glance service for vendors, admins, services, and
users to meaningfully define available key / value pair and tag metadata.
The intent is to enable better metadata collaboration across artifacts,
services, and projects for OpenStack users.
This is about the definition of the available metadata that can be used on
different types of resources (images, artifacts, volumes, flavors, aggregates,
etc). A definition includes the properties type, its key, it's description,
and it's constraints. This catalog will not store the values for specific
instance properties.
For example, a definition of a virtual CPU topology property for number of
cores will include the key to use, a description, and value constraints like
requiring it to be an integer. So, a user, potentially through Horizon, would
be able to search this catalog to list the available properties they can add to
a flavor or image. They will see the virtual CPU topology property in the list
and know that it must be an integer. In the Horizon example, when the user adds
the property, its key and value will be stored in the service that owns that
resource (Nova for flavors and in Glance for images).
Diagram: https://wiki.openstack.org/w/images/b/bb/Glance-Metadata-API.png
Glance Metadata Definitions Catalog implementation started with API version v2.
Authentication
--------------
Glance depends on Keystone and the OpenStack Identity API to handle
authentication of clients. You must obtain an authentication token from
Keystone send it along with all API requests to Glance through the
``X-Auth-Token`` header. Glance will communicate back to Keystone to verify
the token validity and obtain your identity credentials.
See :doc:`authentication` for more information on integrating with Keystone.
Using v2.X
----------
For the purpose of examples, assume there is a Glance API server running
at the URL ``http://glance.example.com`` on the default port 80.
List Available Namespaces
*************************
We want to see a list of available namespaces that the authenticated user
has access to. This includes namespaces owned by the user,
namespaces shared with the user and public namespaces.
We issue a ``GET`` request to ``http://glance.example.com/v2/metadefs/namespaces``
to retrieve this list of available namespaces.
The data is returned as a JSON-encoded mapping in the following format::
{
"namespaces": [
{
"namespace": "MyNamespace",
"display_name": "My User Friendly Namespace",
"description": "My description",
"visibility": "public",
"protected": true,
"owner": "The Test Owner",
"self": "/v2/metadefs/namespaces/MyNamespace",
"schema": "/v2/schemas/metadefs/namespace",
"created_at": "2014-08-28T17:13:06Z",
"updated_at": "2014-08-28T17:13:06Z",
"resource_type_associations": [
{
"name": "OS::Nova::Aggregate",
"created_at": "2014-08-28T17:13:06Z",
"updated_at": "2014-08-28T17:13:06Z"
},
{
"name": "OS::Nova::Flavor",
"prefix": "aggregate_instance_extra_specs:",
"created_at": "2014-08-28T17:13:06Z",
"updated_at": "2014-08-28T17:13:06Z"
}
]
}
],
"first": "/v2/metadefs/namespaces?sort_key=created_at&sort_dir=asc",
"schema": "/v2/schemas/metadefs/namespaces"
}
.. note::
Listing namespaces will only show the summary of each namespace including
counts and resource type associations. Detailed response including all its
objects definitions, property definitions etc. will only be available on
each individual GET namespace request.
Filtering Namespaces Lists
**************************
``GET /v2/metadefs/namespaces`` requests take query parameters that serve to
filter the returned list of namespaces. The following
list details these query parameters.
* ``resource_types=RESOURCE_TYPES``
Filters namespaces having a ``resource_types`` within the list of
comma separated ``RESOURCE_TYPES``.
GET resource also accepts additional query parameters:
* ``sort_key=KEY``
Results will be ordered by the specified sort attribute ``KEY``. Accepted
values include ``namespace``, ``created_at`` (default) and ``updated_at``.
* ``sort_dir=DIR``
Results will be sorted in the direction ``DIR``. Accepted values are ``asc``
for ascending or ``desc`` (default) for descending.
* ``marker=NAMESPACE``
A namespace identifier marker may be specified. When present only
namespaces which occur after the identifier ``NAMESPACE`` will be listed,
i.e. the namespaces which have a `sort_key` later than that of the marker
``NAMESPACE`` in the `sort_dir` direction.
* ``limit=LIMIT``
When present the maximum number of results returned will not exceed ``LIMIT``.
.. note::
If the specified ``LIMIT`` exceeds the operator defined limit (api_limit_max)
then the number of results returned may be less than ``LIMIT``.
* ``visibility=PUBLIC``
An admin user may use the `visibility` parameter to control which results are
returned (PRIVATE or PUBLIC).
Retrieve Namespace
******************
We want to see a more detailed information about a namespace that the
authenticated user has access to. The detail includes the properties, objects,
and resource type associations.
We issue a ``GET`` request to ``http://glance.example.com/v2/metadefs/namespaces/{namespace}``
to retrieve the namespace details.
The data is returned as a JSON-encoded mapping in the following format::
{
"namespace": "MyNamespace",
"display_name": "My User Friendly Namespace",
"description": "My description",
"visibility": "public",
"protected": true,
"owner": "The Test Owner",
"schema": "/v2/schemas/metadefs/namespace",
"resource_type_associations": [
{
"name": "OS::Glance::Image",
"prefix": "hw_",
"created_at": "2014-08-28T17:13:06Z",
"updated_at": "2014-08-28T17:13:06Z"
},
{
"name": "OS::Cinder::Volume",
"prefix": "hw_",
"properties_target": "image",
"created_at": "2014-08-28T17:13:06Z",
"updated_at": "2014-08-28T17:13:06Z"
},
{
"name": "OS::Nova::Flavor",
"prefix": "filter1:",
"created_at": "2014-08-28T17:13:06Z",
"updated_at": "2014-08-28T17:13:06Z"
}
],
"properties": {
"nsprop1": {
"title": "My namespace property1",
"description": "More info here",
"type": "boolean",
"default": true
},
"nsprop2": {
"title": "My namespace property2",
"description": "More info here",
"type": "string",
"default": "value1"
}
},
"objects": [
{
"name": "object1",
"description": "my-description",
"self": "/v2/metadefs/namespaces/MyNamespace/objects/object1",
"schema": "/v2/schemas/metadefs/object",
"created_at": "2014-08-28T17:13:06Z",
"updated_at": "2014-08-28T17:13:06Z",
"required": [],
"properties": {
"prop1": {
"title": "My object1 property1",
"description": "More info here",
"type": "array",
"items": {
"type": "string"
}
}
}
},
{
"name": "object2",
"description": "my-description",
"self": "/v2/metadefs/namespaces/MyNamespace/objects/object2",
"schema": "/v2/schemas/metadefs/object",
"created_at": "2014-08-28T17:13:06Z",
"updated_at": "2014-08-28T17:13:06Z",
"properties": {
"prop1": {
"title": "My object2 property1",
"description": "More info here",
"type": "integer",
"default": 20
}
}
}
]
}
Retrieve available Resource Types
*********************************
We want to see the list of all resource types that are available in Glance
We issue a ``GET`` request to ``http://glance.example.com/v2/metadefs/resource_types``
to retrieve all resource types.
The data is returned as a JSON-encoded mapping in the following format::
{
"resource_types": [
{
"created_at": "2014-08-28T17:13:04Z",
"name": "OS::Glance::Image",
"updated_at": "2014-08-28T17:13:04Z"
},
{
"created_at": "2014-08-28T17:13:04Z",
"name": "OS::Cinder::Volume",
"updated_at": "2014-08-28T17:13:04Z"
},
{
"created_at": "2014-08-28T17:13:04Z",
"name": "OS::Nova::Flavor",
"updated_at": "2014-08-28T17:13:04Z"
},
{
"created_at": "2014-08-28T17:13:04Z",
"name": "OS::Nova::Aggregate",
"updated_at": "2014-08-28T17:13:04Z"
},
{
"created_at": "2014-08-28T17:13:04Z",
"name": "OS::Nova::Instance",
"updated_at": "2014-08-28T17:13:04Z"
}
]
}
Retrieve Resource Types associated with a Namespace
***************************************************
We want to see the list of resource types that are associated for a specific
namespace
We issue a ``GET`` request to ``http://glance.example.com/v2/metadefs/namespaces/{namespace}/resource_types``
to retrieve resource types.
The data is returned as a JSON-encoded mapping in the following format::
{
"resource_type_associations" : [
{
"name" : "OS::Glance::Image",
"prefix" : "hw_",
"created_at": "2014-08-28T17:13:04Z",
"updated_at": "2014-08-28T17:13:04Z"
},
{
"name" :"OS::Cinder::Volume",
"prefix" : "hw_",
"properties_target" : "image",
"created_at": "2014-08-28T17:13:04Z",
"updated_at": "2014-08-28T17:13:04Z"
},
{
"name" : "OS::Nova::Flavor",
"prefix" : "hw:",
"created_at": "2014-08-28T17:13:04Z",
"updated_at": "2014-08-28T17:13:04Z"
}
]
}
Add Namespace
*************
We want to create a new namespace that can contain the properties, objects,
etc.
We issue a ``POST`` request to add an namespace to Glance::
POST http://glance.example.com/v2/metadefs/namespaces/
The input data is an JSON-encoded mapping in the following format::
{
"namespace": "MyNamespace",
"display_name": "My User Friendly Namespace",
"description": "My description",
"visibility": "public",
"protected": true
}
.. note::
Optionally properties, objects and resource type associations could be
added in the same input. See GET Namespace output above(input will be
similar).
Update Namespace
****************
We want to update an existing namespace
We issue a ``PUT`` request to update an namespace to Glance::
PUT http://glance.example.com/v2/metadefs/namespaces/{namespace}
The input data is similar to Add Namespace
Delete Namespace
****************
We want to delete an existing namespace including all its objects,
properties etc.
We issue a ``DELETE`` request to delete an namespace to Glance::
DELETE http://glance.example.com/v2/metadefs/namespaces/{namespace}
Associate Resource Type with Namespace
**************************************
We want to associate a resource type with an existing namespace
We issue a ``POST`` request to associate resource type to Glance::
POST http://glance.example.com/v2/metadefs/namespaces/{namespace}/resource_types
The input data is an JSON-encoded mapping in the following format::
{
"name" :"OS::Cinder::Volume",
"prefix" : "hw_",
"properties_target" : "image",
"created_at": "2014-08-28T17:13:04Z",
"updated_at": "2014-08-28T17:13:04Z"
}
Remove Resource Type associated with a Namespace
************************************************
We want to de-associate namespace from a resource type
We issue a ``DELETE`` request to de-associate namespace resource type to
Glance::
DELETE http://glance.example.com/v2//metadefs/namespaces/{namespace}/resource_types/{resource_type}
List Objects in Namespace
*************************
We want to see the list of meta definition objects in a specific namespace
We issue a ``GET`` request to ``http://glance.example.com/v2/metadefs/namespaces/{namespace}/objects``
to retrieve objects.
The data is returned as a JSON-encoded mapping in the following format::
{
"objects": [
{
"name": "object1",
"description": "my-description",
"self": "/v2/metadefs/namespaces/MyNamespace/objects/object1",
"schema": "/v2/schemas/metadefs/object",
"created_at": "2014-08-28T17:13:06Z",
"updated_at": "2014-08-28T17:13:06Z",
"required": [],
"properties": {
"prop1": {
"title": "My object1 property1",
"description": "More info here",
"type": "array",
"items": {
"type": "string"
}
}
}
},
{
"name": "object2",
"description": "my-description",
"self": "/v2/metadefs/namespaces/MyNamespace/objects/object2",
"schema": "/v2/schemas/metadefs/object",
"created_at": "2014-08-28T17:13:06Z",
"updated_at": "2014-08-28T17:13:06Z",
"properties": {
"prop1": {
"title": "My object2 property1",
"description": "More info here",
"type": "integer",
"default": 20
}
}
}
],
"schema": "/v2/schemas/metadefs/objects"
}
Add object in a specific namespace
**********************************
We want to create a new object which can group the properties
We issue a ``POST`` request to add object to a namespace in Glance::
POST http://glance.example.com/v2/metadefs/namespaces/{namespace}/objects
The input data is an JSON-encoded mapping in the following format::
{
"name": "StorageQOS",
"description": "Our available storage QOS.",
"required": [
"minIOPS"
],
"properties": {
"minIOPS": {
"type": "integer",
"description": "The minimum IOPs required",
"default": 100,
"minimum": 100,
"maximum": 30000369
},
"burstIOPS": {
"type": "integer",
"description": "The expected burst IOPs",
"default": 1000,
"minimum": 100,
"maximum": 30000377
}
}
}
Update Object in a specific namespace
*************************************
We want to update an existing object
We issue a ``PUT`` request to update an object to Glance::
PUT http://glance.example.com/v2/metadefs/namespaces/{namespace}/objects/{object_name}
The input data is similar to Add Object
Delete Object in a specific namespace
*************************************
We want to delete an existing object.
We issue a ``DELETE`` request to delete object in a namespace to Glance::
DELETE http://glance.example.com/v2/metadefs/namespaces/{namespace}/objects/{object_name}
Add property definition in a specific namespace
***********************************************
We want to create a new property definition in a namespace
We issue a ``POST`` request to add property definition to a namespace in
Glance::
POST http://glance.example.com/v2/metadefs/namespaces/{namespace}/properties
The input data is an JSON-encoded mapping in the following format::
{
"name": "hypervisor_type",
"title" : "Hypervisor",
"type": "array",
"description": "The type of hypervisor required",
"items": {
"type": "string",
"enum": [
"hyperv",
"qemu",
"kvm"
]
}
}
Update property definition in a specific namespace
**************************************************
We want to update an existing object
We issue a ``PUT`` request to update an property definition in a namespace to
Glance::
PUT http://glance.example.com/v2/metadefs/namespaces/{namespace}/properties/{property_name}
The input data is similar to Add property definition
Delete property definition in a specific namespace
**************************************************
We want to delete an existing object.
We issue a ``DELETE`` request to delete property definition in a namespace to
Glance::
DELETE http://glance.example.com/v2/metadefs/namespaces/{namespace}/properties/{property_name}
API Message Localization
------------------------
Glance supports HTTP message localization. For example, an HTTP client can
receive API messages in Chinese even if the locale language of the server is
English.
How to use it
*************
To receive localized API messages, the HTTP client needs to specify the
**Accept-Language** header to indicate the language to use to translate the
message. For more info about Accept-Language, please refer http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
A typical curl API request will be like below::
curl -i -X GET -H 'Accept-Language: zh' -H 'Content-Type: application/json'
http://127.0.0.1:9292/v2/metadefs/namespaces/{namespace}
Then the response will be like the following::
HTTP/1.1 404 Not Found
Content-Length: 234
Content-Type: text/html; charset=UTF-8
X-Openstack-Request-Id: req-54d403a0-064e-4544-8faf-4aeef086f45a
Date: Sat, 22 Feb 2014 06:26:26 GMT
<html>
<head>
<title>404 Not Found</title>
</head>
<body>
<h1>404 Not Found</h1>
&#25214;&#19981;&#21040;&#20219;&#20309;&#20855;&#26377;&#26631;&#35782; aaa &#30340;&#26144;&#20687;<br /><br />
</body>
</html>
.. note::
Be sure there is the language package under /usr/share/locale-langpack/ on
the target Glance server.

View File

@ -1,60 +0,0 @@
..
Copyright 2012 OpenStack Foundation
All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may
not use this file except in compliance with the License. You may obtain
a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations
under the License.
Database Management
===================
The default metadata driver for glance uses sqlalchemy, which implies there
exists a backend database which must be managed. The ``glance-manage`` binary
provides a set of commands for making this easier.
The commands should be executed as a subcommand of 'db':
glance-manage db <cmd> <args>
Sync the Database
-----------------
glance-manage db sync <version> <current_version>
Place a database under migration control and upgrade, creating it first if necessary.
Determining the Database Version
--------------------------------
glance-manage db version
This will print the current migration level of a glance database.
Upgrading an Existing Database
------------------------------
glance-manage db upgrade <VERSION>
This will take an existing database and upgrade it to the specified VERSION.
Downgrading an Existing Database
--------------------------------
glance-manage db downgrade <VERSION>
This will downgrade an existing database from the current version to the
specified VERSION.

View File

@ -1,108 +0,0 @@
..
Copyright 2011 OpenStack Foundation
All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may
not use this file except in compliance with the License. You may obtain
a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations
under the License.
Disk and Container Formats
==========================
When adding an image to Glance, you must specify what the virtual
machine image's *disk format* and *container format* are. Disk and container
formats are configurable on a per-deployment basis. This document intends to
establish a global convention for what specific values of *disk_format* and
*container_format* mean.
Disk Format
-----------
The disk format of a virtual machine image is the format of the underlying
disk image. Virtual appliance vendors have different formats for laying out
the information contained in a virtual machine disk image.
You can set your image's disk format to one of the following:
* **raw**
This is an unstructured disk image format
* **vhd**
This is the VHD disk format, a common disk format used by virtual machine
monitors from VMWare, Xen, Microsoft, VirtualBox, and others
* **vmdk**
Another common disk format supported by many common virtual machine monitors
* **vdi**
A disk format supported by VirtualBox virtual machine monitor and the QEMU
emulator
* **iso**
An archive format for the data contents of an optical disc (e.g. CDROM).
* **qcow2**
A disk format supported by the QEMU emulator that can expand dynamically and
supports Copy on Write
* **aki**
This indicates what is stored in Glance is an Amazon kernel image
* **ari**
This indicates what is stored in Glance is an Amazon ramdisk image
* **ami**
This indicates what is stored in Glance is an Amazon machine image
Container Format
----------------
The container format refers to whether the virtual machine image is in a
file format that also contains metadata about the actual virtual machine.
Note that the container format string is not currently used by Glance or
other OpenStack components, so it is safe to simply specify **bare** as
the container format if you are unsure.
You can set your image's container format to one of the following:
* **bare**
This indicates there is no container or metadata envelope for the image
* **ovf**
This is the OVF container format
* **aki**
This indicates what is stored in Glance is an Amazon kernel image
* **ari**
This indicates what is stored in Glance is an Amazon ramdisk image
* **ami**
This indicates what is stored in Glance is an Amazon machine image
* **ova**
This indicates what is stored in Glance is an OVA tar archive file

View File

@ -1,163 +0,0 @@
#【sprint42】 42242: 版本回退@daisy1
|修改日期 |修改人 | 修改内容|
|:----|:----|:----:|:----|
|2016-06-17| 陈雪英 | 新增|
##1、特性简介
版本回退方案验证背景TECS升级失败需要回退。
环境信息
| 角色 |主控 |备控 | 计算节点|
|:----|:----|:----:|:----|
|主机 | A | B | C|
|当前老版本| 100 | 100 | 100|
|待升新版本 | 101 | 101 | 101 |
正常升级流程:
第一步 HA禁止倒换升级B/C版本到最新 B 100--->101 C 100----->101
第二步 A--->BAB主备倒换B为主
第三步 等待20分钟进行基本功能验证
第四步 升级A 100----->101
第五步 取消禁止倒换
如果版本升级之后第三步验证时发现新版本101有问题需要支持环境回退到老版本100。
##2、方案验证
**验证组网**控制节点glance/db/dbbackup/monagodb使用共享磁盘方式+OVS
要求正常升级环境时到以上第三步发现异常后需要将B,C回退到老版本
### A 新版本使用有问题回退B,C
当前环境信息
| 角色 |主控 |备控 | 计算节点|
|:----|:----|:----:|:----|
|主机 | A备 | B主 | C计|
|当前环境版本| 100 | 101异常 | 101|
==**回退步骤**==
**1、取消禁止倒换B--->AAB主备倒换A转主**A转主失败的情况暂不考虑
取消禁止倒换pcs resource clear lb_float_ip
ABy 主备倒换 pcs cluster move host_162_160_1_132 host_162_160_1_132 为A的主机名
time:10s
**2、再次禁止倒换**
禁止倒换命令pcs resource ban lb_float_ip host_162_160_1_132
host_162_160_1_132即为B的主机名
time:2s
**3、在daisy中保存待回退版本100**
copy time:10s
**4、回退计算节点C101---->100**
1如果计算节点使用的是DVS网络保存计算节点上的nova.conf文件为nova_old.conf需要关注计算节点是否还有其他配置需要保存多后端iscsi_use_multipath的配置
save nova.conf time:10s
2如果计算节点有虚拟机需要迁移相关虚拟机到其他计算节点
migrate vm time:unknown, 120
注意:虚拟如果不迁移,需要用户接受以下三种情况:
a、计算节点故障
b、用户能接受虚拟机中断业务
c、用户不能接受需要TECS保证不同版本之间支持迁移
3运行在docker的daisy进入如下/var/lib/daisy/tecs//f3e0fd0c-512b-43b6-a078-f9c41c0daa8a/目录获取tecs.confmappings.json文件并拷贝到daisy的/home/tecs_install目录下
time:60s
4修改tecs.conf文件中的EXCLUDE_SERVERS和CONFIG_NEUTRON_ML2_JSON_PATH配置项
EXCLUDE_SERVERS=A,B (填写不需要重新安装的节点A和B)
CONFIG_NEUTRON_ML2_JSON_PATH = /home/tecs_install/mappings.json (填写mappings.json文件所在的路径)
time=60s
5到计算节点上B用bin包手动卸载异常版本101
time=120s
6在daisy节点执行100.bin文件使用5 conf方式安装计算节点TECS版本。
**注意:**安装bin前需要清理daisy主机上/root/.ssh/known_hosts文件中的C点的公钥信息否则安装时会让输入ssh密码
Adding post install manifest entries [ DONE ]
root@10.43.203.90's password:
time=200s
7TECS安装成功之后
需要手动修改nova.conf文件
compute_manager=nova.compute.manager.ComputeManager配置项修改为
compute_manager=nova.compute.tecs_manager.TecsComputeManager(已知问题TECS2.0_P7B1中未合入最新DEV版本NOVA已经修改)
vncserver_proxyclient_address=127.0.0.1配置项修改为
vncserver_proxyclient_address=host-162-160-1-12.STORAGE
如果配置的是DVS比较nova_old.conf与当前计算节点的nova.conf文件手动修改nova.conf中的vcpu_pin_set和vcpupin_policy等配置项
或者直接用原来的nova_old.conf文件替换当前nova.conf文件
8)重启C的服务openstack-service restart
注意:openstack-nova-storage服务也要手动重启一下
9)检查计算节点服务全部正常启动。
**5、回退控制节点备板B100----->101**
1参考回退计算节点方法配置控制节点B的tecs.conf文件EXCLUDE_SERVERS=AC
CONFIG_NEUTRON_ML2_JSON_PATH = /home/tecs_install/mappings.json
2到控制节点B上用bin包手动卸载异常版本101
time=3'35"=215s
3在B板上执行100.bin文件使用5 conf方式安装TECS版本。
time=11'15"=615s
注意安装bin前需要清理daisy主机上/root/.ssh/known_hosts文件中的B点的公钥信息否则安装时会让输入ssh密码
Adding post install manifest entries [ DONE ]
root@10.43.203.90's password:
4TECS版本安装完成之后在备板B上执行/home/tecs_install/storage_auto_config目录下执行python storage_auto_config.py cinder_conf cinderManageIP同步cinder多后端配置。
注意: 如果是自研KS3200磁阵对于后端使用的cinder_zte_conf.xml文件需要手动修改这个字段`<LocalIP>129.0.0.8</LocalIP>`
也可以执行上面命令时加IP地址如python storage_auto_config.py cinder_conf cinderManageIP
cinderManageIP为cinder组件的管理平面地址。
time=10s
5)从正常的控制节点A拷贝/etc/corosync/corosync.conf/var/lib/pcsd/ip_name.conf/var/lib/pcsd/pcs_settings.conf 到B的相同目录下
如果是集群方式,还需要拷贝/etc/drdb.d/WebData.res 文件到相同目录下
6在备节点B上执行pcs cluster start命令启动集群
time=10s
7用systemctl status pacemaker.service检查服务状态OKcrm_mon -1资源启动正常
8清除禁止HA倒换操作pcs resource clear lb_float_ip
9HA可能会自动设置为维护模式需要手动取消维护模式相关命令pcs property set unmanaged=false
10如果glance/db/dbbackup/monagodb盘是集群方式还需要将主板上的数据手动同步到备板的磁盘上。
**6、检查回退的版本是否正常**
1主备控制节点HA进行倒换可以正常倒换
2创建虚拟机正常
### B 升级节点B时异常回退B
参考以上5、回退控制节点备板B
| 角色 |主控 |备控 | 计算节点|
|:----|:----|:----:|:----|
|主机 | A备 | B主 | C计|
|当前环境版本| 100 | 101异常 | 100|
### C 升级节点C时异常回退C
| 角色 |主控 |备控 | 计算节点|
|:----|:----|:----:|:----|
|主机 | A备 | B主 | C计|
|当前环境版本| 100 | 100 | 101(异常)|
参考以上4、回退计算节点C
##3、遗留问题
本地集群和共享集群方式需要继续验证
##4、合入版本
##5、注意事项
LB的资源不能手动配置通过安装保证
计算节点安装完成之后需要手动修改nova.conf文件中的巨页配置信息
计算节点安装完成之后需要手动修改nova.conf文件中的多路径配置信息
控制节点cinder多后端配置会丢失bin方式安装后默认只有LVM后端
CEPH后端需要手动修改CEPH相关配置。
对于有些数据库不兼容的情况需要单独考虑
##6、文档修改
##7、验收方法

View File

@ -1,979 +0,0 @@
# Daisy 安装指导书
[TOC]
## 1 引言
### 1.1 编写目的
本文档从Daisy的基本概念入手旨在介绍Daisy部署的基本配置和用法结合组网图介绍部署过程中参数配置和界面使用。
### 1.2 术语和缩略语
|服务 |项目名称 |功能描述|
|----|:----:|:----|
|Daisy|Daisy|TECS的自动化部署工具|
|Dashboard| Dashboard|Web界面用户通过Dashboard能够进行界面化的daisy部署|
|Identity Service| Keystone |向服务提供认证和鉴权功能|
|Ironic| Ironic| Ironic是OpenStack提供裸金属部署的解决方案,而非虚拟机。默认情况下,它将使用PXE和IPMI接口管理主机,但Ironic还支持特定供应商的插件可以实现额外的功能|
|TECS | Tulip Elastic Computer System |郁金香弹性计算系统|
|IPMI| Intelligent Platform Management Interface| 智能平台管理接口 (IPMI)是一种开放标准的硬件管理接口规格,定义了嵌入式管理子系统进行通信的特定方法|
|BMC| Board Management Controller |单板管理模块|
### 1.3 支持IPMI服务器列表
Daisy部署的服务器需要支持IPMI协议现有硬件服务器中支持IPMI的服务器类型有
E9000HPC7000DELLRS4300I8350等。
##2 组网规划
###2.1 组网说明
本次安装组网采用2个控制节点HA+LB+2个计算节点compute+1个KS3200 IPSAN。
![image](image/netplan.JPG)
###2.2 硬件说明
|服务器类型| 数量 | 用途|
|----| :----: |:----|
|E9000刀片 | 4 |2块控制节点其中一块含 安装daisy服务器2块计算节点|
|KS3200 IPSAN | 1 |IPSAN作为TECS的存储后端|
###2.3 网络规划
本场景为典型的Daisy部署TECS环境场景 规划了管理平面MANAGEMENTpublic平面PUBLICAPI存储管理平面STORAGE存储业务面storage_data以及虚拟机业务平面DATAPLANE其中管理平面MANAGEMENT与存储管理平面STORAGE合一。
实际物理服务器上还有PXE部署平面DEPLOYMENT用于主机发现和安装其他节点操作系统但网络映射不需要关注所以该平面不列在下面列表中。
E9000刀片包含4个网口网口与平面的映射关系如下
![image](image/netconf.JPG)
Daisy所在服务器的地址需要手工配置网络规划如下
![image](image/daisynetconf.JPG)
##3 Daisy安装和说明
###3.1 OS+DAISY+TECS版本说明
整套环境安装需要取用3个版本OS+DAISY+TECS版本本例的daisy服务器运行在docker中所以daisy安装时需要取用带docker的操作系统。
|系统 | 版本|
|----|:----|
|OS|Mimosa-V02.16.11.P7B1I59-CGSL_VPLAT-5.1-x86_64-KVM-director003-daisy117.iso
|DAISY| daisy-2016.2.11-7.11.119.el7.x86_64.rpm|
|TECS| ZXTECS_V02.16.11_P7B1_I156.zip|
###3.2 第一台裸机Daisy服务器的操作系统安装
第一台裸机后续做daisy服务器使用的操作系统需要用U盘进行安装U盘制作方法见.附件1 U盘的制作方法
#### 3.2.1服务器BMC地址设置
通过登录系统管理单板SMM的web页面设置对应服务器的BMC地址。
以E9000为例SMM的初始登录地址左板192.168.5.7右板192.168.5.8。如需要修改IP可以通过使用网线连接PC与SMM上的网口登录SMM的地址例如https://192.168.5.7用户名zteroot密码superuser。
选中导航条中的【机框管理】页面,在左侧导航树中选【机框配置】-【网络配置】可以修改SMM和刀片的BMC IP子网掩码和网关。
![image](image/bmcip.JPG)
注:
1 SMM设置的地址必须物理可通否则修改后无法登录。
2 刀片的BMC地址必须与SMM设置的地址在同一网段否则BMC地址不通。
如果使用Daisy服务器安装部署目标刀片必须确保Daisy服务器所在刀片与目标刀片的BMC地址物理可通。
#### 3.2.2安装TFG操作系统
本章描述如何安装第一台服务器的TFG操作系统。
准备工作:
1. 调试机与刀片smm管理模块网络互通通过kvm链接
2. 要安装的刀片上电
3. 服务器安装做好raid
4. 将U盘接入待安装的第一台服务器7槽
所有服务器安装操作系统之前都要先设置好raid。服务器设置好RAID之后后续如果没有修改需要无需再重复做RAID。
#####3.2.2.1刀片启动模式修改
配置前提SMM单板已经配置好并且可以登陆如下图
![image](image/smmlogin1.JPG)
输入用户名和密码默认为zteroot/superuser登陆
![image](image/smmlogin2.JPG)
点击【机框管理】,左侧的【机框配置】-【单板配置】在右边界面中选中第一块服务器所在的7槽刀片点击【设置】配置为USB启动。
![image](image/setusb.JPG)
#####3.2.2.2 通过BMC地址登录服务器KVM
【机框管理】,左侧的【机框配置】-【网络配置】查看该服务器的BMC地址为10.43.203.239。通过该地址https://10.43.203.239/默认用户名与密码为zteroot/superuser登录该服务器的KVM观察服务器重启及操作系统安装过程。
![image](image/bmcipcheck.JPG)
#####3.2.2.3 操作系统安装
将U盘插在第一块服务器上重启该服务器通过服务器KVM可看观察到安装过程.
![image](image/installos.JPG)
安装完成后会提示退出重启。
注意系统重启前可以先更改该刀片的启动方式为硬盘启动并拔出U盘然后再重启刀片。
####3.2.4操作系统设置
操作系统涉及的主机名、IP地址、网卡规划请参照规划说明。
本节操作所有控制节点和计算节点都需要执行只是第一台daisy服务需要手动配置主机名和IP地址其他节点和计算节点daisy安装时会自动进行配置。
#####3.2.4.1 地址规划
此Daisy所在服务器的地址规划见2.3网络规划。
1、第一台服务器需要手工配置其他服务器通过Daisy中的网络平面配置会自动分配。
2、STORAGE存储控制面地址与MANAGEMENT合一。
#####3.2.4.2 主机名设置
[root@localhost]# **vi /etc/hostname**
==host-10-43-203-132==
[root@localhost]# **hostnamectl set-hostname host-10-43-203-132**
[root@localhost]# logout
logout之后重新登录.
#####3.2.4.3 网口配置
1、enp132s0f0、enp132s0f1网卡做绑定绑定口名称为bond0,并分别配置VLAN为161,162的子接口bond0.161bond0.162
修改/etc/sysconfig/network-scripts目录下ifcfg-enp132s0f0、ifcfg-enp132s0f1文件多余的配置删除。。
[root@host-10-43-203-132 network-scripts]# **cat ifcfg-enp132s0f0**
TYPE=Ethernet
BOOTPROTO=static
NAME=enp132s0f0
DEVICE="enp132s0f0"
ONBOOT="yes"
MASTER=bond0
SLAVE=yes
[root@host-10-43-203-132 network-scripts]# **cat ifcfg-enp132s0f1**
TYPE=Ethernet
BOOTPROTO=static
NAME=enp132s0f1
DEVICE="enp132s0f1"
ONBOOT="yes"
MASTER=bond0
SLAVE=yes
[root@host-10-43-203-132 network-scripts]# **cat ifcfg-bond0**
BOOTPROTO="static"
ONBOOT="yes"
DEVICE="bond0"
BONDING_OPTS="miimon=100 mode=1"
[root@host-10-43-203-132 network-scripts]#
[root@host-10-43-203-132 network-scripts]# **cat ifcfg-bond0.161**
OTPROTO="static"
ONBOOT="yes"
DEVICE="bond0.161"
IPADDR="162.161.1.132
NETMASK="255.255.255.0"
VLAN=yes
[root@host-10-43-203-132 network-scripts]# **cat ifcfg-bond0.162**
OTPROTO="static"
ONBOOT="yes"
DEVICE="bond0.162"
IPADDR="162.162.1.132"
NETMASK="255.255.255.0"
VLAN=yes
[root@host-10-43-203-132 network-scripts]#
2、enp129s0f0网口上配置地址和VLAN160接口
在服务器上执行ip link add link enp129s0f0 name enp129s0f0.160 type vlan id 160命令增加VLAN160子接口然后修改以下配置文件。
[root@host-10-43-203-132 network-scripts]# **ip link add link enp129s0f0 name enp129s0f0.160 type vlan id 160**
[root@host-10-43-203-132 network-scripts]# **cat ifcfg-enp129s0f0**
HWADDR=4C:09:B4:B1:C1:F0
TYPE=Ethernet
BOOTPROTO=static
NAME=enp129s0f0
UUID=56ae2b62-8826-4c11-9a89-290e7ca67071
DEVICE="enp129s0f0"
ONBOOT="yes"
IPADDR=10.43.203.132
NETMASK=255.255.254.0
GATEWAY=10.43.202.1
[root@host-10-43-203-132 network-scripts]# **cat ifcfg-enp129s0f0.160**
OTPROTO="static"
ONBOOT="yes"
DEVICE="enp129s0f0.160"
IPADDR="162.160.1.132"
NETMASK="255.255.255.0"
VLAN=yes
本例中已经设置大网网关10.43.202.1,如果没有设置网关,需要设置一下网关,否则安装TECS会失败
设置网关后执行service network restart生效配置重启之后network服务正常ifconfig查看配置的地址均已生效。
###3.3 运行在Docker中的daisy安装
执行daisy_docker_init.sh input1 input2 input3 input4 input5 input6 来起daisy和vdirector容器
入参的含义:
input1 daisy里面dhcp的网口
input2 daisy管理面ip
input3 ICT绑定的地址
input4 director的nginx对外暴露的IP用来替换endpoints中的openstackIPdirector提供给nfvo访问的ip地址--------nfvo访问vim用
input5 nvfo的IPVIM主动nvfo上报PM数据用的
input6 : nvfo的端口VIM主动nvfo上报PM数据用的
本文中只起daisy容器所以只需填写input1 input2参数即可。 根据前面规划bond0为daisy里面dhcp的网口10.43.203.132为daisy管理口IP。
[root@host-10-43-203-132 home]# **daisy_docker_init.sh bond0 10.43.203.132**
daisy docker config file: /var/lib/daisy/scripts/daisy.conf
ln -s '/usr/lib/systemd/system/nfs-server.service' '/etc/systemd/system/nfs.target.wants/nfs-server.service'
rsyslogd restart!
vdirector config file not exist!
creating daisy ...
daisy-mysql
daisy-mysql.backup
WARNING: IPv4 forwarding is disabled. Networking will not work.
ccda0709026a7a185f6cf9e28bae39436144d8dafc60684eb79d591572fbba4f
VOL_pLP3o
WARNING: IPv4 forwarding is disabled. Networking will not work.
"daisy" created
[root@host-10-43-203-132 home]# **docker-manage ps**
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
==afa9b42d4736 937cb3bd58a4 "/bin/sh -c /bin/sh" 8 seconds ago Up 7 seconds daisy==
docker-manage ps命令查看有如上高亮部分信息时表示daisy容器已运行。
使用docker-manage enter daisy命令进行daisy容器设置hosts。
[root@host-10-43-203-132 home]# **docker-manage enter daisy**
-bash-4.2#**cat /etc/hosts**
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
==10.43.203.132 localhost==
###3.4 登陆daisy的web页面
Daisy容器创建后稍等2分钟等待daisy相关服务正常运行后即可进入daisy的dashboard页面即http://10.43.203.132:18080/ 具体ip就是在起daisy的时候输入的ip地址端口号为18080默认帐户admin/keystone
![image](image/daisylogin1.JPG)
至此daisy服务器安装完毕如需部署TECS主机则可以参考下一章 4 集群部署
##4 DAISY独立部署TECS示例
###4.1版本上传
登录daisy DASHBOARD界面进入【版本】页面点击【选择文件】分别上传OS和TECS版本。
![image](image/versionupload.JPG)
上传完成之后可以显示ISO与bin文件.
![image](image/versionuploadOK.JPG)
###4.2创建集群
登录daisy DASHBOARD界面进入【集群】列表第一次登录时集群是空的点击蓝色部分即可进行集群创建.
![image](image/clustercreate.JPG)
####4.2.1基本信息
集群创建时先需要配置基本信息在基本信息中填写集群名称是否启用DNS以及描述信息描述信息可以不填。
![image](image/clustercreatebase.JPG)
####4.2.2角色配置
1、控制节点HA配置
![image](image/createroleha.JPG)
Public浮动IP需要与Public平面在同一网段其他浮动IP需要与管理平面在同一网段浮动IP可以手动配置也可以选择自动分配如果自动分配网络平面的地址池中需要多分配4个IP地址用于分配各浮动IP地址。
NTP IP需要填专有时钟服务器地址如果没有可以填HA浮动IP地址
2、glance/DB/DBBackup/MongoDB后端类型配置
![image](image/createhasharedisk.JPG)
![image](image/createhasharedisk2.JPG)
3、cinder后端类型配置
根据组网要求KS3200 IPSAN磁阵做为cinder后端cinder点击新增一条后端配置
![image](image/cinderbackend1.JPG)
新增后端配置
![image](image/cinderbackendconf.JPG)
按确定后即可增加一条cinder后端配置。
![image](image/cinderbackendok.JPG)
4、LB浮动IP配置
![image](image/createlbconf.JPG)
####4.2.3网络平面配置
参见2.3网络规划
说明本组网中MANAGEMENT与STORAGE平面合一。
根据组网图做如下配置:
1、MANAGEMENT网络平面配置
![image](image/management.JPG)
2、PUBLICAPI网络平面配置
![image](image/public.JPG)
3、DATAPLANE网络平面配置
![image](image/dataplane.JPG)
4、STORAGE网络平面配置
![image](image/storage1.JPG)
storage增加两个存储业务面网络配置
点击增加网络平面按钮
![image](image/storage2.JPG)
分别增加storage_data161, storage_data162网络平面配置(此处只截图161的配置过程)
![image](image/storage3.JPG)
![image](image/storage4.JPG)
配置完成之后按右下角创建按钮即可进行集群创建,集群创建成功之后自动跳转到集群主机部署页面进行添加主机。
###4.3 集群主机部署
####4.3.1 主机发现
主机发现有两种方式:
一种是对操作系统已经安装成功的服务器通过SSH方式发现如此处daisy所在的服务器因为操作系统已经安装好只需要安装TECS可以通过SSH方式发现
还有一种是PXE方式发现。
#####4.3.1.1 SSH发现宿主机
登录daisy集群页面创建一个集群cxy1然后进入集群cxy1点击集群主机部署即可开始发现主机操作。
![image](image/findhost.JPG)
点击发现主机然后逐一输入物理目标主机的SSH访问地址10.43.203.132用户名和密码默认是root/ossdbg1点击提交后右侧即可显示待SSH发现的主机列表
![image](image/sshfindhost.JPG)
点击开始发现发现成功之后主机列表可以显示SSH发现的主机。
![image](image/sshfindhostok.JPG)
#####4.3.1.2 PXE方式发现其他主机
PXE发现首先要保证主机的PXE网络是通的在daisy服务器上用ipmiping命令检查各主机的IPMI是否是通的。
主机的IPMI地址参考3.2.1节中BMC IP地址的信息。
[root@host-10-43-203-132 home]# **ipmiping 10.43.203.236**
ipmiping 10.43.203.236 (10.43.203.236)
*response received from 10.43.203.236: rq_seq=44*
登录SMM将所有待安装系统的服务器设置为PXE网络启动如下图 3、4、12槽为待PXE发现的主机点“操作”中的设置分别将其设置为网络启动。
![image](image/pxefindhost1.JPG)
通过单板IPMI地址分别登录其KVM查看系统启动情况如3槽IPMI地址为10.43.203.247
则登录https://10.43.203.247,用户名/密码默认为zteroot/superuser; 在 设备操作---单板操作 中对服务器设置重启,然后点击单板操作旁边的 设置 按钮,按确定后服务器即可重启。
![image](image/pxefindhost2.JPG)
登录服务器的KVM查看其能正常重启且通过DHCP网口正确获取到小系统并能正常进入小系统。
![image](image/pxefindhost3.JPG)
回到daisy页面进行发现主机正常即可正常显示PXE发现的主机列表。
![image](image/pxefindhostok.JPG)
注意如果10分钟内没有发现主机需要检查PXE网络是否正确。
PXE网络的几种组网说明需要补充相关组网图和文字
被安装的目标主机使用的PXE口如果使用VLAN隔离需要使用native方式。
1、PXE口不做BOND的情况
2、PXE口做BOND的情况
一个主机只允许一个网口加入PXE所在的VLAN此网络的报文不带VLAN使用的是native网络
3、同一机框内有多个PXE服务器的情况。
#####4.3.1.3 添加主机
发现成功之后选中所有主机,按下一步会自动将主机加入到集群中,并进入分配角色页面。
![image](image/addhost.JPG)
#####4.3.1.4磁阵配置
> 详见附件2 KS3200 IPSAN磁阵配置daiy安装指导.md
####4.3.2分配角色
Daisy的主机角色包括如下3种
|名称 |描述 |中文描述|
|----|:----|:----|
|CONTROLLER_LB| Controller rolebackup type is loadbalance| 控制角色备份方式为LB|
|CONTROLLER_HA| Controller rolebackup type is HAactive/standby |控制角色备份方式为HA|
|COMPUTER| Compute role| 计算角色|
一个主机可以承载一种角色也可以承载多个角色角色的配置最终影响被部署主机安装哪些TECS组件服务。角色和TECS组件的对应关系Daisy已默认定义。如不更改用户不需要关心。
对于控制节点可以有HA/LB两中组合的角色分配方式HA的方式为控制节点必选角色LB为控制节点可选角色作为控制节点的主机同时也可以拥有COMPUTE角色以同时具备计算节点的功能。控制节点最少要有两个主机节点且角色一致。对于计算节点只有COMPUTE这一种角色。
根据组网规划当前4个节点的角色规划为两个控制节点HA+LB +两个计算节点COMPUTER ,通过拖拽的方式给每个物理主机分配角色。
![image](image/addrole.JPG)
分配完角色之后即可按下一步进行绑定网口。
####4.3.3绑定网口
主机角色分配完成之后,点击下一步,即可进行绑定网口操作。
选中某个你要绑定网卡的主机,点击右上角的绑定网口按钮,按照自己的需要进行物理网口的绑定。
根据前面组网规划选择enp132s0f0, enp132s0f1做linux绑定绑定口名称为bond0绑定模式为active-backup。
![image](image/bond.JPG)
按绑定后,即可显示绑定成功;再选择其他主机,分别做绑定。
![image](image/bondok.JPG)
####4.3.4网络映射
绑定完网卡后,点击下一步,进入网络映射配置页面,在这里需要将物理主机的物理网卡(或者绑定后的网卡)对应到之前在集群里面配置的网络平面。
注意:对于管理面以及存储面相关地址的分配规则目前是,按照完成网络映射配置的顺序从地址池地址中从小到大顺序分配,因此需要按照刀片的槽位顺序从小到底,逐个设置网络映射。
![image](image/mapnetcard.JPG)
选中其中一个主机,点击【配置网络平面】
![image](image/mapnetcard1.JPG)
对于计算节点还需要配置physnet1 网络需要选择虚拟交换机类型本组网中使用OVS网络。
![image](image/mapnetcard2.JPG)
依次分配好所有主机的网络平面并保存修改
![image](image/mapnetcardok.JPG)
####4.3.5主机配置
网络映射配置完成之后,点击下一步开始主机配置。
选择一个主机,点击【主机配置】,即可进行配置
![image](image/hostconf.JPG)
配置参数
 操作系统版本点击下拉框选择之前上传的OS版本
 系统盘正常情况下填写sda
 系统盘大小默认50G建议根据服务器的实际硬盘大小填写此分配100G。
 IPMI User和Password物理主机的IPMI的用户和密码E9000刀片默认设置为zteroot/superuser
可以在7槽的daisy服务器上通过命令对各刀片的IPMI用户进行验证。
在主机---主机列表页面可以查询到各个服务器的IPMI地址然后用如下命令进行验证。
![image](image/hostlist.JPG)
[root@host-10-43-203-132 /(daisy_admin)]$ ipmitool -I lanplus -H 10.43.203.26 -U zteroot -P superuser chassis power status
Chassis Power is on
[root@host-10-43-203-132 /(daisy_admin)]$ ipmitool -I lanplus -H 10.43.203.236 -U zteroot -P superuser chassis power status
Chassis Power is on
[root@host-10-43-203-132 /(daisy_admin)]$ ipmitool -I lanplus -H 10.43.203.247 -U zteroot -P superuser chassis power status
Chassis Power is on
验证成功就可以通过ipmi设置刀片从PXE或disk方式启动并自动安装系统。
 巨页大小在physnet1网络使用DVS交换时需要配置巨页参数默认1G这个参数只在角色为计算节点的主机配置。
 巨页个数在physnet1网络使用DVS交换时需要配置巨页参数, 这个参数只在角色为计算节点的主机配置规划要求为128G内存设置10864G内存设置44此处因为使用的是OVS网络所以可以不配置。
 被隔离的核在physnet1网络使用DVS交换时需要配置巨页参数, 这个参数只在角色为计算节点的主机配置。
所有主机配置完成之后即可按【部署】进行自动部署
![image](image/hostconfok.JPG)
####4.3.6部署
按部署按钮之后自动跳转到集群部署信息页面通过进度条提示可以实时显示整个部署进程。安装过程中先安装OS再安装TECS版本。
![image](image/deploy1.JPG)
OS安装成功之后开始安装TECS版本
![image](image/deploy2.JPG)
![image](image/deployok.JPG)
状态中显示TECS安装成功进度为100%时表示TECS安装成功。
##5 Daisy WEB界面介绍
###5.1 集群
####5.1.1 我的集群列表
####5.1.2 创建集群
#####5.1.2.1 基本信息
#####5.1.2.2 角色配置
#####5.1.2.3 网络平面配置
####5.1.3集群部署信息
#####5.1.3.1 集群主机部署
######5.1.3.1.1 添加主机
1. SSH发现
2. PXE发现
3. 添加主机
######5.1.3.1.2 分配角色
######5.1.3.1.3 绑定网口
######5.1.3.1.4 网络映射
######5.1.3.1.5 主机配置
#####5.1.3.2 重置主机
除宿主机之外,所有其他主机均可进行重置主机;
选择一台主机然后点击重置主机主机重置之后可以操作系统可以重新进行安装OS。
#####5.1.3.3 直接部署
直接部署可以将主机的系统进行重新安装的操作
#####5.1.3.4 移出集群
移出集群可以将主机从当前集群移出,此时这台主机将重新进入主机发现列表,需要进行重新配置,加入其他集群。
#####5.1.3.5 生成主机模板
####5.1.4 集群操作
#####5.1.4.1 修改集群
#####5.1.4.2 升级集群
Daisy支持已安装的集群的升级功能。在升级前需要将升级包上传到/var/lib/daisy/tecs/(特别说明该目录下只能存放一份最新的TFG和TECS的bin包)可以通过5.1节实现web页面上传版本。上传的版本会自动替换固定目录下的原有版本。
登录web进入集群页面鼠标移动到待升级的集群会显示一些图标点击向上箭头的图标会跳出确认对话框点击“确认”即自动跳转至集群进度界面显示升级进度。
#####5.1.4.3 卸载TECS
Daisy支持已安装的集群在部署后卸载集群中的刀片的tecs软件。进入集群页面鼠标移动到待卸载的集群会显示一些图标点击向下箭头的图标会跳出确认对话框点击“确认”即自动跳转至集群进度界面显示卸载进度。
#####5.1.4.4 生成集群模板
###5.2 版本
####5.2.1 上传OS和TECS版本
上传OS和TECS版本有两种方式一种是通过docker将版本上传到daisy服务器的/var/lib/daisy/tecs目录一种是从dashboard上传。
1、通过docker上传版本
拷贝版本到第一台服务器daisy的宿主机/home/目录下。
执行命令docker cp Mimosa-V02.16.10.P6B1I32-CGSL_VPLAT-5.1-x86_64-KVM.iso daisy:/var/lib/daisy/tecs
执行命令docker cp ZXTECS_V02.16.10_P6B1_I151_installtecs_el7_noarch.bin daisy:/var/lib/daisy/tecs
2、通过dashboard上传
进入web界面后点击左上角版本点击浏览选择需要上传的OS和TECS版本这里上传的OS版本为Mimosa-V02.16.10.P6B1I22-CGSL_VPLAT-5.1-x86_64-KVM.iso上传的TECS版本为ZXTECS_V02.16.10_P6B1_I102_installtecs_el7_noarch.bin上传后可以在版本页面看到上传后的版本文件。
###5.3 主机
####5.3.1 主机列表
####5.3.2 加入集群
####5.3.3 移出集群
###5.4 模板
###5.5 系统
####5.5.1 备份和恢复
#####5.5.1.1 备份
#####5.5.1.2 恢复
####5.5.2 系统配置
##6 daisy安装升级卸载操作指导
##7 附件
###7.1 附件1 U盘的制作
###7.3 附件2 KS3200 IPSAN磁阵配置

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

View File

@ -1,27 +0,0 @@
..
Copyright 2010 OpenStack Foundation
All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may
not use this file except in compliance with the License. You may obtain
a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations
under the License.
Image Identifiers
=================
Images are uniquely identified by way of a URI that
matches the following signature::
<Glance Server Location>/v1/images/<ID>
where `<Glance Server Location>` is the resource location of the Glance service
that knows about an image, and `<ID>` is the image's identifier. Image
identifiers in Glance are *uuids*, making them *globally unique*.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

View File

@ -1,931 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd">
<!--Created by yEd 3.14-->
<key attr.name="Description" attr.type="string" for="graph" id="d0"/>
<key for="port" id="d1" yfiles.type="portgraphics"/>
<key for="port" id="d2" yfiles.type="portgeometry"/>
<key for="port" id="d3" yfiles.type="portuserdata"/>
<key attr.name="url" attr.type="string" for="node" id="d4"/>
<key attr.name="description" attr.type="string" for="node" id="d5"/>
<key for="node" id="d6" yfiles.type="nodegraphics"/>
<key for="graphml" id="d7" yfiles.type="resources"/>
<key attr.name="url" attr.type="string" for="edge" id="d8"/>
<key attr.name="description" attr.type="string" for="edge" id="d9"/>
<key for="edge" id="d10" yfiles.type="edgegraphics"/>
<graph edgedefault="directed" id="G">
<data key="d0"/>
<node id="n0" yfiles.foldertype="group">
<data key="d4"/>
<data key="d6">
<y:ProxyAutoBoundsNode>
<y:Realizers active="0">
<y:GroupNode>
<y:Geometry height="85.11637612609246" width="111.74245254504217" x="126.64775665295588" y="85.43888426770397"/>
<y:Fill color="#F5F5F5" transparent="false"/>
<y:BorderStyle color="#000000" type="dashed" width="1.0"/>
<y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="21.4609375" modelName="internal" modelPosition="t" textColor="#000000" visible="true" width="111.74245254504217" x="0.0" y="0.0">Keystone</y:NodeLabel>
<y:Shape type="roundrectangle"/>
<y:State closed="false" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
<y:Insets bottom="15" bottomF="15.0" left="15" leftF="15.0" right="15" rightF="15.0" top="15" topF="15.0"/>
<y:BorderInsets bottom="4" bottomF="3.6554386260924616" left="0" leftF="0.0" right="0" rightF="0.0" top="0" topF="0.0"/>
</y:GroupNode>
<y:GroupNode>
<y:Geometry height="50.0" width="50.0" x="-50.0" y="-266.5"/>
<y:Fill color="#F5F5F5" transparent="false"/>
<y:BorderStyle color="#000000" type="dashed" width="1.0"/>
<y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="21.4609375" modelName="internal" modelPosition="t" textColor="#000000" visible="true" width="65.201171875" x="-7.6005859375" y="0.0">Folder 2</y:NodeLabel>
<y:Shape type="roundrectangle"/>
<y:State closed="true" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
<y:Insets bottom="5" bottomF="5.0" left="5" leftF="5.0" right="5" rightF="5.0" top="5" topF="5.0"/>
<y:BorderInsets bottom="0" bottomF="0.0" left="0" leftF="0.0" right="0" rightF="0.0" top="0" topF="0.0"/>
</y:GroupNode>
</y:Realizers>
</y:ProxyAutoBoundsNode>
</data>
<graph edgedefault="directed" id="n0:">
<node id="n0::n0">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="30.0" width="81.74245254504217" x="141.64775665295588" y="121.89982176770397"/>
<y:Fill color="#CFE2F3" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="22.984375" x="29.379038772521085" y="6.015625">API<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="roundrectangle"/>
</y:ShapeNode>
</data>
</node>
</graph>
</node>
<node id="n1" yfiles.foldertype="group">
<data key="d4"/>
<data key="d6">
<y:ProxyAutoBoundsNode>
<y:Realizers active="0">
<y:GroupNode>
<y:Geometry height="245.2759236593156" width="354.36701957715013" x="262.0184097290039" y="-56.61171875000008"/>
<y:Fill color="#F5F5F5" transparent="false"/>
<y:BorderStyle color="#000000" type="dashed" width="1.0"/>
<y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="21.4609375" modelName="internal" modelPosition="t" textColor="#000000" visible="true" width="354.36701957715013" x="0.0" y="0.0">Glance</y:NodeLabel>
<y:Shape type="roundrectangle"/>
<y:State closed="false" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
<y:Insets bottom="15" bottomF="15.0" left="15" leftF="15.0" right="15" rightF="15.0" top="15" topF="15.0"/>
<y:BorderInsets bottom="0" bottomF="0.0" left="0" leftF="0.0" right="5" rightF="4.930725250244336" top="0" topF="0.0"/>
</y:GroupNode>
<y:GroupNode>
<y:Geometry height="50.0" width="50.0" x="0.0" y="60.0"/>
<y:Fill color="#F5F5F5" transparent="false"/>
<y:BorderStyle color="#000000" type="dashed" width="1.0"/>
<y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="21.4609375" modelName="internal" modelPosition="t" textColor="#000000" visible="true" width="65.201171875" x="-7.6005859375" y="0.0">Folder 3</y:NodeLabel>
<y:Shape type="roundrectangle"/>
<y:State closed="true" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
<y:Insets bottom="5" bottomF="5.0" left="5" leftF="5.0" right="5" rightF="5.0" top="5" topF="5.0"/>
<y:BorderInsets bottom="0" bottomF="0.0" left="0" leftF="0.0" right="0" rightF="0.0" top="0" topF="0.0"/>
</y:GroupNode>
</y:Realizers>
</y:ProxyAutoBoundsNode>
</data>
<graph edgedefault="directed" id="n1:">
<node id="n1::n0">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="104.36576740931571" width="30.0" x="277.0184097290039" y="-20.15078125000008"/>
<y:Fill color="#CFE2F3" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="14" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="20.296875" modelName="custom" rotationAngle="270.0" textColor="#000000" visible="true" width="66.6103515625" x="4.8515625" y="18.877707923407854">REST API<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="roundrectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n1::n1">
<data key="d6">
<y:SVGNode>
<y:Geometry height="57.0" width="48.61853134180035" x="526.3442775726315" y="6.625562401126842"/>
<y:Fill color="#CCCCFF" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="14" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="20.296875" modelName="custom" textColor="#000000" visible="true" width="77.3359375" x="-14.358703079099882" y="-24.296875">Glance DB<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.5" nodeRatioX="-1.1657341758564144E-15" nodeRatioY="-0.5" offsetX="0.0" offsetY="-4.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:SVGNodeProperties usingVisualBounds="true"/>
<y:SVGModel svgBoundsPolicy="0">
<y:SVGContent refid="1"/>
</y:SVGModel>
</y:SVGNode>
</data>
</node>
<node id="n1::n2">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="57.0" width="91.60232162475586" x="504.85238243115384" y="104.31752484326745"/>
<y:Fill color="#CFE2F3" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="14" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="52.890625" modelName="custom" textColor="#000000" visible="true" width="84.0966796875" x="3.7528209686279297" y="4.0">Database
Abstraction
Layer<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="-0.5" nodeRatioX="0.0" nodeRatioY="-0.5" offsetX="0.0" offsetY="4.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="roundrectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n1::n3">
<data key="d6">
<y:GenericNode configuration="com.yworks.entityRelationship.big_entity">
<y:Geometry height="167.70803755785937" width="67.39999999999998" x="357.99770660400395" y="-6.390512714591921"/>
<y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" backgroundColor="#B7C9E3" configuration="com.yworks.entityRelationship.label.name" fontFamily="Dialog" fontSize="14" fontStyle="plain" hasLineColor="false" height="52.890625" modelName="internal" modelPosition="t" textColor="#000000" visible="true" width="73.1728515625" x="-2.8864257812500114" y="4.0">Glance
Domain
Controller</y:NodeLabel>
<y:NodeLabel alignment="center" autoSizePolicy="content" borderDistance="5.0" configuration="com.yworks.entityRelationship.label.attributes" fontFamily="Dialog" fontSize="14" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="101.78125" modelName="custom" textColor="#000000" visible="true" width="63.458984375" x="2.0" y="64.890625">Auth
Notifier
Policy
Quota
Location
DB<y:LabelModel>
<y:ErdAttributesNodeLabelModel/>
</y:LabelModel>
<y:ModelParameter>
<y:ErdAttributesNodeLabelModelParameter/>
</y:ModelParameter>
</y:NodeLabel>
<y:StyleProperties>
<y:Property class="java.lang.Boolean" name="y.view.ShadowNodePainter.SHADOW_PAINTING" value="true"/>
</y:StyleProperties>
</y:GenericNode>
</data>
</node>
<node id="n1::n4">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="73.31015624999992" width="30.0" x="277.0184097290039" y="100.3540486593156"/>
<y:Fill color="#CFE2F3" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="14" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="20.296875" modelName="custom" rotationAngle="270.0" textColor="#000000" visible="true" width="46.4033203125" x="4.8515625" y="13.45341796874996">AuthZ<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="rectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n1::n5">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="82.38854738860971" width="34.587519999999984" x="458.5772320883177" y="54.38402188052849"/>
<y:Fill color="#CFE2F3" transparent="false"/>
<y:BorderStyle color="#000000" type="dashed" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="14" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="36.59375" modelName="custom" rotationAngle="270.0" textColor="#000000" visible="true" width="61.94140625" x="-1.0031149999999798" y="10.223570569304854">Registry
Layer<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="roundrectangle"/>
</y:ShapeNode>
</data>
</node>
</graph>
</node>
<node id="n2" yfiles.foldertype="group">
<data key="d4"/>
<data key="d6">
<y:ProxyAutoBoundsNode>
<y:Realizers active="0">
<y:GroupNode>
<y:Geometry height="87.25366089528723" width="372.7381182861328" x="126.64775665295588" y="203.5500972234542"/>
<y:Fill color="#F5F5F5" transparent="false"/>
<y:BorderStyle color="#000000" type="dashed" width="1.0"/>
<y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="21.4609375" modelName="internal" modelPosition="t" textColor="#000000" visible="true" width="372.7381182861328" x="0.0" y="0.0">Glance Store</y:NodeLabel>
<y:Shape type="roundrectangle"/>
<y:State closed="false" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
<y:Insets bottom="15" bottomF="15.0" left="15" leftF="15.0" right="15" rightF="15.0" top="15" topF="15.0"/>
<y:BorderInsets bottom="1" bottomF="1.3333333333333712" left="0" leftF="0.0" right="0" rightF="0.0" top="4" topF="4.459390061953798"/>
</y:GroupNode>
<y:GroupNode>
<y:Geometry height="50.0" width="50.0" x="0.0" y="60.0"/>
<y:Fill color="#F5F5F5" transparent="false"/>
<y:BorderStyle color="#000000" type="dashed" width="1.0"/>
<y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="21.4609375" modelName="internal" modelPosition="t" textColor="#000000" visible="true" width="65.201171875" x="-7.6005859375" y="0.0">Folder 4</y:NodeLabel>
<y:Shape type="roundrectangle"/>
<y:State closed="true" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
<y:Insets bottom="5" bottomF="5.0" left="5" leftF="5.0" right="5" rightF="5.0" top="5" topF="5.0"/>
<y:BorderInsets bottom="0" bottomF="0.0" left="0" leftF="0.0" right="0" rightF="0.0" top="0" topF="0.0"/>
</y:GroupNode>
</y:Realizers>
</y:ProxyAutoBoundsNode>
</data>
<graph edgedefault="directed" id="n2:">
<node id="n2::n0">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="30.0" width="221.13579666137696" x="263.25007827771174" y="244.47042478540806"/>
<y:Fill color="#CFE2F3" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="14" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="20.296875" modelName="custom" textColor="#000000" visible="true" width="149.0859375" x="36.02492958068848" y="4.8515625">Glance Store Drivers<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="roundrectangle"/>
</y:ShapeNode>
</data>
</node>
<node id="n2::n1">
<data key="d5"/>
<data key="d6">
<y:ShapeNode>
<y:Geometry height="30.0" width="91.60232162475586" x="141.64775665295588" y="244.470424785408"/>
<y:Fill color="#CFE2F3" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="81.490234375" x="5.05604362487793" y="6.015624999999972">AuthN/AuthZ<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="rectangle"/>
</y:ShapeNode>
</data>
</node>
</graph>
</node>
<node id="n3" yfiles.foldertype="group">
<data key="d4"/>
<data key="d6">
<y:ProxyAutoBoundsNode>
<y:Realizers active="0">
<y:GroupNode>
<y:Geometry height="120.31768417358398" width="482.44128799438477" x="126.64775665295588" y="313.3428206187414"/>
<y:Fill color="#F5F5F5" transparent="false"/>
<y:BorderStyle color="#000000" type="dashed" width="1.0"/>
<y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="21.4609375" modelName="internal" modelPosition="t" textColor="#000000" visible="true" width="482.44128799438477" x="0.0" y="0.0">Supported Storages</y:NodeLabel>
<y:Shape type="roundrectangle"/>
<y:State closed="false" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
<y:Insets bottom="15" bottomF="15.0" left="15" leftF="15.0" right="15" rightF="15.0" top="15" topF="15.0"/>
<y:BorderInsets bottom="0" bottomF="0.0" left="0" leftF="0.0" right="0" rightF="0.0" top="0" topF="0.0"/>
</y:GroupNode>
<y:GroupNode>
<y:Geometry height="50.0" width="50.0" x="0.0" y="60.0"/>
<y:Fill color="#F5F5F5" transparent="false"/>
<y:BorderStyle color="#000000" type="dashed" width="1.0"/>
<y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="21.4609375" modelName="internal" modelPosition="t" textColor="#000000" visible="true" width="65.201171875" x="-7.6005859375" y="0.0">Folder 5</y:NodeLabel>
<y:Shape type="roundrectangle"/>
<y:State closed="true" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
<y:Insets bottom="5" bottomF="5.0" left="5" leftF="5.0" right="5" rightF="5.0" top="5" topF="5.0"/>
<y:BorderInsets bottom="0" bottomF="0.0" left="0" leftF="0.0" right="0" rightF="0.0" top="0" topF="0.0"/>
</y:GroupNode>
</y:Realizers>
</y:ProxyAutoBoundsNode>
</data>
<graph edgedefault="directed" id="n3:">
<node id="n3::n0">
<data key="d6">
<y:SVGNode>
<y:Geometry height="46.887996673583984" width="39.527000427246094" x="233.28872497570978" y="349.8037581187414"/>
<y:Fill color="#CCCCFF" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="33.6953125" x="2.915843963623047" y="50.887996673583984">Swift<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="-0.5" nodeRatioX="0.0" nodeRatioY="0.5" offsetX="0.0" offsetY="4.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:SVGNodeProperties usingVisualBounds="true"/>
<y:SVGModel svgBoundsPolicy="0">
<y:SVGContent refid="2"/>
</y:SVGModel>
</y:SVGNode>
</data>
</node>
<node id="n3::n1">
<data key="d6">
<y:SVGNode>
<y:Geometry height="46.887996673583984" width="39.527000427246094" x="310.52522476208674" y="349.8037581187414"/>
<y:Fill color="#CCCCFF" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="19.251953125" x="10.137523651123047" y="50.887996673583984">S3<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="-0.5" nodeRatioX="0.0" nodeRatioY="0.5" offsetX="0.0" offsetY="4.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:SVGNodeProperties usingVisualBounds="true"/>
<y:SVGModel svgBoundsPolicy="0">
<y:SVGContent refid="2"/>
</y:SVGModel>
</y:SVGNode>
</data>
</node>
<node id="n3::n2">
<data key="d6">
<y:SVGNode>
<y:Geometry height="46.887996673583984" width="39.527000427246094" x="387.7617245484637" y="349.8037581187414"/>
<y:Fill color="#CCCCFF" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="34.984375" x="2.271312713623047" y="50.887996673583984">Ceph<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="-0.5" nodeRatioX="0.0" nodeRatioY="0.5" offsetX="0.0" offsetY="4.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:SVGNodeProperties usingVisualBounds="true"/>
<y:SVGModel svgBoundsPolicy="0">
<y:SVGContent refid="2"/>
</y:SVGModel>
</y:SVGNode>
</data>
</node>
<node id="n3::n3">
<data key="d6">
<y:SVGNode>
<y:Geometry height="46.887996673583984" width="39.527000427246094" x="542.2347241212176" y="349.8037581187414"/>
<y:Fill color="#CCCCFF" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="64.181640625" x="-12.327320098876953" y="50.887996673583984">Sheepdog<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="-0.5" nodeRatioX="0.0" nodeRatioY="0.5" offsetX="0.0" offsetY="4.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:SVGNodeProperties usingVisualBounds="true"/>
<y:SVGModel svgBoundsPolicy="0">
<y:SVGContent refid="2"/>
</y:SVGModel>
</y:SVGNode>
</data>
</node>
<node id="n3::n4">
<data key="d6">
<y:SVGNode>
<y:Geometry height="46.887996673583984" width="39.527000427246094" x="464.99822433484064" y="349.8037581187414"/>
<y:Fill color="#CCCCFF" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="15.443359375" x="12.041820526123047" y="50.887996673583984">...<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="-0.5" nodeRatioX="0.0" nodeRatioY="0.5" offsetX="0.0" offsetY="4.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:SVGNodeProperties usingVisualBounds="true"/>
<y:SVGModel svgBoundsPolicy="0">
<y:SVGContent refid="2"/>
</y:SVGModel>
</y:SVGNode>
</data>
</node>
<node id="n3::n5">
<data key="d6">
<y:SVGNode>
<y:Geometry height="46.887996673583984" width="39.527000427246094" x="156.05222518933283" y="349.8037581187414"/>
<y:Fill color="#CCCCFF" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="68.3359375" x="-14.404468536376953" y="50.887996673583984">Filesystem<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="-0.5" nodeRatioX="0.0" nodeRatioY="0.5" offsetX="0.0" offsetY="4.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:SVGNodeProperties usingVisualBounds="true"/>
<y:SVGModel svgBoundsPolicy="0">
<y:SVGContent refid="2"/>
</y:SVGModel>
</y:SVGNode>
</data>
</node>
</graph>
</node>
<node id="n4" yfiles.foldertype="group">
<data key="d4"/>
<data key="d6">
<y:ProxyAutoBoundsNode>
<y:Realizers active="0">
<y:GroupNode>
<y:Geometry height="82.38854738860971" width="116.67238708489901" x="126.64775665295588" y="-56.61171875000008"/>
<y:Fill color="#F5F5F5" transparent="false"/>
<y:BorderStyle color="#000000" type="dashed" width="1.0"/>
<y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="21.4609375" modelName="internal" modelPosition="t" textColor="#000000" visible="true" width="116.67238708489901" x="0.0" y="0.0">A client</y:NodeLabel>
<y:Shape type="roundrectangle"/>
<y:State closed="false" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
<y:Insets bottom="15" bottomF="15.0" left="15" leftF="15.0" right="15" rightF="15.0" top="15" topF="15.0"/>
<y:BorderInsets bottom="7" bottomF="7.3276098886097145" left="4" leftF="4.350065460143156" right="9" rightF="9.280000000000001" top="0" topF="0.0"/>
</y:GroupNode>
<y:GroupNode>
<y:Geometry height="50.0" width="50.0" x="0.0" y="60.0"/>
<y:Fill color="#F5F5F5" transparent="false"/>
<y:BorderStyle color="#000000" type="dashed" width="1.0"/>
<y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="21.4609375" modelName="internal" modelPosition="t" textColor="#000000" visible="true" width="65.201171875" x="-7.6005859375" y="0.0">Folder 7</y:NodeLabel>
<y:Shape type="roundrectangle"/>
<y:State closed="true" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
<y:Insets bottom="5" bottomF="5.0" left="5" leftF="5.0" right="5" rightF="5.0" top="5" topF="5.0"/>
<y:BorderInsets bottom="0" bottomF="0.0" left="0" leftF="0.0" right="0" rightF="0.0" top="0" topF="0.0"/>
</y:GroupNode>
</y:Realizers>
</y:ProxyAutoBoundsNode>
</data>
<graph edgedefault="directed" id="n4:">
<node id="n4::n0">
<data key="d6">
<y:ShapeNode>
<y:Geometry height="23.599999999999994" width="73.04232162475586" x="145.99782211309903" y="-20.15078125000008"/>
<y:Fill color="#CFE2F3" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="41.1015625" x="15.970379562377929" y="2.815624999999997">AuthN<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
<y:Shape type="rectangle"/>
</y:ShapeNode>
</data>
</node>
</graph>
</node>
<edge id="e0" source="n4" target="n1::n0">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="58.32816665216302" sy="12.506663805695155" tx="-15.011292881435509" ty="-34.942883704657845"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e1" source="n2::n0" target="n3::n0">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e2" source="n2::n0" target="n3::n1">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e3" source="n2::n0" target="n3::n2">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e4" source="n2::n0" target="n3::n4">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e5" source="n2::n0" target="n3::n3">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="n1::e0" source="n1::n2" target="n1::n1">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="-0.677778248786808" ty="18.374437598873158"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e6" source="n1" target="n1::n3">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="-112.55865812122867" sy="-30.426253688481314" tx="-11.222289489306997" ty="-60.26124827714441"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e7" source="n1" target="n1::n2">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="-45.40152409183127" sy="82.03123343692525" tx="0.0" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="n1::e1" source="n1::n0" target="n1::n3">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="-17.387848956502122" ty="-45.43140360967999"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="n1::e2" source="n1::n3" target="n1::n4">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="-24.26150334743697" sy="-7.984957560950406" tx="0.0" ty="0.0">
<y:Point x="327.01145599999995" y="69.47854850338736"/>
<y:Point x="327.01145599999995" y="137.00912678431555"/>
</y:Path>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e8" source="n1::n4" target="n0::n0">
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="40.885760959262484" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e9" source="n1::n3" target="n2::n0">
<data key="d9"/>
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="-33.69779049576158" sy="56.756894670177246" tx="-35.51082494315817" ty="-4.970424785408056">
<y:Point x="338.30715166524203" y="134.220400734515"/>
</y:Path>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="n1::e3" source="n1::n3" target="n1::n2">
<data key="d9"/>
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="6.30229339599606" sy="74.03649393566224" tx="-3.6535432435317716" ty="18.68247515673255"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="n1::e4" source="n1::n3" target="n1::n5">
<data key="d9"/>
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="32.82803356803731" sy="74.0250641592717" tx="-0.3616713564354086" ty="-14.745599999999996">
<y:Point x="439.24713382695796" y="151.48857022360946"/>
<y:Point x="439.24713382695796" y="80.83269557483335"/>
</y:Path>
<y:LineStyle color="#000000" type="dashed" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="n1::e5" source="n1::n5" target="n1::n2">
<data key="d9"/>
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.949048643564538" sy="-15.707648031929011" tx="-26.87798799596328" ty="-5.105597300363115">
<y:Point x="523.7755552475685" y="79.87064754290434"/>
</y:Path>
<y:LineStyle color="#000000" type="dashed" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="n2::e0" source="n2::n0" target="n2::n1">
<data key="d9"/>
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e10" source="n2::n1" target="n0::n0">
<data key="d9"/>
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="-4.929934539856845" sy="-15.002176922503736" tx="0.0" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e11" source="n2::n0" target="n3::n5">
<data key="d9"/>
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e12" source="n4::n0" target="n0::n0">
<data key="d9"/>
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
</graph>
<data key="d7">
<y:Resources>
<y:Resource id="1">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;svg version="1.1"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
x="0px" y="0px" width="40px" height="48px" viewBox="0 0 40 48" enable-background="new 0 0 40 48" xml:space="preserve"&gt;
&lt;defs&gt;
&lt;/defs&gt;
&lt;linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="370.2002" y1="655.0938" x2="409.4502" y2="655.0938" gradientTransform="matrix(1 0 0 1 -370.2002 -614.5742)"&gt;
&lt;stop offset="0" style="stop-color:#4D4D4D"/&gt;
&lt;stop offset="0.0558" style="stop-color:#5F5F5F"/&gt;
&lt;stop offset="0.2103" style="stop-color:#8D8D8D"/&gt;
&lt;stop offset="0.3479" style="stop-color:#AEAEAE"/&gt;
&lt;stop offset="0.4623" style="stop-color:#C2C2C2"/&gt;
&lt;stop offset="0.5394" style="stop-color:#C9C9C9"/&gt;
&lt;stop offset="0.6247" style="stop-color:#C5C5C5"/&gt;
&lt;stop offset="0.7072" style="stop-color:#BABABA"/&gt;
&lt;stop offset="0.7885" style="stop-color:#A6A6A6"/&gt;
&lt;stop offset="0.869" style="stop-color:#8B8B8B"/&gt;
&lt;stop offset="0.9484" style="stop-color:#686868"/&gt;
&lt;stop offset="1" style="stop-color:#4D4D4D"/&gt;
&lt;/linearGradient&gt;
&lt;path fill="url(#SVGID_1_)" d="M19.625,37.613C8.787,37.613,0,35.738,0,33.425v10c0,2.313,8.787,4.188,19.625,4.188
c10.839,0,19.625-1.875,19.625-4.188v-10C39.25,35.738,30.464,37.613,19.625,37.613z"/&gt;
&lt;linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="370.2002" y1="649.0938" x2="409.4502" y2="649.0938" gradientTransform="matrix(1 0 0 1 -370.2002 -614.5742)"&gt;
&lt;stop offset="0" style="stop-color:#B3B3B3"/&gt;
&lt;stop offset="0.0171" style="stop-color:#B6B6B6"/&gt;
&lt;stop offset="0.235" style="stop-color:#D7D7D7"/&gt;
&lt;stop offset="0.4168" style="stop-color:#EBEBEB"/&gt;
&lt;stop offset="0.5394" style="stop-color:#F2F2F2"/&gt;
&lt;stop offset="0.6579" style="stop-color:#EEEEEE"/&gt;
&lt;stop offset="0.7724" style="stop-color:#E3E3E3"/&gt;
&lt;stop offset="0.8853" style="stop-color:#CFCFCF"/&gt;
&lt;stop offset="0.9965" style="stop-color:#B4B4B4"/&gt;
&lt;stop offset="1" style="stop-color:#B3B3B3"/&gt;
&lt;/linearGradient&gt;
&lt;path fill="url(#SVGID_2_)" d="M19.625,37.613c10.839,0,19.625-1.875,19.625-4.188l-1.229-2c0,2.168-8.235,3.927-18.396,3.927
c-9.481,0-17.396-1.959-18.396-3.927l-1.229,2C0,35.738,8.787,37.613,19.625,37.613z"/&gt;
&lt;linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="371.4297" y1="646" x2="408.2217" y2="646" gradientTransform="matrix(1 0 0 1 -370.2002 -614.5742)"&gt;
&lt;stop offset="0" style="stop-color:#C9C9C9"/&gt;
&lt;stop offset="1" style="stop-color:#808080"/&gt;
&lt;/linearGradient&gt;
&lt;ellipse fill="url(#SVGID_3_)" cx="19.625" cy="31.425" rx="18.396" ry="3.926"/&gt;
&lt;linearGradient id="SVGID_4_" gradientUnits="userSpaceOnUse" x1="370.2002" y1="641.0938" x2="409.4502" y2="641.0938" gradientTransform="matrix(1 0 0 1 -370.2002 -614.5742)"&gt;
&lt;stop offset="0" style="stop-color:#4D4D4D"/&gt;
&lt;stop offset="0.0558" style="stop-color:#5F5F5F"/&gt;
&lt;stop offset="0.2103" style="stop-color:#8D8D8D"/&gt;
&lt;stop offset="0.3479" style="stop-color:#AEAEAE"/&gt;
&lt;stop offset="0.4623" style="stop-color:#C2C2C2"/&gt;
&lt;stop offset="0.5394" style="stop-color:#C9C9C9"/&gt;
&lt;stop offset="0.6247" style="stop-color:#C5C5C5"/&gt;
&lt;stop offset="0.7072" style="stop-color:#BABABA"/&gt;
&lt;stop offset="0.7885" style="stop-color:#A6A6A6"/&gt;
&lt;stop offset="0.869" style="stop-color:#8B8B8B"/&gt;
&lt;stop offset="0.9484" style="stop-color:#686868"/&gt;
&lt;stop offset="1" style="stop-color:#4D4D4D"/&gt;
&lt;/linearGradient&gt;
&lt;path fill="url(#SVGID_4_)" d="M19.625,23.613C8.787,23.613,0,21.738,0,19.425v10c0,2.313,8.787,4.188,19.625,4.188
c10.839,0,19.625-1.875,19.625-4.188v-10C39.25,21.738,30.464,23.613,19.625,23.613z"/&gt;
&lt;linearGradient id="SVGID_5_" gradientUnits="userSpaceOnUse" x1="370.2002" y1="635.0938" x2="409.4502" y2="635.0938" gradientTransform="matrix(1 0 0 1 -370.2002 -614.5742)"&gt;
&lt;stop offset="0" style="stop-color:#B3B3B3"/&gt;
&lt;stop offset="0.0171" style="stop-color:#B6B6B6"/&gt;
&lt;stop offset="0.235" style="stop-color:#D7D7D7"/&gt;
&lt;stop offset="0.4168" style="stop-color:#EBEBEB"/&gt;
&lt;stop offset="0.5394" style="stop-color:#F2F2F2"/&gt;
&lt;stop offset="0.6579" style="stop-color:#EEEEEE"/&gt;
&lt;stop offset="0.7724" style="stop-color:#E3E3E3"/&gt;
&lt;stop offset="0.8853" style="stop-color:#CFCFCF"/&gt;
&lt;stop offset="0.9965" style="stop-color:#B4B4B4"/&gt;
&lt;stop offset="1" style="stop-color:#B3B3B3"/&gt;
&lt;/linearGradient&gt;
&lt;path fill="url(#SVGID_5_)" d="M19.625,23.613c10.839,0,19.625-1.875,19.625-4.188l-1.229-2c0,2.168-8.235,3.926-18.396,3.926
c-9.481,0-17.396-1.959-18.396-3.926l-1.229,2C0,21.738,8.787,23.613,19.625,23.613z"/&gt;
&lt;linearGradient id="SVGID_6_" gradientUnits="userSpaceOnUse" x1="371.4297" y1="632" x2="408.2217" y2="632" gradientTransform="matrix(1 0 0 1 -370.2002 -614.5742)"&gt;
&lt;stop offset="0" style="stop-color:#C9C9C9"/&gt;
&lt;stop offset="1" style="stop-color:#808080"/&gt;
&lt;/linearGradient&gt;
&lt;ellipse fill="url(#SVGID_6_)" cx="19.625" cy="17.426" rx="18.396" ry="3.926"/&gt;
&lt;linearGradient id="SVGID_7_" gradientUnits="userSpaceOnUse" x1="370.2002" y1="627.5938" x2="409.4502" y2="627.5938" gradientTransform="matrix(1 0 0 1 -370.2002 -614.5742)"&gt;
&lt;stop offset="0" style="stop-color:#4D4D4D"/&gt;
&lt;stop offset="0.0558" style="stop-color:#5F5F5F"/&gt;
&lt;stop offset="0.2103" style="stop-color:#8D8D8D"/&gt;
&lt;stop offset="0.3479" style="stop-color:#AEAEAE"/&gt;
&lt;stop offset="0.4623" style="stop-color:#C2C2C2"/&gt;
&lt;stop offset="0.5394" style="stop-color:#C9C9C9"/&gt;
&lt;stop offset="0.6247" style="stop-color:#C5C5C5"/&gt;
&lt;stop offset="0.7072" style="stop-color:#BABABA"/&gt;
&lt;stop offset="0.7885" style="stop-color:#A6A6A6"/&gt;
&lt;stop offset="0.869" style="stop-color:#8B8B8B"/&gt;
&lt;stop offset="0.9484" style="stop-color:#686868"/&gt;
&lt;stop offset="1" style="stop-color:#4D4D4D"/&gt;
&lt;/linearGradient&gt;
&lt;path fill="url(#SVGID_7_)" d="M19.625,10.113C8.787,10.113,0,8.238,0,5.925v10c0,2.313,8.787,4.188,19.625,4.188
c10.839,0,19.625-1.875,19.625-4.188v-10C39.25,8.238,30.464,10.113,19.625,10.113z"/&gt;
&lt;linearGradient id="SVGID_8_" gradientUnits="userSpaceOnUse" x1="370.2002" y1="621.5938" x2="409.4502" y2="621.5938" gradientTransform="matrix(1 0 0 1 -370.2002 -614.5742)"&gt;
&lt;stop offset="0" style="stop-color:#B3B3B3"/&gt;
&lt;stop offset="0.0171" style="stop-color:#B6B6B6"/&gt;
&lt;stop offset="0.235" style="stop-color:#D7D7D7"/&gt;
&lt;stop offset="0.4168" style="stop-color:#EBEBEB"/&gt;
&lt;stop offset="0.5394" style="stop-color:#F2F2F2"/&gt;
&lt;stop offset="0.6579" style="stop-color:#EEEEEE"/&gt;
&lt;stop offset="0.7724" style="stop-color:#E3E3E3"/&gt;
&lt;stop offset="0.8853" style="stop-color:#CFCFCF"/&gt;
&lt;stop offset="0.9965" style="stop-color:#B4B4B4"/&gt;
&lt;stop offset="1" style="stop-color:#B3B3B3"/&gt;
&lt;/linearGradient&gt;
&lt;path fill="url(#SVGID_8_)" d="M19.625,10.113c10.839,0,19.625-1.875,19.625-4.188l-1.229-2c0,2.168-8.235,3.926-18.396,3.926
c-9.481,0-17.396-1.959-18.396-3.926L0,5.925C0,8.238,8.787,10.113,19.625,10.113z"/&gt;
&lt;linearGradient id="SVGID_9_" gradientUnits="userSpaceOnUse" x1="371.4297" y1="618.5" x2="408.2217" y2="618.5" gradientTransform="matrix(1 0 0 1 -370.2002 -614.5742)"&gt;
&lt;stop offset="0" style="stop-color:#C9C9C9"/&gt;
&lt;stop offset="1" style="stop-color:#808080"/&gt;
&lt;/linearGradient&gt;
&lt;ellipse fill="url(#SVGID_9_)" cx="19.625" cy="3.926" rx="18.396" ry="3.926"/&gt;
&lt;path opacity="0.24" fill="#FFFFFF" enable-background="new " d="M31.291,46.792c0,0-4.313,0.578-7.249,0.694
C20.917,47.613,15,47.613,15,47.613l-2.443-10.279l-0.119-2.283l-1.231-1.842L9.789,23.024l-0.082-0.119L9.3,20.715l-1.45-1.44
L5.329,8.793c0,0,5.296,0.882,7.234,1.07s8.375,0.25,8.375,0.25l3,9.875l-0.25,1.313l1.063,2.168l2.312,9.644l-0.375,1.875
l1.627,2.193L31.291,46.792z"/&gt;
&lt;/svg&gt;
</y:Resource>
<y:Resource id="2">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;svg version="1.1"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
x="0px" y="0px" width="41px" height="48px" viewBox="-0.875 -0.887 41 48" enable-background="new -0.875 -0.887 41 48"
xml:space="preserve"&gt;
&lt;defs&gt;
&lt;/defs&gt;
&lt;linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="642.8008" y1="-979.1445" x2="682.0508" y2="-979.1445" gradientTransform="matrix(1 0 0 -1 -642.8008 -939.4756)"&gt;
&lt;stop offset="0" style="stop-color:#3C89C9"/&gt;
&lt;stop offset="0.1482" style="stop-color:#60A6DD"/&gt;
&lt;stop offset="0.3113" style="stop-color:#81C1F0"/&gt;
&lt;stop offset="0.4476" style="stop-color:#95D1FB"/&gt;
&lt;stop offset="0.5394" style="stop-color:#9CD7FF"/&gt;
&lt;stop offset="0.636" style="stop-color:#98D4FD"/&gt;
&lt;stop offset="0.7293" style="stop-color:#8DCAF6"/&gt;
&lt;stop offset="0.8214" style="stop-color:#79BBEB"/&gt;
&lt;stop offset="0.912" style="stop-color:#5EA5DC"/&gt;
&lt;stop offset="1" style="stop-color:#3C89C9"/&gt;
&lt;/linearGradient&gt;
&lt;path fill="url(#SVGID_1_)" d="M19.625,36.763C8.787,36.763,0,34.888,0,32.575v10c0,2.313,8.787,4.188,19.625,4.188
c10.839,0,19.625-1.875,19.625-4.188v-10C39.25,34.888,30.464,36.763,19.625,36.763z"/&gt;
&lt;linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="642.8008" y1="-973.1445" x2="682.0508" y2="-973.1445" gradientTransform="matrix(1 0 0 -1 -642.8008 -939.4756)"&gt;
&lt;stop offset="0" style="stop-color:#9CD7FF"/&gt;
&lt;stop offset="0.0039" style="stop-color:#9DD7FF"/&gt;
&lt;stop offset="0.2273" style="stop-color:#BDE5FF"/&gt;
&lt;stop offset="0.4138" style="stop-color:#D1EEFF"/&gt;
&lt;stop offset="0.5394" style="stop-color:#D9F1FF"/&gt;
&lt;stop offset="0.6155" style="stop-color:#D5EFFE"/&gt;
&lt;stop offset="0.6891" style="stop-color:#C9E7FA"/&gt;
&lt;stop offset="0.7617" style="stop-color:#B6DAF3"/&gt;
&lt;stop offset="0.8337" style="stop-color:#9AC8EA"/&gt;
&lt;stop offset="0.9052" style="stop-color:#77B0DD"/&gt;
&lt;stop offset="0.9754" style="stop-color:#4D94CF"/&gt;
&lt;stop offset="1" style="stop-color:#3C89C9"/&gt;
&lt;/linearGradient&gt;
&lt;path fill="url(#SVGID_2_)" d="M19.625,36.763c10.839,0,19.625-1.875,19.625-4.188l-1.229-2c0,2.168-8.235,3.927-18.396,3.927
c-9.481,0-17.396-1.959-18.396-3.927l-1.229,2C0,34.888,8.787,36.763,19.625,36.763z"/&gt;
&lt;path fill="#3C89C9" d="M19.625,26.468c10.16,0,19.625,2.775,19.625,2.775c-0.375,2.721-5.367,5.438-19.554,5.438
c-12.125,0-18.467-2.484-19.541-4.918C-0.127,29.125,9.465,26.468,19.625,26.468z"/&gt;
&lt;linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="642.8008" y1="-965.6948" x2="682.0508" y2="-965.6948" gradientTransform="matrix(1 0 0 -1 -642.8008 -939.4756)"&gt;
&lt;stop offset="0" style="stop-color:#3C89C9"/&gt;
&lt;stop offset="0.1482" style="stop-color:#60A6DD"/&gt;
&lt;stop offset="0.3113" style="stop-color:#81C1F0"/&gt;
&lt;stop offset="0.4476" style="stop-color:#95D1FB"/&gt;
&lt;stop offset="0.5394" style="stop-color:#9CD7FF"/&gt;
&lt;stop offset="0.636" style="stop-color:#98D4FD"/&gt;
&lt;stop offset="0.7293" style="stop-color:#8DCAF6"/&gt;
&lt;stop offset="0.8214" style="stop-color:#79BBEB"/&gt;
&lt;stop offset="0.912" style="stop-color:#5EA5DC"/&gt;
&lt;stop offset="1" style="stop-color:#3C89C9"/&gt;
&lt;/linearGradient&gt;
&lt;path fill="url(#SVGID_3_)" d="M19.625,23.313C8.787,23.313,0,21.438,0,19.125v10c0,2.313,8.787,4.188,19.625,4.188
c10.839,0,19.625-1.875,19.625-4.188v-10C39.25,21.438,30.464,23.313,19.625,23.313z"/&gt;
&lt;linearGradient id="SVGID_4_" gradientUnits="userSpaceOnUse" x1="642.8008" y1="-959.6948" x2="682.0508" y2="-959.6948" gradientTransform="matrix(1 0 0 -1 -642.8008 -939.4756)"&gt;
&lt;stop offset="0" style="stop-color:#9CD7FF"/&gt;
&lt;stop offset="0.0039" style="stop-color:#9DD7FF"/&gt;
&lt;stop offset="0.2273" style="stop-color:#BDE5FF"/&gt;
&lt;stop offset="0.4138" style="stop-color:#D1EEFF"/&gt;
&lt;stop offset="0.5394" style="stop-color:#D9F1FF"/&gt;
&lt;stop offset="0.6155" style="stop-color:#D5EFFE"/&gt;
&lt;stop offset="0.6891" style="stop-color:#C9E7FA"/&gt;
&lt;stop offset="0.7617" style="stop-color:#B6DAF3"/&gt;
&lt;stop offset="0.8337" style="stop-color:#9AC8EA"/&gt;
&lt;stop offset="0.9052" style="stop-color:#77B0DD"/&gt;
&lt;stop offset="0.9754" style="stop-color:#4D94CF"/&gt;
&lt;stop offset="1" style="stop-color:#3C89C9"/&gt;
&lt;/linearGradient&gt;
&lt;path fill="url(#SVGID_4_)" d="M19.625,23.313c10.839,0,19.625-1.875,19.625-4.188l-1.229-2c0,2.168-8.235,3.926-18.396,3.926
c-9.481,0-17.396-1.959-18.396-3.926l-1.229,2C0,21.438,8.787,23.313,19.625,23.313z"/&gt;
&lt;path fill="#3C89C9" d="M19.476,13.019c10.161,0,19.625,2.775,19.625,2.775c-0.375,2.721-5.367,5.438-19.555,5.438
c-12.125,0-18.467-2.485-19.541-4.918C-0.277,15.674,9.316,13.019,19.476,13.019z"/&gt;
&lt;linearGradient id="SVGID_5_" gradientUnits="userSpaceOnUse" x1="642.8008" y1="-952.4946" x2="682.0508" y2="-952.4946" gradientTransform="matrix(1 0 0 -1 -642.8008 -939.4756)"&gt;
&lt;stop offset="0" style="stop-color:#3C89C9"/&gt;
&lt;stop offset="0.1482" style="stop-color:#60A6DD"/&gt;
&lt;stop offset="0.3113" style="stop-color:#81C1F0"/&gt;
&lt;stop offset="0.4476" style="stop-color:#95D1FB"/&gt;
&lt;stop offset="0.5394" style="stop-color:#9CD7FF"/&gt;
&lt;stop offset="0.636" style="stop-color:#98D4FD"/&gt;
&lt;stop offset="0.7293" style="stop-color:#8DCAF6"/&gt;
&lt;stop offset="0.8214" style="stop-color:#79BBEB"/&gt;
&lt;stop offset="0.912" style="stop-color:#5EA5DC"/&gt;
&lt;stop offset="1" style="stop-color:#3C89C9"/&gt;
&lt;/linearGradient&gt;
&lt;path fill="url(#SVGID_5_)" d="M19.625,10.113C8.787,10.113,0,8.238,0,5.925v10c0,2.313,8.787,4.188,19.625,4.188
c10.839,0,19.625-1.875,19.625-4.188v-10C39.25,8.238,30.464,10.113,19.625,10.113z"/&gt;
&lt;linearGradient id="SVGID_6_" gradientUnits="userSpaceOnUse" x1="642.8008" y1="-946.4946" x2="682.0508" y2="-946.4946" gradientTransform="matrix(1 0 0 -1 -642.8008 -939.4756)"&gt;
&lt;stop offset="0" style="stop-color:#9CD7FF"/&gt;
&lt;stop offset="0.0039" style="stop-color:#9DD7FF"/&gt;
&lt;stop offset="0.2273" style="stop-color:#BDE5FF"/&gt;
&lt;stop offset="0.4138" style="stop-color:#D1EEFF"/&gt;
&lt;stop offset="0.5394" style="stop-color:#D9F1FF"/&gt;
&lt;stop offset="0.6155" style="stop-color:#D5EFFE"/&gt;
&lt;stop offset="0.6891" style="stop-color:#C9E7FA"/&gt;
&lt;stop offset="0.7617" style="stop-color:#B6DAF3"/&gt;
&lt;stop offset="0.8337" style="stop-color:#9AC8EA"/&gt;
&lt;stop offset="0.9052" style="stop-color:#77B0DD"/&gt;
&lt;stop offset="0.9754" style="stop-color:#4D94CF"/&gt;
&lt;stop offset="1" style="stop-color:#3C89C9"/&gt;
&lt;/linearGradient&gt;
&lt;path fill="url(#SVGID_6_)" d="M19.625,10.113c10.839,0,19.625-1.875,19.625-4.188l-1.229-2c0,2.168-8.235,3.926-18.396,3.926
c-9.481,0-17.396-1.959-18.396-3.926L0,5.925C0,8.238,8.787,10.113,19.625,10.113z"/&gt;
&lt;linearGradient id="SVGID_7_" gradientUnits="userSpaceOnUse" x1="644.0293" y1="-943.4014" x2="680.8223" y2="-943.4014" gradientTransform="matrix(1 0 0 -1 -642.8008 -939.4756)"&gt;
&lt;stop offset="0" style="stop-color:#9CD7FF"/&gt;
&lt;stop offset="1" style="stop-color:#3C89C9"/&gt;
&lt;/linearGradient&gt;
&lt;ellipse fill="url(#SVGID_7_)" cx="19.625" cy="3.926" rx="18.396" ry="3.926"/&gt;
&lt;path opacity="0.24" fill="#FFFFFF" enable-background="new " d="M31.04,45.982c0,0-4.354,0.664-7.29,0.781
c-3.125,0.125-8.952,0-8.952,0l-2.384-10.292l0.044-2.108l-1.251-1.154L9.789,23.024l-0.082-0.119L9.5,20.529l-1.65-1.254
L5.329,8.793c0,0,4.213,0.903,7.234,1.07s8.375,0.25,8.375,0.25l3,9.875l-0.25,1.313l1.063,2.168l2.312,9.645l-0.521,1.416
l1.46,1.834L31.04,45.982z"/&gt;
&lt;/svg&gt;
</y:Resource>
</y:Resources>
</data>
</graphml>

View File

@ -1,51 +0,0 @@
/*
# All Rights Reserved.
# Copyright 2013 IBM Corp.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
*/
/*
This file can be compiled by graphviz with issuing the following command:
dot -Tpng -oimage_status_transition.png image_status_transition.dot
See http://www.graphviz.org to get more info.
*/
digraph {
node [shape="doublecircle" color="#006699" style="filled"
fillcolor="#33CCFF" fixedsize="True" width="1.5" height="1.5"];
"" -> "queued" [label="create image"];
"queued" -> "active" [label="add location*"];
"queued" -> "saving" [label="upload"];
"queued" -> "deleted" [label="delete"];
"saving" -> "active" [label="upload succeed"];
"saving" -> "killed" [label="upload fail"];
"saving" -> "deleted" [label="delete"];
"active" -> "queued" [label="remove location*"];
"active" -> "pending_delete" [label="delayed delete"];
"active" -> "deleted" [label="delete"];
"active" -> "deactivated" [label="deactivate"];
"deactivated" -> "active" [label="reactivate"];
"deactivated" -> "deleted" [label="delete"];
"killed" -> "deleted" [label="delete"];
"pending_delete" -> "deleted" [label="after scrub time"];
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 153 KiB

View File

@ -1,90 +0,0 @@
..
Copyright 2010 OpenStack Foundation
All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may
not use this file except in compliance with the License. You may obtain
a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations
under the License.
Welcome to Glance's documentation!
==================================
The Glance project provides a service where users can upload and discover
data assets that are meant to be used with other services. This currently
includes images and metadata definitions.
Glance image services include discovering, registering, and
retrieving virtual machine images. Glance has a RESTful API that allows
querying of VM image metadata as well as retrieval of the actual image.
VM images made available through Glance can be stored in a variety of
locations from simple filesystems to object-storage systems like the
OpenStack Swift project.
Glance, as with all OpenStack projects, is written with the following design
guidelines in mind:
* **Component based architecture**: Quickly add new behaviors
* **Highly available**: Scale to very serious workloads
* **Fault tolerant**: Isolated processes avoid cascading failures
* **Recoverable**: Failures should be easy to diagnose, debug, and rectify
* **Open standards**: Be a reference implementation for a community-driven api
This documentation is generated by the Sphinx toolkit and lives in the source
tree. Additional documentation on Glance and other components of OpenStack can
be found on the `OpenStack wiki`_.
.. _`OpenStack wiki`: http://wiki.openstack.org
Glance Background Concepts
==========================
.. toctree::
:maxdepth: 1
architecture
identifiers
statuses
formats
common-image-properties
metadefs-concepts
Installing/Configuring Glance
=============================
.. toctree::
:maxdepth: 1
installing
configuring
authentication
policies
Operating Glance
================
.. toctree::
:maxdepth: 1
controllingservers
db
cache
notifications
Using Glance
============
.. toctree::
:maxdepth: 1
daisyapi
daisyclient
daisymetadefcatalogapi

View File

@ -1,179 +0,0 @@
..
Copyright 2011 OpenStack Foundation
All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may
not use this file except in compliance with the License. You may obtain
a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations
under the License.
Installation
============
Installing from packages
~~~~~~~~~~~~~~~~~~~~~~~~
To install the latest released version of Glance,
follow the following instructions.
Debian, Ubuntu
##############
1. Add the Glance PPA to your sources.lst::
$> sudo add-apt-repository ppa:glance-core/trunk
$> sudo apt-get update
2. Install Glance::
$> sudo apt-get install glance
Red Hat, Fedora
###############
Only RHEL 6, Fedora 18, and newer releases have the necessary
components packaged.
On RHEL 6, enable the EPEL repository.
Install Glance::
$ su -
# yum install openstack-glance
openSUSE, SLE
#############
openSUSE 13.2, SLE 12, and the rolling release Factory needs an extra
repository enabled to install all the OpenStack packages.
Search the proper repository in the `Cloud:OpenStack:Master <https://build.opensuse.org/project/repositories/Cloud:OpenStack:Master>`_ project. For example, for openSUSE 13.2:
1. Add the OpenStack master repository::
$ sudo zypper ar -f -g http://download.opensuse.org/repositories/Cloud:/OpenStack:/Master/openSUSE_13.2/ OpenStack
$ sudo zypper ref
2. Install Glance::
$ sudo zypper in openstack-glance
Installing from source tarballs
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To install the latest version of Glance from the Launchpad Bazaar repositories,
following the following instructions.
1. Grab the source tarball from `Launchpad <http://launchpad.net/glance/+download>`_
2. Untar the source tarball::
$> tar -xzf <FILE>
3. Change into the package directory and build/install::
$> cd glance-<RELEASE>
$> sudo python setup.py install
Installing from Git
~~~~~~~~~~~~~~~~~~~
To install the latest version of Glance from the GitHub Git repositories,
following the following instructions.
Debian, Ubuntu
##############
1. Install Git and build dependencies::
$> sudo apt-get install git
$> sudo apt-get build-dep glance
.. note::
If you want to build the Glance documentation locally, you will also want
to install the python-sphinx package
2. Clone Glance's trunk branch from GitHub::
$> git clone git://github.com/openstack/glance
$> cd glance
3. Install Glance::
$> sudo python setup.py install
Red Hat, Fedora
###############
On Fedora, most developers and essentially all users install packages.
Instructions below are not commonly used, and even then typically in a
throw-away VM.
Since normal build dependencies are resolved by mechanisms of RPM,
there is no one-line command to install everything needed by
the source repository in git. One common way to discover the dependencies
is to search for *BuildRequires:* in the specfile of openstack-glance
for the appropriate distro.
In case of Fedora 16, for example, do this::
$ su -
# yum install git
# yum install python2-devel python-setuptools python-distutils-extra
# yum install python-webob python-eventlet
# yum install python-virtualenv
Build Glance::
$ python setup.py build
If any missing modules crop up, install them with yum, then retry the build.
.. note::
If you want to build the Glance documentation, you will also want
to install the packages python-sphinx and graphviz, then run
"python setup.py build_sphinx". Due to required features of
python-sphinx 1.0 or better, documentation can only be built
on Fedora 15 or later.
Test the build::
$ ./run_tests.sh -s
Once Glance is built and tested, install it::
$ su -
# python setup.py install
openSUSE, SLE
#############
On openSUSE and SLE (also this is valid for Factory), we can install
all the build dependencies using Zypper.
1. Install Git and build dependencies::
$ sudo zypper install git
$ sudo zypper source-install -d openstack-glance
.. note::
If you want to build the Glance documentation locally, you will also want
to install the packages python-sphinx and graphviz.
2. Clone Glance's trunk branch from GitHub::
$ git clone git://github.com/openstack/glance
$ cd glance
3. Install Glance::
$ sudo python setup.py install

View File

@ -1,39 +0,0 @@
==========
daisy-api
==========
---------------------------------------
Server for the daisy Image Service API
---------------------------------------
:Author: daisy@lists.launchpad.net
:Date: 2014-01-16
:Copyright: OpenStack LLC
:Version: 2014.1
:Manual section: 1
:Manual group: cloud computing
SYNOPSIS
========
daisy-api [options]
DESCRIPTION
===========
daisy-api is a server daemon that serves the daisy API
OPTIONS
=======
**General options**
.. include:: general_options.rst
FILES
=====
**/etc/daisy/daisy-api.conf**
Default configuration file for daisy API
.. include:: footer.rst

View File

@ -1,103 +0,0 @@
=============
daisy-manage
=============
-------------------------
daisy Management Utility
-------------------------
:Author: daisy@lists.launchpad.net
:Date: 2014-01-16
:Copyright: OpenStack LLC
:Version: 2014.1
:Manual section: 1
:Manual group: cloud computing
SYNOPSIS
========
daisy-manage [options]
DESCRIPTION
===========
daisy-manage is a utility for managing and configuring a daisy installation.
One important use of daisy-manage is to setup the database. To do this run::
daisy-manage db_sync
Note: daisy-manage commands can be run either like this::
daisy-manage db sync
or with the db commands concatenated, like this::
daisy-manage db_sync
COMMANDS
========
**db**
This is the prefix for the commands below when used with a space
rather than a _. For example "db version".
**db_version**
This will print the current migration level of a daisy database.
**db_upgrade <VERSION>**
This will take an existing database and upgrade it to the
specified VERSION.
**db_downgrade <VERSION>**
This will take an existing database and downgrade it to the
specified VERSION.
**db_version_control**
Place the database under migration control.
**db_sync <VERSION> <CURRENT_VERSION>**
Place a database under migration control and upgrade, creating
it first if necessary.
**db_export_metadefs**
Export the metadata definitions into json format. By default the
definitions are exported to /etc/daisy/metadefs directory.
**db_load_metadefs**
Load the metadata definitions into daisy database. By default the
definitions are imported from /etc/daisy/metadefs directory.
**db_unload_metadefs**
Unload the metadata definitions. Clears the contents of all the daisy
db tables including metadef_namespace_resource_types, metadef_tags,
metadef_objects, metadef_resource_types, metadef_namespaces and
metadef_properties.
OPTIONS
=======
**General Options**
.. include:: general_options.rst
**--sql_connection=CONN_STRING**
A proper SQLAlchemy connection string as described
`here <http://www.sqlalchemy.org/docs/05/reference/sqlalchemy/connections.html?highlight=engine#sqlalchemy.create_engine>`_
.. include:: footer.rst
CONFIGURATION
=============
The following paths are searched for a ``daisy-manage.conf`` file in the
following order:
* ``~/.daisy``
* ``~/``
* ``/etc/daisy``
* ``/etc``
All options set in ``daisy-manage.conf`` override those set in
``daisy-registry.conf`` and ``daisy-api.conf``.

View File

@ -1,40 +0,0 @@
===============
daisy-registry
===============
--------------------------------------
Server for the daisy Registry Service
--------------------------------------
:Author: daisy@lists.launchpad.net
:Date: 2014-01-16
:Copyright: OpenStack LLC
:Version: 2014.1
:Manual section: 1
:Manual group: cloud computing
SYNOPSIS
========
daisy-registry [options]
DESCRIPTION
===========
daisy-registry is a server daemon that serves image metadata through a
REST-like API.
OPTIONS
=======
**General options**
.. include:: general_options.rst
FILES
=====
**/etc/daisy/daisy-registry.conf**
Default configuration file for daisy Registry
.. include:: footer.rst

View File

@ -1,9 +0,0 @@
SEE ALSO
========
* `OpenStack Glance <http://glance.openstack.org>`__
BUGS
====
* Glance bugs are tracked in Launchpad so you can view current bugs at `OpenStack Glance <http://bugs.launchpad.net/glance>`__

View File

@ -1,67 +0,0 @@
**-h, --help**
Show the help message and exit
**--version**
Print the version number and exit
**-v, --verbose**
Print more verbose output
**--noverbose**
Disable verbose output
**-d, --debug**
Print debugging output (set logging level to DEBUG instead of
default WARNING level)
**--nodebug**
Disable debugging output
**--use-syslog**
Use syslog for logging
**--nouse-syslog**
Disable the use of syslog for logging
**--syslog-log-facility SYSLOG_LOG_FACILITY**
syslog facility to receive log lines
**--config-dir DIR**
Path to a config directory to pull \*.conf files from. This
file set is sorted, to provide a predictable parse order
if individual options are over-ridden. The set is parsed after
the file(s) specified via previous --config-file, arguments hence
over-ridden options in the directory take precedence. This means
that configuration from files in a specified config-dir will
always take precedence over configuration from files specified
by --config-file, regardless to argument order.
**--config-file PATH**
Path to a config file to use. Multiple config files can be
specified by using this flag multiple times, for example,
--config-file <file1> --config-file <file2>. Values in latter
files take precedence.
**--log-config-append PATH**
**--log-config PATH**
The name of logging configuration file. It does not
disable existing loggers, but just appends specified
logging configuration to any other existing logging
options. Please see the Python logging module documentation
for details on logging configuration files. The log-config
name for this option is depcrecated.
**--log-format FORMAT**
A logging.Formatter log message format string which may use any
of the available logging.LogRecord attributes. Default: None
**--log-date-format DATE_FORMAT**
Format string for %(asctime)s in log records. Default: None
**--log-file PATH, --logfile PATH**
(Optional) Name of log file to output to. If not set, logging
will go to stdout.
**--log-dir LOG_DIR, --logdir LOG_DIR**
(Optional) The directory to keep log files in (will be prepended
to --log-file)

View File

@ -1,22 +0,0 @@
**-os-auth-token=OS_AUTH_TOKEN**
Defaults to env[OS_AUTH_TOKEN]
**--os-username=OS_USERNAME**
Defaults to env[OS_USERNAME]
**--os-password=OS_PASSWORD**
Defaults to env[OS_PASSWORD]
**--os-region-name=OS_REGION_NAME**
Defaults to env[OS_REGION_NAME]
**--os-tenant-id=OS_TENANT_ID**
Defaults to env[OS_TENANT_ID]
**--os-tenant-name=OS_TENANT_NAME**
Defaults to env[OS_TENANT_NAME]
**--os-auth-url=OS_AUTH_URL**
Defaults to env[OS_AUTH_URL]

View File

@ -1,185 +0,0 @@
..
Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may
not use this file except in compliance with the License. You may obtain
a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations
under the License.
Metadata Definition Concepts
============================
The metadata definition service was added to Glance in the Juno release of
OpenStack.
It provides a common API for vendors, admins, services, and users to
meaningfully **define** available key / value pair metadata that
can be used on different types of resources (images, artifacts, volumes,
flavors, aggregates, etc). A definition includes a property's key,
its description, its constraints, and the resource types to which it can be
associated.
This catalog does not store the values for specific instance properties.
For example, a definition of a virtual CPU topology property for the number of
cores will include the base key to use (for example, cpu_cores), a description,
and value constraints like requiring it to be an integer. So, a user,
potentially through Horizon, would be able to search this catalog to list the
available properties they can add to a flavor or image. They will see the
virtual CPU topology property in the list and know that it must be an integer.
When the user adds the property its key and value will be stored in the
service that owns that resource (for example, Nova for flavors and in Glance
for images). The catalog also includes any additional prefix required when
the property is applied to different types of resources, such as "hw_" for
images and "hw:" for flavors. So, on an image, the user would know to set the
property as "hw_cpu_cores=1".
Terminology
-----------
Background
~~~~~~~~~~
The term *metadata* can become very overloaded and confusing. This
catalog is about the additional metadata that is passed as arbitrary
key / value pairs or tags across various artifacts and OpenStack services.
Below are a few examples of the various terms used for metadata across
OpenStack services today:
+-------------------------+---------------------------+----------------------+
| Nova | Cinder | Glance |
+=========================+===========================+======================+
| Flavor | Volume & Snapshot | Image & Snapshot |
| + *extra specs* | + *image metadata* | + *properties* |
| Host Aggregate | + *metadata* | + *tags* |
| + *metadata* | VolumeType | |
| Instances | + *extra specs* | |
| + *metadata* | + *qos specs* | |
| + *tags* | | |
+-------------------------+---------------------------+----------------------+
Catalog Concepts
~~~~~~~~~~~~~~~~
The below figure illustrates the concept terminology used in the metadata
definitions catalog::
A namespace is associated with 0 to many resource types, making it visible to
the API / UI for applying to that type of resource. RBAC Permissions are
managed at a namespace level.
+----------------------------------------------+
| Namespace |
| |
| +-----------------------------------------+ |
| | Object Definition | |
| | | | +--------------------+
| | +-------------------------------------+ | | +--> | Resource Type: |
| | | Property Definition A (key=integer) | | | | | e.g. Nova Flavor |
| | +-------------------------------------+ | | | +--------------------+
| | | | |
| | +-------------------------------------+ | | |
| | | Property Definition B (key=string) | | | | +--------------------+
| | +-------------------------------------+ | +--+--> | Resource Type: |
| | | | | | e.g. Glance Image |
| +-----------------------------------------+ | | +--------------------+
| | |
| +-------------------------------------+ | |
| | Property Definition C (key=boolean) | | | +--------------------+
| +-------------------------------------+ | +--> | Resource Type: |
| | | e.g. Cinder Volume |
+----------------------------------------------+ +--------------------+
Properties may be defined standalone or within the context of an object.
Catalog Terminology
~~~~~~~~~~~~~~~~~~~
The following terminology is used within the metadata definition catalog.
**Namespaces**
Metadata definitions are contained in namespaces.
- Specify the access controls (CRUD) for everything defined in it. Allows for
admin only, different projects, or the entire cloud to define and use the
definitions in the namespace
- Associates the contained definitions to different types of resources
**Properties**
A property describes a single property and its primitive constraints. Each
property can ONLY be a primitive type:
* string, integer, number, boolean, array
Each primitive type is described using simple JSON schema notation. This
means NO nested objects and no definition referencing.
**Objects**
An object describes a group of one to many properties and their primitive
constraints. Each property in the group can ONLY be a primitive type:
* string, integer, number, boolean, array
Each primitive type is described using simple JSON schema notation. This
means NO nested objects.
The object may optionally define required properties under the semantic
understanding that a user who uses the object should provide all required
properties.
**Resource Type Association**
Resource type association specifies the relationship between resource
types and the namespaces that are applicable to them. This information can be
used to drive UI and CLI views. For example, the same namespace of
objects, properties, and tags may be used for images, snapshots, volumes, and
flavors. Or a namespace may only apply to images.
Resource types should be aligned with Heat resource types whenever possible.
http://docs.openstack.org/developer/heat/template_guide/openstack.html
It is important to note that the same base property key can require different
prefixes depending on the target resource type. The API provides a way to
retrieve the correct property based on the target resource type.
Below are a few examples:
The desired virtual CPU topology can be set on both images and flavors
via metadata. The keys have different prefixes on images than on flavors.
On flavors keys are prefixed with ``hw:``, but on images the keys are prefixed
with ``hw_``.
For more: https://github.com/openstack/nova-specs/blob/master/specs/juno/virt-driver-vcpu-topology.rst
Another example is the AggregateInstanceExtraSpecsFilter and scoped properties
(e.g. properties with something:something=value). For scoped / namespaced
properties, the AggregateInstanceExtraSpecsFilter requires a prefix of
"aggregate_instance_extra_specs:" to be used on flavors but not on the
aggregate itself. Otherwise, the filter will not evaluate the property during
scheduling.
So, on a host aggregate, you may see:
companyx:fastio=true
But then when used on the flavor, the AggregateInstanceExtraSpecsFilter needs:
aggregate_instance_extra_specs:companyx:fastio=true
In some cases, there may be multiple different filters that may use
the same property with different prefixes. In this case, the correct prefix
needs to be set based on which filter is enabled.

View File

@ -1,213 +0,0 @@
..
Copyright 2011-2013 OpenStack Foundation
All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may
not use this file except in compliance with the License. You may obtain
a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations
under the License.
Notifications
=============
Notifications can be generated for several events in the image lifecycle.
These can be used for auditing, troubleshooting, etc.
Notification Drivers
--------------------
* log
This driver uses the standard Python logging infrastructure with
the notifications ending up in file specificed by the log_file
configuration directive.
* messaging
This strategy sends notifications to a message queue configured
using oslo.messaging configuration options.
* noop
This strategy produces no notifications. It is the default strategy.
Notification Types
------------------
* ``image.create``
Emitted when an image record is created in Glance. Image record creation is
independent of image data upload.
* ``image.prepare``
Emitted when Glance begins uploading image data to its store.
* ``image.upload``
Emitted when Glance has completed the upload of image data to its store.
* ``image.activate``
Emitted when an image goes to `active` status. This occurs when Glance
knows where the image data is located.
* ``image.send``
Emitted upon completion of an image being sent to a consumer.
* ``image.update``
Emitted when an image record is updated in Glance.
* ``image.delete``
Emitted when an image deleted from Glance.
* ``task.run``
Emitted when a task is picked up by the executor to be run.
* ``task.processing``
Emitted when a task is sent over to the executor to begin processing.
* ``task.success``
Emitted when a task is successfully completed.
* ``task.failure``
Emitted when a task fails.
Content
-------
Every message contains a handful of attributes.
* message_id
UUID identifying the message.
* publisher_id
The hostname of the glance instance that generated the message.
* event_type
Event that generated the message.
* priority
One of WARN, INFO or ERROR.
* timestamp
UTC timestamp of when event was generated.
* payload
Data specific to the event type.
Payload
-------
* image.send
The payload for INFO, WARN, and ERROR events contain the following:
image_id
ID of the image (UUID)
owner_id
Tenant or User ID that owns this image (string)
receiver_tenant_id
Tenant ID of the account receiving the image (string)
receiver_user_id
User ID of the account receiving the image (string)
destination_ip
bytes_sent
The number of bytes actually sent
* image.create
For INFO events, it is the image metadata.
WARN and ERROR events contain a text message in the payload.
* image.prepare
For INFO events, it is the image metadata.
WARN and ERROR events contain a text message in the payload.
* image.upload
For INFO events, it is the image metadata.
WARN and ERROR events contain a text message in the payload.
* image.activate
For INFO events, it is the image metadata.
WARN and ERROR events contain a text message in the payload.
* image.update
For INFO events, it is the image metadata.
WARN and ERROR events contain a text message in the payload.
* image.delete
For INFO events, it is the image id.
WARN and ERROR events contain a text message in the payload.
* task.run
The payload for INFO, WARN, and ERROR events contain the following:
task_id
ID of the task (UUID)
owner
Tenant or User ID that created this task (string)
task_type
Type of the task. Example, task_type is "import". (string)
status,
status of the task. Status can be "pending", "processing",
"success" or "failure". (string)
task_input
Input provided by the user when attempting to create a task. (dict)
result
Resulting output from a successful task. (dict)
message
Message shown in the task if it fails. None if task succeeds. (string)
expires_at
UTC time at which the task would not be visible to the user. (string)
created_at
UTC time at which the task was created. (string)
updated_at
UTC time at which the task was latest updated. (string)
The exceptions are:-
For INFO events, it is the task dict with result and message as None.
WARN and ERROR events contain a text message in the payload.
* task.processing
For INFO events, it is the task dict with result and message as None.
WARN and ERROR events contain a text message in the payload.
* task.success
For INFO events, it is the task dict with message as None and result is a
dict.
WARN and ERROR events contain a text message in the payload.
* task.failure
For INFO events, it is the task dict with result as None and message is
text.
WARN and ERROR events contain a text message in the payload.

View File

@ -1,193 +0,0 @@
..
Copyright 2012 OpenStack Foundation
All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may
not use this file except in compliance with the License. You may obtain
a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations
under the License.
Policies
========
Glance's public API calls may be restricted to certain sets of users using a
policy configuration file. This document explains exactly how policies are
configured and what they apply to.
A policy is composed of a set of rules that are used by the policy "Brain" in
determining if a particular action may be performed by the authorized tenant.
Constructing a Policy Configuration File
----------------------------------------
A policy configuration file is a simply JSON object that contain sets of
rules. Each top-level key is the name of a rule. Each rule
is a string that describes an action that may be performed in the Glance API.
The actions that may have a rule enforced on them are:
* ``get_images`` - List available image entities
* ``GET /v1/images``
* ``GET /v1/images/detail``
* ``GET /v2/images``
* ``get_image`` - Retrieve a specific image entity
* ``HEAD /v1/images/<IMAGE_ID>``
* ``GET /v1/images/<IMAGE_ID>``
* ``GET /v2/images/<IMAGE_ID>``
* ``download_image`` - Download binary image data
* ``GET /v1/images/<IMAGE_ID>``
* ``GET /v2/images/<IMAGE_ID>/file``
* ``upload_image`` - Upload binary image data
* ``POST /v1/images``
* ``PUT /v1/images/<IMAGE_ID>``
* ``PUT /v2/images/<IMAGE_ID>/file``
* ``copy_from`` - Copy binary image data from URL
* ``POST /v1/images``
* ``PUT /v1/images/<IMAGE_ID>``
* ``add_image`` - Create an image entity
* ``POST /v1/images``
* ``POST /v2/images``
* ``modify_image`` - Update an image entity
* ``PUT /v1/images/<IMAGE_ID>``
* ``PUT /v2/images/<IMAGE_ID>``
* ``publicize_image`` - Create or update images with attribute
* ``POST /v1/images`` with attribute ``is_public`` = ``true``
* ``PUT /v1/images/<IMAGE_ID>`` with attribute ``is_public`` = ``true``
* ``POST /v2/images`` with attribute ``visibility`` = ``public``
* ``PUT /v2/images/<IMAGE_ID>`` with attribute ``visibility`` = ``public``
* ``delete_image`` - Delete an image entity and associated binary data
* ``DELETE /v1/images/<IMAGE_ID>``
* ``DELETE /v2/images/<IMAGE_ID>``
* ``add_member`` - Add a membership to the member repo of an image
* ``POST /v2/images/<IMAGE_ID>/members``
* ``get_members`` - List the members of an image
* ``GET /v1/images/<IMAGE_ID>/members``
* ``GET /v2/images/<IMAGE_ID>/members``
* ``delete_member`` - Delete a membership of an image
* ``DELETE /v1/images/<IMAGE_ID>/members/<MEMBER_ID>``
* ``DELETE /v2/images/<IMAGE_ID>/members/<MEMBER_ID>``
* ``modify_member`` - Create or update the membership of an image
* ``PUT /v1/images/<IMAGE_ID>/members/<MEMBER_ID>``
* ``PUT /v1/images/<IMAGE_ID>/members``
* ``POST /v2/images/<IMAGE_ID>/members``
* ``PUT /v2/images/<IMAGE_ID>/members/<MEMBER_ID>``
* ``manage_image_cache`` - Allowed to use the image cache management API
To limit an action to a particular role or roles, you list the roles like so ::
{
"delete_image": ["role:admin", "role:superuser"]
}
The above would add a rule that only allowed users that had roles of either
"admin" or "superuser" to delete an image.
Writing Rules
-------------
Role checks are going to continue to work exactly as they already do. If the
role defined in the check is one that the user holds, then that will pass,
e.g., ``role:admin``.
To write a generic rule, you need to know that there are three values provided
by Glance that can be used in a rule on the left side of the colon (``:``).
Those values are the current user's credentials in the form of:
- role
- tenant
- owner
The left side of the colon can also contain any value that Python can
understand, e.g.,:
- ``True``
- ``False``
- ``"a string"``
- &c.
Using ``tenant`` and ``owner`` will only work with images. Consider the
following rule::
tenant:%(owner)s
This will use the ``tenant`` value of the currently authenticated user. It
will also use ``owner`` from the image it is acting upon. If those two
values are equivalent the check will pass. All attributes on an image (as well
as extra image properties) are available for use on the right side of the
colon. The most useful are the following:
- ``owner``
- ``protected``
- ``is_public``
Therefore, you could construct a set of rules like the following::
{
"not_protected": "False:%(protected)s",
"is_owner": "tenant:%(owner)s",
"is_owner_or_admin": "rule:is_owner or role:admin",
"not_protected_and_is_owner": "rule:not_protected and rule:is_owner",
"get_image": "rule:is_owner_or_admin",
"delete_image": "rule:not_protected_and_is_owner",
"add_member": "rule:not_protected_and_is_owner"
}
Examples
--------
Example 1. (The default policy configuration)
::
{
"default": ""
}
Note that an empty JSON list means that all methods of the
Glance API are callable by anyone.
Example 2. Disallow modification calls to non-admins
::
{
"default": "",
"add_image": "role:admin",
"modify_image": "role:admin",
"delete_image": "role:admin"
}

View File

@ -1,95 +0,0 @@
..
Copyright 2010 OpenStack Foundation
All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may
not use this file except in compliance with the License. You may obtain
a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations
under the License.
Image Statuses
==============
Images in Glance can be in one the following statuses:
* ``queued``
The image identifier has been reserved for an image in the Glance
registry. No image data has been uploaded to Glance and the image
size was not explicitly set to zero on creation.
* ``saving``
Denotes that an image's raw data is currently being uploaded to Glance.
When an image is registered with a call to `POST /images` and there
is an `x-image-meta-location` header present, that image will never be in
the `saving` status (as the image data is already available in some other
location).
* ``active``
Denotes an image that is fully available in Glance. This occurs when
the image data is uploaded, or the image size is explicitly set to
zero on creation.
* ``killed``
Denotes that an error occurred during the uploading of an image's data,
and that the image is not readable.
* ``deleted``
Glance has retained the information about the image, but it is no longer
available to use. An image in this state will be removed automatically
at a later date.
* ``pending_delete``
This is similar to `deleted`, however, Glance has not yet removed the
image data. An image in this state is not recoverable.
.. figure:: /images/image_status_transition.png
:figwidth: 100%
:align: center
:alt: Image status transition
This is a representation of how the image move from one status to the next.
* Add location from zero to more than one.
* Remove location from one or more to zero by PATCH method which is only
supported in v2.
Task Statuses
==============
Tasks in Glance can be in one the following statuses:
* ``pending``
The task identifier has been reserved for a task in the Glance.
No processing has begun on it yet.
* ``processing``
The task has been picked up by the underlying executor and is being run
using the backend Glance execution logic for that task type.
* ``success``
Denotes that the task has had a successful run within Glance. The ``result``
field of the task shows more details about the outcome.
* ``failure``
Denotes that an error occurred during the execution of the task and it
cannot continue processing. The ``message`` field of the task shows what the
error was.

View File

@ -113,32 +113,6 @@ This package contains the daisy Python library.
CI Build Id = %{_description}
SVN Revision = %{_svn_revision}
%package doc
Summary: Documentation for OpenStack Image Service
Group: Documentation
Requires: %{name} = %{version}-%{release}
BuildRequires: systemd-units
BuildRequires: python-sphinx
BuildRequires: python-oslo-sphinx
BuildRequires: graphviz
# Required to build module documents
BuildRequires: python-boto
BuildRequires: python-eventlet
BuildRequires: python-routes
BuildRequires: python-sqlalchemy
BuildRequires: python-webob
%description doc
OpenStack Image Service (code-named daisy) provides discovery, registration,
and delivery services for virtual disk images.
This package contains documentation files for daisy.
CI Build Id = %{_description}
SVN Revision = %{_svn_revision}
%prep
%setup -q -n daisy-%{upstream_version}
@ -163,15 +137,6 @@ rm -fr %{buildroot}%{python2_sitelib}/daisy/tests
# and replaced daisyclient
rm -f %{buildroot}%{_bindir}/daisy
export PYTHONPATH="$( pwd ):$PYTHONPATH"
pushd doc
sphinx-build -b html source build/html
#sphinx-build -b man source build/man
mkdir -p %{buildroot}%{_mandir}/man1
#install -p -D -m 644 build/man/*.1 %{buildroot}%{_mandir}/man1/
popd
# Fix hidden-file-or-dir warnings
rm -fr doc/build/html/.doctrees doc/build/html/.buildinfo
rm -f %{buildroot}%{_sysconfdir}/daisy*.conf
@ -291,7 +256,3 @@ fi
%{python2_sitelib}/daisy
%{python2_sitelib}/*.egg-info
%files doc
%doc doc/build/html