Merge "Delete doc/source in code/daisy"
@ -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})
|
@ -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)
|
@ -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)
|
@ -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
|
@ -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
|
@ -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.
|
@ -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``.
|
@ -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>
|
@ -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
|
||||
|
@ -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).
|
@ -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>
|
||||
找不到任何具有标识 aaa 的映像<br /><br />
|
||||
</body>
|
||||
</html>
|
||||
|
||||
.. note::
|
||||
Be sure there is the language package under /usr/share/locale-langpack/ on
|
||||
the target Glance server.
|
@ -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>`_
|
@ -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>
|
||||
找不到任何具有标识 aaa 的映像<br /><br />
|
||||
</body>
|
||||
</html>
|
||||
|
||||
.. note::
|
||||
Be sure there is the language package under /usr/share/locale-langpack/ on
|
||||
the target Glance server.
|
@ -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.
|
||||
|
@ -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
|
@ -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--->B,AB主备倒换,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--->A,AB主备倒换,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、回退计算节点C(101---->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.conf,mappings.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
|
||||
|
||||
7)TECS安装成功之后,
|
||||
需要手动修改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、回退控制节点备板B(100----->101)**
|
||||
1)参考回退计算节点方法配置控制节点B的tecs.conf文件,EXCLUDE_SERVERS=A,C
|
||||
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:
|
||||
|
||||
4)TECS版本安装完成之后,在备板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检查服务状态OK,crm_mon -1资源启动正常
|
||||
8)清除禁止HA倒换操作,pcs resource clear lb_float_ip
|
||||
9)HA可能会自动设置为维护模式,需要手动取消维护模式,相关命令,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、验收方法
|
||||
无
|
@ -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的服务器类型有:
|
||||
|
||||
E9000,HPC7000,DELL,RS4300,I8350等。
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
##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环境场景, 规划了管理平面(MANAGEMENT),public平面(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盘制作方法见5.1附件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.161,bond0.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中的openstackIP(director提供给nfvo访问的ip地址--------nfvo访问vim用)
|
||||
|
||||
input5 : nvfo的IP,VIM主动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 role,backup type is loadbalance| 控制角色,备份方式为LB|
|
||||
|CONTROLLER_HA| Controller role,backup type is HA,active/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内存设置108,64G内存设置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磁阵配置
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 42 KiB |
Before Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 96 KiB |
Before Width: | Height: | Size: 136 KiB |
Before Width: | Height: | Size: 45 KiB |
Before Width: | Height: | Size: 44 KiB |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 9.8 KiB |
Before Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 56 KiB |
Before Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 45 KiB |
Before Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 47 KiB |
Before Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 44 KiB |
Before Width: | Height: | Size: 41 KiB |
Before Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 50 KiB |
Before Width: | Height: | Size: 74 KiB |
Before Width: | Height: | Size: 50 KiB |
Before Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 62 KiB |
Before Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 62 KiB |
Before Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 85 KiB |
Before Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 44 KiB |
Before Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 42 KiB |
Before Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 48 KiB |
@ -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*.
|
Before Width: | Height: | Size: 52 KiB |
Before Width: | Height: | Size: 128 KiB |
@ -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"><?xml version="1.0" encoding="utf-8"?>
|
||||
<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">
|
||||
<defs>
|
||||
</defs>
|
||||
<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)">
|
||||
<stop offset="0" style="stop-color:#4D4D4D"/>
|
||||
<stop offset="0.0558" style="stop-color:#5F5F5F"/>
|
||||
<stop offset="0.2103" style="stop-color:#8D8D8D"/>
|
||||
<stop offset="0.3479" style="stop-color:#AEAEAE"/>
|
||||
<stop offset="0.4623" style="stop-color:#C2C2C2"/>
|
||||
<stop offset="0.5394" style="stop-color:#C9C9C9"/>
|
||||
<stop offset="0.6247" style="stop-color:#C5C5C5"/>
|
||||
<stop offset="0.7072" style="stop-color:#BABABA"/>
|
||||
<stop offset="0.7885" style="stop-color:#A6A6A6"/>
|
||||
<stop offset="0.869" style="stop-color:#8B8B8B"/>
|
||||
<stop offset="0.9484" style="stop-color:#686868"/>
|
||||
<stop offset="1" style="stop-color:#4D4D4D"/>
|
||||
</linearGradient>
|
||||
<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"/>
|
||||
<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)">
|
||||
<stop offset="0" style="stop-color:#B3B3B3"/>
|
||||
<stop offset="0.0171" style="stop-color:#B6B6B6"/>
|
||||
<stop offset="0.235" style="stop-color:#D7D7D7"/>
|
||||
<stop offset="0.4168" style="stop-color:#EBEBEB"/>
|
||||
<stop offset="0.5394" style="stop-color:#F2F2F2"/>
|
||||
<stop offset="0.6579" style="stop-color:#EEEEEE"/>
|
||||
<stop offset="0.7724" style="stop-color:#E3E3E3"/>
|
||||
<stop offset="0.8853" style="stop-color:#CFCFCF"/>
|
||||
<stop offset="0.9965" style="stop-color:#B4B4B4"/>
|
||||
<stop offset="1" style="stop-color:#B3B3B3"/>
|
||||
</linearGradient>
|
||||
<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"/>
|
||||
<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)">
|
||||
<stop offset="0" style="stop-color:#C9C9C9"/>
|
||||
<stop offset="1" style="stop-color:#808080"/>
|
||||
</linearGradient>
|
||||
<ellipse fill="url(#SVGID_3_)" cx="19.625" cy="31.425" rx="18.396" ry="3.926"/>
|
||||
<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)">
|
||||
<stop offset="0" style="stop-color:#4D4D4D"/>
|
||||
<stop offset="0.0558" style="stop-color:#5F5F5F"/>
|
||||
<stop offset="0.2103" style="stop-color:#8D8D8D"/>
|
||||
<stop offset="0.3479" style="stop-color:#AEAEAE"/>
|
||||
<stop offset="0.4623" style="stop-color:#C2C2C2"/>
|
||||
<stop offset="0.5394" style="stop-color:#C9C9C9"/>
|
||||
<stop offset="0.6247" style="stop-color:#C5C5C5"/>
|
||||
<stop offset="0.7072" style="stop-color:#BABABA"/>
|
||||
<stop offset="0.7885" style="stop-color:#A6A6A6"/>
|
||||
<stop offset="0.869" style="stop-color:#8B8B8B"/>
|
||||
<stop offset="0.9484" style="stop-color:#686868"/>
|
||||
<stop offset="1" style="stop-color:#4D4D4D"/>
|
||||
</linearGradient>
|
||||
<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"/>
|
||||
<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)">
|
||||
<stop offset="0" style="stop-color:#B3B3B3"/>
|
||||
<stop offset="0.0171" style="stop-color:#B6B6B6"/>
|
||||
<stop offset="0.235" style="stop-color:#D7D7D7"/>
|
||||
<stop offset="0.4168" style="stop-color:#EBEBEB"/>
|
||||
<stop offset="0.5394" style="stop-color:#F2F2F2"/>
|
||||
<stop offset="0.6579" style="stop-color:#EEEEEE"/>
|
||||
<stop offset="0.7724" style="stop-color:#E3E3E3"/>
|
||||
<stop offset="0.8853" style="stop-color:#CFCFCF"/>
|
||||
<stop offset="0.9965" style="stop-color:#B4B4B4"/>
|
||||
<stop offset="1" style="stop-color:#B3B3B3"/>
|
||||
</linearGradient>
|
||||
<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"/>
|
||||
<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)">
|
||||
<stop offset="0" style="stop-color:#C9C9C9"/>
|
||||
<stop offset="1" style="stop-color:#808080"/>
|
||||
</linearGradient>
|
||||
<ellipse fill="url(#SVGID_6_)" cx="19.625" cy="17.426" rx="18.396" ry="3.926"/>
|
||||
<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)">
|
||||
<stop offset="0" style="stop-color:#4D4D4D"/>
|
||||
<stop offset="0.0558" style="stop-color:#5F5F5F"/>
|
||||
<stop offset="0.2103" style="stop-color:#8D8D8D"/>
|
||||
<stop offset="0.3479" style="stop-color:#AEAEAE"/>
|
||||
<stop offset="0.4623" style="stop-color:#C2C2C2"/>
|
||||
<stop offset="0.5394" style="stop-color:#C9C9C9"/>
|
||||
<stop offset="0.6247" style="stop-color:#C5C5C5"/>
|
||||
<stop offset="0.7072" style="stop-color:#BABABA"/>
|
||||
<stop offset="0.7885" style="stop-color:#A6A6A6"/>
|
||||
<stop offset="0.869" style="stop-color:#8B8B8B"/>
|
||||
<stop offset="0.9484" style="stop-color:#686868"/>
|
||||
<stop offset="1" style="stop-color:#4D4D4D"/>
|
||||
</linearGradient>
|
||||
<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"/>
|
||||
<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)">
|
||||
<stop offset="0" style="stop-color:#B3B3B3"/>
|
||||
<stop offset="0.0171" style="stop-color:#B6B6B6"/>
|
||||
<stop offset="0.235" style="stop-color:#D7D7D7"/>
|
||||
<stop offset="0.4168" style="stop-color:#EBEBEB"/>
|
||||
<stop offset="0.5394" style="stop-color:#F2F2F2"/>
|
||||
<stop offset="0.6579" style="stop-color:#EEEEEE"/>
|
||||
<stop offset="0.7724" style="stop-color:#E3E3E3"/>
|
||||
<stop offset="0.8853" style="stop-color:#CFCFCF"/>
|
||||
<stop offset="0.9965" style="stop-color:#B4B4B4"/>
|
||||
<stop offset="1" style="stop-color:#B3B3B3"/>
|
||||
</linearGradient>
|
||||
<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"/>
|
||||
<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)">
|
||||
<stop offset="0" style="stop-color:#C9C9C9"/>
|
||||
<stop offset="1" style="stop-color:#808080"/>
|
||||
</linearGradient>
|
||||
<ellipse fill="url(#SVGID_9_)" cx="19.625" cy="3.926" rx="18.396" ry="3.926"/>
|
||||
<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"/>
|
||||
</svg>
|
||||
</y:Resource>
|
||||
<y:Resource id="2"><?xml version="1.0" encoding="utf-8"?>
|
||||
<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">
|
||||
<defs>
|
||||
</defs>
|
||||
<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)">
|
||||
<stop offset="0" style="stop-color:#3C89C9"/>
|
||||
<stop offset="0.1482" style="stop-color:#60A6DD"/>
|
||||
<stop offset="0.3113" style="stop-color:#81C1F0"/>
|
||||
<stop offset="0.4476" style="stop-color:#95D1FB"/>
|
||||
<stop offset="0.5394" style="stop-color:#9CD7FF"/>
|
||||
<stop offset="0.636" style="stop-color:#98D4FD"/>
|
||||
<stop offset="0.7293" style="stop-color:#8DCAF6"/>
|
||||
<stop offset="0.8214" style="stop-color:#79BBEB"/>
|
||||
<stop offset="0.912" style="stop-color:#5EA5DC"/>
|
||||
<stop offset="1" style="stop-color:#3C89C9"/>
|
||||
</linearGradient>
|
||||
<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"/>
|
||||
<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)">
|
||||
<stop offset="0" style="stop-color:#9CD7FF"/>
|
||||
<stop offset="0.0039" style="stop-color:#9DD7FF"/>
|
||||
<stop offset="0.2273" style="stop-color:#BDE5FF"/>
|
||||
<stop offset="0.4138" style="stop-color:#D1EEFF"/>
|
||||
<stop offset="0.5394" style="stop-color:#D9F1FF"/>
|
||||
<stop offset="0.6155" style="stop-color:#D5EFFE"/>
|
||||
<stop offset="0.6891" style="stop-color:#C9E7FA"/>
|
||||
<stop offset="0.7617" style="stop-color:#B6DAF3"/>
|
||||
<stop offset="0.8337" style="stop-color:#9AC8EA"/>
|
||||
<stop offset="0.9052" style="stop-color:#77B0DD"/>
|
||||
<stop offset="0.9754" style="stop-color:#4D94CF"/>
|
||||
<stop offset="1" style="stop-color:#3C89C9"/>
|
||||
</linearGradient>
|
||||
<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"/>
|
||||
<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"/>
|
||||
<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)">
|
||||
<stop offset="0" style="stop-color:#3C89C9"/>
|
||||
<stop offset="0.1482" style="stop-color:#60A6DD"/>
|
||||
<stop offset="0.3113" style="stop-color:#81C1F0"/>
|
||||
<stop offset="0.4476" style="stop-color:#95D1FB"/>
|
||||
<stop offset="0.5394" style="stop-color:#9CD7FF"/>
|
||||
<stop offset="0.636" style="stop-color:#98D4FD"/>
|
||||
<stop offset="0.7293" style="stop-color:#8DCAF6"/>
|
||||
<stop offset="0.8214" style="stop-color:#79BBEB"/>
|
||||
<stop offset="0.912" style="stop-color:#5EA5DC"/>
|
||||
<stop offset="1" style="stop-color:#3C89C9"/>
|
||||
</linearGradient>
|
||||
<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"/>
|
||||
<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)">
|
||||
<stop offset="0" style="stop-color:#9CD7FF"/>
|
||||
<stop offset="0.0039" style="stop-color:#9DD7FF"/>
|
||||
<stop offset="0.2273" style="stop-color:#BDE5FF"/>
|
||||
<stop offset="0.4138" style="stop-color:#D1EEFF"/>
|
||||
<stop offset="0.5394" style="stop-color:#D9F1FF"/>
|
||||
<stop offset="0.6155" style="stop-color:#D5EFFE"/>
|
||||
<stop offset="0.6891" style="stop-color:#C9E7FA"/>
|
||||
<stop offset="0.7617" style="stop-color:#B6DAF3"/>
|
||||
<stop offset="0.8337" style="stop-color:#9AC8EA"/>
|
||||
<stop offset="0.9052" style="stop-color:#77B0DD"/>
|
||||
<stop offset="0.9754" style="stop-color:#4D94CF"/>
|
||||
<stop offset="1" style="stop-color:#3C89C9"/>
|
||||
</linearGradient>
|
||||
<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"/>
|
||||
<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"/>
|
||||
<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)">
|
||||
<stop offset="0" style="stop-color:#3C89C9"/>
|
||||
<stop offset="0.1482" style="stop-color:#60A6DD"/>
|
||||
<stop offset="0.3113" style="stop-color:#81C1F0"/>
|
||||
<stop offset="0.4476" style="stop-color:#95D1FB"/>
|
||||
<stop offset="0.5394" style="stop-color:#9CD7FF"/>
|
||||
<stop offset="0.636" style="stop-color:#98D4FD"/>
|
||||
<stop offset="0.7293" style="stop-color:#8DCAF6"/>
|
||||
<stop offset="0.8214" style="stop-color:#79BBEB"/>
|
||||
<stop offset="0.912" style="stop-color:#5EA5DC"/>
|
||||
<stop offset="1" style="stop-color:#3C89C9"/>
|
||||
</linearGradient>
|
||||
<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"/>
|
||||
<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)">
|
||||
<stop offset="0" style="stop-color:#9CD7FF"/>
|
||||
<stop offset="0.0039" style="stop-color:#9DD7FF"/>
|
||||
<stop offset="0.2273" style="stop-color:#BDE5FF"/>
|
||||
<stop offset="0.4138" style="stop-color:#D1EEFF"/>
|
||||
<stop offset="0.5394" style="stop-color:#D9F1FF"/>
|
||||
<stop offset="0.6155" style="stop-color:#D5EFFE"/>
|
||||
<stop offset="0.6891" style="stop-color:#C9E7FA"/>
|
||||
<stop offset="0.7617" style="stop-color:#B6DAF3"/>
|
||||
<stop offset="0.8337" style="stop-color:#9AC8EA"/>
|
||||
<stop offset="0.9052" style="stop-color:#77B0DD"/>
|
||||
<stop offset="0.9754" style="stop-color:#4D94CF"/>
|
||||
<stop offset="1" style="stop-color:#3C89C9"/>
|
||||
</linearGradient>
|
||||
<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"/>
|
||||
<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)">
|
||||
<stop offset="0" style="stop-color:#9CD7FF"/>
|
||||
<stop offset="1" style="stop-color:#3C89C9"/>
|
||||
</linearGradient>
|
||||
<ellipse fill="url(#SVGID_7_)" cx="19.625" cy="3.926" rx="18.396" ry="3.926"/>
|
||||
<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"/>
|
||||
</svg>
|
||||
</y:Resource>
|
||||
</y:Resources>
|
||||
</data>
|
||||
</graphml>
|
@ -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"];
|
||||
}
|
Before Width: | Height: | Size: 153 KiB |
@ -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
|
@ -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
|
@ -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
|
@ -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``.
|
@ -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
|
@ -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>`__
|
@ -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)
|
@ -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]
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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.
|
@ -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"
|
||||
}
|
@ -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.
|
@ -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
|
||||
|
||||
|
||||
|