diff -Nru glance-2012.1~rc1~20120309.1315/Authors glance-2012.1~rc1~20120316.1354/Authors --- glance-2012.1~rc1~20120309.1315/Authors 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/Authors 2012-03-16 00:16:11.000000000 +0000 @@ -28,6 +28,7 @@ Justin Santa Barbara Justin Shepherd Ken Pepple +Ken Thomas Kevin L. Mitchell Lorin Hochstein Major Hayden diff -Nru glance-2012.1~rc1~20120309.1315/babel.cfg glance-2012.1~rc1~20120316.1354/babel.cfg --- glance-2012.1~rc1~20120309.1315/babel.cfg 1970-01-01 00:00:00.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/babel.cfg 2012-03-16 00:16:11.000000000 +0000 @@ -0,0 +1 @@ +[python: **.py] diff -Nru glance-2012.1~rc1~20120309.1315/bin/glance glance-2012.1~rc1~20120316.1354/bin/glance --- glance-2012.1~rc1~20120309.1315/bin/glance 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/bin/glance 2012-03-16 00:16:11.000000000 +0000 @@ -41,10 +41,10 @@ gettext.install('glance', unicode=1) -from glance import version from glance import client as glance_client from glance.common import exception from glance.common import utils +from glance import version SUCCESS = 0 @@ -164,7 +164,7 @@ id Optional. If not specified, an image identifier will be automatically assigned. -name Required. A name for the image. +name Optional. A name for the image. size Optional. Should be size in bytes of the image if specified. is_public Optional. If specified, interpreted as a boolean value @@ -190,7 +190,7 @@ copy_from=s3://akey:skey@s3.amazonaws.com/images/fedora16 Any other field names are considered to be custom properties so be careful -to spell field names correctly. :) +to spell field names correctly. STREAMING IMAGE DATA =============================================================================== @@ -217,12 +217,8 @@ print e return FAILURE - if 'name' not in fields.keys(): - print "Please specify a name for the image using name=VALUE" - return FAILURE - image_meta = {'id': fields.pop('id', None), - 'name': fields.pop('name'), + 'name': fields.pop('name', None), 'is_public': utils.bool_from_string( fields.pop('is_public', False)), 'protected': utils.bool_from_string( @@ -336,7 +332,7 @@ container_format Format of the container All other field names are considered to be custom properties so be careful -to spell field names correctly. :)""" +to spell field names correctly.""" c = get_client(options) try: image_id = args.pop(0) @@ -784,43 +780,16 @@ specified by the --host and --port options supplied to the CLI """ - - if options.auth_url or os.getenv('OS_AUTH_URL'): - force_strategy = 'keystone' - else: - force_strategy = None - - creds = dict(username=options.username or \ - os.getenv('OS_AUTH_USER', os.getenv('OS_USERNAME')), - password=options.password or \ - os.getenv('OS_AUTH_KEY', os.getenv('OS_PASSWORD')), - tenant=options.tenant or \ - os.getenv('OS_AUTH_TENANT', - os.getenv('OS_TENANT_NAME')), - auth_url=options.auth_url or os.getenv('OS_AUTH_URL'), - strategy=force_strategy or options.auth_strategy or \ - os.getenv('OS_AUTH_STRATEGY', 'noauth'), - region=options.region or os.getenv('OS_REGION_NAME'), - ) - - if creds['strategy'] == 'keystone' and not creds['auth_url']: - msg = ("--auth_url option or OS_AUTH_URL environment variable " - "required when keystone authentication strategy is enabled\n") - raise exception.ClientConfigurationError(msg) - - use_ssl = (options.use_ssl or ( - creds['auth_url'] is not None and - creds['auth_url'].find('https') != -1)) - - client = (glance_client.ProgressClient if not options.is_silent_upload - else glance_client.Client) - - return client(host=options.host, + return glance_client.get_client(host=options.host, port=options.port, - use_ssl=use_ssl, - auth_tok=options.auth_token or - os.getenv('OS_TOKEN'), - creds=creds, + username=options.os_username, + password=options.os_password, + tenant=options.os_tenant_name, + auth_url=options.os_auth_url, + auth_strategy=options.os_auth_strategy, + auth_token=options.os_auth_token, + region=options.os_region_name, + is_silent_upload=options.is_silent_upload, insecure=options.insecure) @@ -858,30 +827,31 @@ "SSL (https) requests. The server's certificate will " "not be verified against any certificate authorities. " "This option should be used with caution.") - parser.add_option('-A', '--auth_token', dest="auth_token", - metavar="TOKEN", default=None, + parser.add_option('-A', '--os_auth_token', '--auth_token', + dest="os_auth_token", metavar="TOKEN", default=None, help="Authentication token to use to identify the " - "client to the glance server") - parser.add_option('-I', '--username', dest="username", + "client to the glance server. --auth_token" + "is deprecated and will be removed") + parser.add_option('-I', '--os_username', dest="os_username", metavar="USER", default=None, help="User name used to acquire an authentication token") - parser.add_option('-K', '--password', dest="password", + parser.add_option('-K', '--os_password', dest="os_password", metavar="PASSWORD", default=None, help="Password used to acquire an authentication token") - parser.add_option('-R', '--region', dest="region", + parser.add_option('-R', '--os_region_name', dest="os_region_name", metavar="REGION", default=None, help="Region name. When using keystone authentication " "version 2.0 or later this identifies the region " "name to use when selecting the service endpoint. A " "region name must be provided if more than one " "region endpoint is available") - parser.add_option('-T', '--tenant', dest="tenant", + parser.add_option('-T', '--os_tenant_name', dest="os_tenant_name", metavar="TENANT", default=None, help="Tenant name") - parser.add_option('-N', '--auth_url', dest="auth_url", + parser.add_option('-N', '--os_auth_url', dest="os_auth_url", metavar="AUTH_URL", default=None, help="Authentication URL") - parser.add_option('-S', '--auth_strategy', dest="auth_strategy", + parser.add_option('-S', '--os_auth_strategy', dest="os_auth_strategy", metavar="STRATEGY", default=None, help="Authentication strategy (keystone or noauth)") parser.add_option('--limit', dest="limit", metavar="LIMIT", default=10, @@ -1000,6 +970,10 @@ else: prompt_default = "[y/N]" + # for bug 884116, don't issue the prompt if stdin isn't a tty + if not hasattr(sys.stdin, 'isatty') or not sys.stdin.isatty(): + return default + answer = raw_input("%s %s " % (prompt, prompt_default)) if answer == "": diff -Nru glance-2012.1~rc1~20120309.1315/bin/glance-cache-manage glance-2012.1~rc1~20120316.1354/bin/glance-cache-manage --- glance-2012.1~rc1~20120309.1315/bin/glance-cache-manage 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/bin/glance-cache-manage 2012-03-16 00:16:11.000000000 +0000 @@ -38,9 +38,9 @@ gettext.install('glance', unicode=1) from glance import client as glance_client -from glance import version from glance.common import exception from glance.common import utils +from glance import version SUCCESS = 0 @@ -259,19 +259,16 @@ specified by the --host and --port options supplied to the CLI """ - creds = dict(username=os.getenv('OS_AUTH_USER'), - password=os.getenv('OS_AUTH_KEY'), - tenant=os.getenv('OS_AUTH_TENANT'), - auth_url=os.getenv('OS_AUTH_URL'), - strategy=os.getenv('OS_AUTH_STRATEGY', 'noauth')) - - use_ssl = (options.host.find('https') != -1 or ( - creds['auth_url'] is not None and - creds['auth_url'].find('https') != -1)) - - return glance_client.Client(host=options.host, port=options.port, - use_ssl=use_ssl, auth_tok=options.auth_token, - creds=creds) + return glance_client.get_client(host=options.host, + port=options.port, + username=options.os_username, + password=options.os_password, + tenant=options.os_tenant_name, + auth_url=options.os_auth_url, + auth_strategy=options.os_auth_strategy, + auth_token=options.os_auth_token, + region=options.os_region_name, + insecure=options.insecure) def create_options(parser): @@ -292,10 +289,39 @@ type=int, default=9292, help="Port the Glance API host listens on. " "Default: %default") - parser.add_option('-A', '--auth_token', dest="auth_token", - metavar="TOKEN", default=None, + parser.add_option('-A', '--os_auth_token', '--auth_token', + dest="os_auth_token", metavar="TOKEN", default=None, help="Authentication token to use to identify the " - "client to the glance server") + "client to the glance server. --auth_token" + "is deprecated and will be removed") + parser.add_option('-I', '--os_username', dest="os_username", + metavar="USER", default=None, + help="User name used to acquire an authentication token") + parser.add_option('-K', '--os_password', dest="os_password", + metavar="PASSWORD", default=None, + help="Password used to acquire an authentication token") + parser.add_option('-R', '--os_region_name', dest="os_region_name", + metavar="REGION", default=None, + help="Region name. When using keystone authentication " + "version 2.0 or later this identifies the region " + "name to use when selecting the service endpoint. A " + "region name must be provided if more than one " + "region endpoint is available") + parser.add_option('-T', '--os_tenant_name', dest="os_tenant_name", + metavar="TENANT", default=None, + help="Tenant name") + parser.add_option('-N', '--os_auth_url', dest="os_auth_url", + metavar="AUTH_URL", default=None, + help="Authentication URL") + parser.add_option('-k', '--insecure', dest="insecure", + default=False, action="store_true", + help="Explicitly allow glance to perform \"insecure\" " + "SSL (https) requests. The server's certificate will " + "not be verified against any certificate authorities. " + "This option should be used with caution.") + parser.add_option('-S', '--os_auth_strategy', dest="os_auth_strategy", + metavar="STRATEGY", default=None, + help="Authentication strategy (keystone or noauth)") parser.add_option('-f', '--force', dest="force", metavar="FORCE", default=False, action="store_true", help="Prevent select actions from requesting " diff -Nru glance-2012.1~rc1~20120309.1315/bin/glance-cache-queue-image glance-2012.1~rc1~20120316.1354/bin/glance-cache-queue-image --- glance-2012.1~rc1~20120309.1315/bin/glance-cache-queue-image 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/bin/glance-cache-queue-image 1970-01-01 00:00:00.000000000 +0000 @@ -1,52 +0,0 @@ -#!/usr/bin/env python -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2011 OpenStack LLC. -# 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. - -""" -CLI Utility to queue one or more images for prefetching into the image cache -""" - -import gettext -import os -import sys - -# If ../glance/__init__.py exists, add ../ to Python search path, so that -# it will override what happens to be installed in /usr/(local/)lib/python... -possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]), - os.pardir, - os.pardir)) -if os.path.exists(os.path.join(possible_topdir, 'glance', '__init__.py')): - sys.path.insert(0, possible_topdir) - -gettext.install('glance', unicode=1) - -from glance.common import config - -USAGE = """ -%%prog [OPTIONS] [ ... ] -""" - - -if __name__ == '__main__': - try: - conf = config.GlanceCacheConfigOpts(usage=USAGE) - args = conf() - - app = config.load_paste_app(conf, 'glance-queue-image') - app.run(args) - except RuntimeError, e: - sys.exit("ERROR: %s" % e) diff -Nru glance-2012.1~rc1~20120309.1315/bin/glance-control glance-2012.1~rc1~20120316.1354/bin/glance-control --- glance-2012.1~rc1~20120309.1315/bin/glance-control 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/bin/glance-control 2012-03-16 00:16:11.000000000 +0000 @@ -43,7 +43,6 @@ gettext.install('glance', unicode=1) -from glance import version from glance.common import cfg from glance.common import config diff -Nru glance-2012.1~rc1~20120309.1315/debian/changelog glance-2012.1~rc1~20120316.1354/debian/changelog --- glance-2012.1~rc1~20120309.1315/debian/changelog 2012-03-15 13:29:17.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/debian/changelog 2012-03-16 20:37:43.000000000 +0000 @@ -1,3 +1,9 @@ +glance (2012.1~rc1~20120316.1354-0ubuntu1) precise; urgency=low + + * New upstream release. + + -- Adam Gandelman Fri, 16 Mar 2012 16:23:34 -0400 + glance (2012.1~rc1~20120309.1315-0ubuntu2) precise; urgency=low * debian/glance-common.postinst diff -Nru glance-2012.1~rc1~20120309.1315/doc/source/architecture.rst glance-2012.1~rc1~20120316.1354/doc/source/architecture.rst --- glance-2012.1~rc1~20120309.1315/doc/source/architecture.rst 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/doc/source/architecture.rst 2012-03-16 00:16:11.000000000 +0000 @@ -55,11 +55,9 @@ What is a Registry Server? ========================== -A registry server is any service that publishes image metadata that conforms -to the Glance Registry REST-ful API. Glance comes with a reference -implementation of a registry server called ``glance-registry``, but this is -only a reference implementation that uses a SQL database for its metdata -storage. +A registry server is a service that publishes image metadata for internal +consumption by the Glance API server. The Glance registry server uses a +SQL database for its metdata storage. What is a Store? ================ diff -Nru glance-2012.1~rc1~20120309.1315/doc/source/authentication.rst glance-2012.1~rc1~20120316.1354/doc/source/authentication.rst --- glance-2012.1~rc1~20120309.1315/doc/source/authentication.rst 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/doc/source/authentication.rst 2012-03-16 00:16:11.000000000 +0000 @@ -18,10 +18,8 @@ =================================== Glance may optionally be integrated with Keystone. Setting this up is -relatively straightforward: the Keystone distribution includes the -requisite middleware and examples of appropriately modified -``glance-api.conf`` and ``glance-registry.conf`` configuration files -in the ``examples/paste`` directory. Once you have installed Keystone +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 @@ -37,79 +35,6 @@ those images to show up in lists, potentially confusing users. -Configuring the Glance Client to use Keystone ---------------------------------------------- - -Once the Glance API and Registry servers have been configured to use Keystone, you -will need to configure the Glance client (``bin/glance``) to use Keystone as -well. - -Just as with Nova, the specifying of authentication credentials is done via -environment variables. The only difference being that Glance environment -variables start with `OS_AUTH_` while Nova's begin with `NOVA_`. - -If you already have Nova credentials present in your environment, you can use -the included tool, ``tools/nova_to_os_env.sh``, to create Glance-style -credentials. To use this tool, verify that Nova credentials are present by -running:: - - $ env | grep NOVA_ - NOVA_USERNAME= - NOVA_API_KEY= - NOVA_PROJECT_ID= - NOVA_URL= - NOVA_AUTH_STRATEGY=keystone - -.. note:: - - If `NOVA_AUTH_STRATEGY=keystone` is not present, add that to your ``novarc`` file - and re-source it. If the command produces no output at all, then you will need - to source your ``novarc``. - - Also, make sure that `NOVA_URL` points to Keystone and not the Nova API - server. Keystone will return the address for Nova and Glance's API servers - via its "service catalog". - -Once Nova credentials are present in the environment, you will need to source -the conervsion script:: - - $ source ./tools/nova_to_os_env.sh - -The final step is to verify that the `OS_AUTH_` crednetials are present:: - - $ env | grep OS_AUTH - OS_AUTH_USER= - OS_AUTH_KEY= - OS_AUTH_TENANT= - OS_AUTH_URL= - OS_AUTH_STRATEGY=keystone - -Alternatively, these credentials may be specified using the following -switches to the ``bin/glance`` command: - - -I USER, --username=USER - User name used to acquire an authentication token - -K PASSWORD, --password=PASSWORD - Password used to acquire an authentication token - -T TENANT, --tenant=TENANT - Tenant name - -N AUTH_URL, --auth_url=AUTH_URL - Authentication URL - -S STRATEGY, --auth_strategy=STRATEGY - Authentication strategy (keystone or noauth) - -Or, if a pre-authenticated token is preferred, the following option allows -the client-side interaction with keystone to be by-passed (useful if a long -sequence of commands is being scripted): - - -A TOKEN, --auth_token=TOKEN - Authentication token to use to identify the client to - the glance server - -In general the command line switch takes precedence over the corresponding -OS_AUTH_* environment variable, if both are set. - - Configuring the Glance servers to use Keystone ---------------------------------------------- @@ -155,6 +80,9 @@ auth_protocol = http auth_uri = http://127.0.0.1:5000/ admin_token = 999888777666 + 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 @@ -173,12 +101,16 @@ to this URI to obtain one. * The ``admin_token`` variable specifies the administrative token that Glance uses in its query to the Keystone Admin service. +* If no ``admin_token`` is provided, or it becomes invalid, the admin auth + credentials (``admin_user``, ``admin_tenant_name``, ``admin_password``) + will be used to retrieve a new admin token The other piece of middleware needed for Glance API is the ``auth-context``:: [filter:auth_context] - paste.filter_factory = keystone.middleware.glance_auth_token:filter_factory + paste.filter_factory = glance.common.wsgi:filter_factory + glance.filter_factory = keystone.middleware.glance_auth_token:KeystoneContextMiddleware Finally, to actually enable using Keystone authentication, the application pipeline must be modified. By default, it looks like:: @@ -205,7 +137,8 @@ [filter:auth-context] context_class = glance.registry.context.RequestContext - paste.filter_factory = keystone.middleware.glance_auth_token:filter_factory + paste.filter_factory = glance.common.wsgi:filter_factory + glance.filter_factory = keystone.middleware.glance_auth_token:KeystoneContextMiddleware The ``context_class`` variable is needed to specify the Registry-specific request context, which contains the extra access @@ -218,7 +151,8 @@ pipeline = authtoken auth-context registryapp To enable the above application pipeline, in your main ``glance-registry.conf`` -configuration file, select the appropriate deployment flavor like so:: +configuration file, select the appropriate deployment flavor by adding a +``flavor`` attribute in the ``paste_deploy`` group:: [paste_deploy] flavor = keystone @@ -234,3 +168,37 @@ access that image. These membership associations may also have a `can_share` attribute, which, if set to `true`, delegates the authority to share an image to the named tenant. + +Configuring the Glance Client to use Keystone +--------------------------------------------- + +Once the Glance API and Registry servers have been configured to use +Keystone, you will need to configure the Glance client (``bin/glance``) +to use Keystone as well. Like the other OpenStack projects, this is +done through a common set of environment variables. These credentials may +may alternatively be specified using the following switches to +the ``bin/glance`` command: + + OS_USERNAME=, -I , --os_username= + User name used to acquire an authentication token + OS_PASSWORD=, -K , --os_password= + Password used to acquire an authentication token + OS_TENANT_NAME= -T , --os_tenant_name= + Tenant name + OS_AUTH_URL=, -N , --os_auth_url= + Authentication endpoint + OS_REGION_NAME=, -R , --os_region_name= + Used to select a specific region while + authenticating against Keystone + +Or, if a pre-authenticated token is preferred, the following option allows +the client-side interaction with keystone to be bypassed (useful if a long +sequence of commands is being scripted): + + OS_TOKEN=, -A , --os_auth_token= + User's authentication token that identifies the + client to the glance server. This is not + an admin token. + +In general the command line switch takes precedence over the corresponding +OS_* environment variable, if both are set. diff -Nru glance-2012.1~rc1~20120309.1315/doc/source/cache.rst glance-2012.1~rc1~20120316.1354/doc/source/cache.rst --- glance-2012.1~rc1~20120309.1315/doc/source/cache.rst 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/doc/source/cache.rst 2012-03-16 00:16:18.000000000 +0000 @@ -85,22 +85,9 @@ This will queue the image with identifier ```` for prefetching - * You may use the ``glance-cache-queue-image`` executable, supplying a list - of image identifiers to queue for prefetching into the cache. - - Example usage:: - - $> glance-cache-queue-image 12345 ABCDE - - would queue the images with identifiers ``12345`` and ``ABCDE`` 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, reporting the results of the fetch for each image, as shown -below:: - - TODO +concurrently, logging the results of the fetch for each image. Finding Which Images are in the Image Cache ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -108,7 +95,7 @@ You can find out which images are in the image cache using one of the following methods: - * If the ``cache_manage`` middleware is enabled in the application pipeline, + * 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. @@ -132,7 +119,7 @@ Manually Removing Images from the Image Cache ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -If the ``cache_manage`` middleware is enabled, you may call +If the ``cachemanage`` middleware is enabled, you may call ``DELETE /cached-images/`` to remove the image file for image with identifier ```` from the cache. diff -Nru glance-2012.1~rc1~20120309.1315/doc/source/client.rst glance-2012.1~rc1~20120316.1354/doc/source/client.rst --- glance-2012.1~rc1~20120309.1315/doc/source/client.rst 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/doc/source/client.rst 2012-03-16 00:16:11.000000000 +0000 @@ -112,7 +112,7 @@ c = Client("glance.example.com", 9292) - filters = {'status': 'saving', 'size_max': (5 * 1024 * 1024 * 1024)} + filters = {'status': 'saving', 'size_max': 5368709120} print c.get_images_detailed(filters=filters) Sorting Images Returned via ``get_images()`` and ``get_images_detailed()`` @@ -151,12 +151,11 @@ that the Glance server knows about. We have queried the Glance server for a list of public 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. +data returned includes the `id` field for each available image. This +`id` field value is needed to get the metadata for a specific image. -Continuing the example from above, in order to get metadata about the -first public image returned, we can use the following code +In order to get metadata for a specific image using an id, we can use the +following code .. code-block:: python @@ -164,7 +163,7 @@ c = Client("glance.example.com", 9292) - print c.get_image_meta("http://glance.example.com/images/71c675ab-d94f-49cd-a114-e12490b328d9") + print c.get_image_meta("71c675ab-d94f-49cd-a114-e12490b328d9") Retrieving a Virtual Machine Image ---------------------------------- @@ -172,11 +171,6 @@ 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 public 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 both the metadata about the first public image returned and its image data, we can use the following code @@ -186,7 +180,7 @@ c = Client("glance.example.com", 9292) - meta, image_file = c.get_image("http://glance.example.com/images/71c675ab-d94f-49cd-a114-e12490b328d9") + meta, image_file = c.get_image("71c675ab-d94f-49cd-a114-e12490b328d9") print meta @@ -197,7 +191,7 @@ .. note:: - The return from Client.get_image() is a tuple of (`metadata`, `file`) + The return from Client.get_image is a tuple of (`metadata`, `file`) where `metadata` is a mapping of metadata about the image and `file` is a generator that yields chunks of image data. @@ -205,7 +199,7 @@ ---------------------------------- We have created a new virtual machine image in some way (created a -"golden image" or snapshotted/backed up an existing image) and we +"golden" image or snapshotted/backed up an existing image) and we wish to do two things: * Store the disk image data in Glance @@ -219,96 +213,13 @@ glance.client.Client.add_image(image_meta, image_data=None) -The `image_meta` argument is a mapping containing various image metadata. +The `image_meta` argument is a dictionary containing various image metadata. +The keys in this dictionary map directly to the 'x-image-meta-*' headers +accepted in the Glance API. Simply drop the leading 'x-image-meta-' from each +header to determine what key should be used in the metadata dictionary. See the +:doc:`API docs ` for a complete list of acceptable attributes. The `image_data` argument is the disk image data and is an optional argument. -The list of metadata that `image_meta` can contain are listed below. - -* `name` - - This key/value is required. 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. - -* `id` - - This key/value is optional. - - When present, Glance will use the supplied identifier for the image. - If the identifier already exists in that Glance node, then a - `glance.common.exception.Duplicate` will be raised. The value of the header - must be a properly formatted uuid (i.e. 71c675ab-d94f-49cd-a114-e12490b328d9). - - When this key/value is *not* present, Glance will generate an identifier - for the image and return this identifier in the response (see below). - -* `store` - - This key/value is optional. Valid values are one of `file`, `s3` or `swift` - - When present, Glance will attempt to store the disk image data in the - backing store indicated by the value. If the Glance node does not support - the backing store, Glance will raise a `glance.common.exception.BadRequest` - - 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. - -* `type` - - This key/values is required. Valid values are one of `kernel`, `machine`, - `raw`, or `ramdisk`. - -* `size` - - This key/value is optional. - - When present, Glance assumes that the expected size of the request body - will be the value. If the length in bytes of the request body *does not - match* the value, Glance will raise a `glance.common.exception.BadRequest` - - When not present, Glance will calculate the image's size based on the size - of the request body. - -* `is_public` - - This key/value is optional. - - When present, Glance converts the value to a boolean value, so "on, 1, true" - are all true values. When true, 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 specific to - a user. - -* `properties` - - This key/value is optional. - - When present, the value is assumed to be a mapping of free-form key/value - attributes to store with the image. - - For example, if the following is the value of the `properties` key in the - `image_meta` argument:: - - {'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 with `properties`. However, keep in mind that there - is a 8K limit on the size of all HTTP headers sent in a request and this - number will effectively limit the number of image properties. - - If the `image_data` argument is omitted, Glance will add the `image_meta` - mapping to its registries and return the newly-registered image metadata, - including the new image's identifier. The `status` of the image will be - set to the value `queued`. - As a complete example, the following code would add a new machine image to Glance @@ -319,7 +230,8 @@ c = Client("glance.example.com", 9292) meta = {'name': 'Ubuntu 10.10 5G', - 'type': 'machine', + 'container_format': 'ovf', + 'disk_format': 'vhd', 'is_public': True, 'properties': {'distro': 'Ubuntu 10.10'}} diff -Nru glance-2012.1~rc1~20120309.1315/doc/source/community.rst glance-2012.1~rc1~20120316.1354/doc/source/community.rst --- glance-2012.1~rc1~20120309.1315/doc/source/community.rst 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/doc/source/community.rst 1970-01-01 00:00:00.000000000 +0000 @@ -1,83 +0,0 @@ -.. - Copyright 2010 OpenStack, LLC - 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. - -Getting Involved -================ - -The Glance community is a very friendly group and there are places online to join in with the -community. Feel free to ask questions. This document points you to some of the places where you can -communicate with people. - -How to Join the OpenStack Community ------------------------------------ - -Our community welcomes all people interested in open source cloud computing, and there are no formal -membership requirements. The best way to join the community is to talk with others online or at a meetup -and offer contributions through Launchpad, the wiki, or blogs. We welcome all types of contributions, -from blueprint designs to documentation to testing to deployment scripts. - -Contributing Code ------------------ - -To contribute code, sign up for a Launchpad account and sign a contributor license agreement, -available on the ``_. Once the CLA is signed you -can contribute code through the Bazaar version control system which is related to your Launchpad account. - -#openstack on Freenode IRC Network ----------------------------------- - -There is a very active chat channel at ``_. This -is usually the best place to ask questions and find your way around. IRC stands for Internet Relay -Chat and it is a way to chat online in real time. You can also ask a question and come back to the -log files to read the answer later. Logs for the #openstack IRC channel are stored at -``_. - -OpenStack Wiki --------------- - -The wiki is a living source of knowledge. It is edited by the community, and -has collections of links and other sources of information. Typically the pages are a good place -to write drafts for specs or documentation, describe a blueprint, or collaborate with others. - -`OpenStack Wiki `_ - -Glance on Launchpad -------------------- - -Launchpad is a code hosting service that hosts the Glance source code. From -Launchpad you can report bugs, ask questions, and register blueprints (feature requests). - -* `Learn about how to use bzr with launchpad `_ -* `Launchpad Glance Page `_ - -OpenStack Blog --------------- - -The OpenStack blog includes a weekly newsletter that aggregates OpenStack news -from around the internet, as well as providing inside information on upcoming -events and posts from OpenStack contributors. - -`OpenStack Blog `_ - -See also: `Planet OpenStack `_, aggregating blogs -about OpenStack from around the internet into a single feed. If you'd like to contribute to this blog -aggregation with your blog posts, there are instructions for `adding your blog `_. - -Twitter -------- - -Because all the cool kids do it: `@openstack `_. Also follow the -`#openstack `_ tag for relevant tweets. diff -Nru glance-2012.1~rc1~20120309.1315/doc/source/configuring.rst glance-2012.1~rc1~20120316.1354/doc/source/configuring.rst --- glance-2012.1~rc1~20120309.1315/doc/source/configuring.rst 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/doc/source/configuring.rst 2012-03-16 00:16:11.000000000 +0000 @@ -49,7 +49,7 @@ application for each component) may be found by default in -paste.ini alongside the main configuration file, .conf. For example, ``glance-api-paste.ini`` corresponds to ``glance-api.conf``. -This pathname for the paste config is configurable, as follows: +This pathname for the paste config is configurable, as follows:: [paste_deploy] config_file = /path/to/paste/config @@ -597,14 +597,18 @@ ``glance-cache-pruner`` executable is what prunes the image cache to be equal to or less than this value. The ``glance-cache-pruner`` executable is designed to be run via cron on a regular basis. See more about this executable in -`Controlling the Growth of the Image Cache` +:doc:`Controlling the Growth of the Image Cache ` + +.. note:: + + These configuration options must be set in both the glance-cache + and glance-api configuration files. Configuring the Glance Registry ------------------------------- -Glance ships with a default, reference implementation registry server. There -are a number of configuration options in Glance that control how this registry -server operates. These configuration options are specified in the +There are a number of configuration options in Glance that control how +this registry server operates. These configuration options are specified in the ``glance-registry.conf`` config file in the section ``[DEFAULT]``. * ``sql_connection=CONNECTION_STRING`` (``--sql-connection`` when specified diff -Nru glance-2012.1~rc1~20120309.1315/doc/source/conf.py glance-2012.1~rc1~20120316.1354/doc/source/conf.py --- glance-2012.1~rc1~20120309.1315/doc/source/conf.py 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/doc/source/conf.py 2012-03-16 00:16:18.000000000 +0000 @@ -47,10 +47,7 @@ 'sphinx.ext.ifconfig', 'sphinx.ext.intersphinx', 'sphinx.ext.pngmath', - 'sphinx.ext.graphviz', - 'sphinx.ext.todo'] - -todo_include_todos = True + 'sphinx.ext.graphviz'] # Add any paths that contain templates here, relative to this directory. templates_path = [] @@ -138,8 +135,6 @@ u'Glance Cache Pre-fetcher', [u'OpenStack'], 1), ('man/glancecachepruner', 'glance-cache-pruner', u'Glance Cache Pruner', [u'OpenStack'], 1), - ('man/glancecachequeueimage', 'glance-cache-queue-image', - u'Glance Cache Queue Image', [u'OpenStack'], 1), ('man/glancecontrol', 'glance-control', u'Glance Daemon Control Helper ', [u'OpenStack'], 1), ('man/glancemanage', 'glance-manage', u'Glance Management Utility', diff -Nru glance-2012.1~rc1~20120309.1315/doc/source/controllingservers.rst glance-2012.1~rc1~20120316.1354/doc/source/controllingservers.rst --- glance-2012.1~rc1~20120309.1315/doc/source/controllingservers.rst 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/doc/source/controllingservers.rst 2012-03-16 00:16:11.000000000 +0000 @@ -24,13 +24,13 @@ ----------------- There are two ways to start a Glance server (either the API server or the -reference implementation registry server that ships with Glance): +registry server): * Manually calling the server program * Using the ``glance-control`` server daemon wrapper program -We recommend using the second way. +We recommend using the second method. Manually starting the server ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff -Nru glance-2012.1~rc1~20120309.1315/doc/source/gettingstarted.rst glance-2012.1~rc1~20120316.1354/doc/source/gettingstarted.rst --- glance-2012.1~rc1~20120309.1315/doc/source/gettingstarted.rst 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/doc/source/gettingstarted.rst 1970-01-01 00:00:00.000000000 +0000 @@ -1,83 +0,0 @@ -.. - Copyright 2010 OpenStack, LLC - 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. - -Quick Guide to Getting Started with Glance -========================================== - -Glance is a server that provides the following services: - -* Ability to store and retrieve virtual machine images -* Ability to store and retrieve metadata about these virtual machine images -* FUTURE: Convert a virtual machine image from one format to another -* FUTURE: Help caching proxies such as Varnish or Squid cache machine images - -Communication with Glance occurs via a REST-like HTTP interface. - -However, Glance includes a :doc:`Client ` class that makes working with Glance -easy and straightforward. - -In the Cactus release, there will be also command-line tools for -interacting with Glance. - -Overview of Glance Architecture -------------------------------- - -There are two main parts to Glance's architecture: - -* Glance API server -* Glance Registry server(s) - -Glance API Server -***************** - -The API server is the main interface for Glance. It routes requests from -clients to registries of image metadata and to its **backend stores**, which -are the mechanisms by which Glance actually saves incoming virtual machine -images. - -The backend stores that Glance can work with are as follows: - -* **Swift** - - Swift is the highly-available object storage project in OpenStack. More - information can be found about Swift `here `_. - -* **Filesystem** - - The default backend that Glance uses to store virtual machine images - is the filesystem backend. This simple backend writes image files to the - local filesystem. - -* **S3** - - This backend allows Glance to store virtual machine images in Amazon's - S3 service. - -* **HTTP** - - Glance can read virtual machine images that are available via - HTTP somewhere on the Internet. This store is **readonly** - -Glance Registry Servers -*********************** - -Glance registry servers are servers that conform to the Glance Registry API. -Glance ships with a reference implementation of a registry server that -complies with this API (``glance-registry``). - -For more details on Glance's architecture see :doc:`here `. For -more information on what a Glance registry server is, see -:doc:`here `. diff -Nru glance-2012.1~rc1~20120309.1315/doc/source/glance.rst glance-2012.1~rc1~20120316.1354/doc/source/glance.rst --- glance-2012.1~rc1~20120309.1315/doc/source/glance.rst 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/doc/source/glance.rst 2012-03-16 00:16:11.000000000 +0000 @@ -17,7 +17,7 @@ Using the Glance CLI Tool ========================= -Glance ships with a command-line tool for querying and managing Glance +Glance ships with a command-line tool for querying and managing Glance. It has a fairly simple but powerful interface of the form:: Usage: glance [options] [args] @@ -89,27 +89,56 @@ clear Removes all images and metadata from Glance + + Member Commands: + + image-members List members an image is shared with + + member-images List images shared with a member + + member-add Grants a member access to an image + + member-delete Revokes a member's access to an image + + members-replace Replaces all membership for an image + Options: --version show program's version number and exit -h, --help show this help message and exit + --silent-upload disable progress bar animation and information during + upload -v, --verbose Print more verbose output + -d, --debug Print more verbose output -H ADDRESS, --host=ADDRESS - Address of Glance API host. Default: example.com + Address of Glance API host. Default: 0.0.0.0 -p PORT, --port=PORT Port the Glance API host listens on. Default: 9292 -U URL, --url=URL URL of Glance service. This option can be used to specify the hostname, port and protocol (http/https) of the glance server, for example -U https://localhost:9292/v1 Default: None - -k, --insecure Explicitly allow glance to perform insecure SSL - requests. The server certificate will not be - verified against any certificate authorities. - This option should be used with caution. - -R REGION, --region=REGION - When using keystone authentication version 2.0 - or later this identifies the region name to - use when selecting the service endpoint. Where - more than one region endpoint is available a - region must be provided. + -k, --insecure Explicitly allow glance to perform "insecure" SSL + (https) requests. The server's certificate will not be + verified against any certificate authorities. This + option should be used with caution. + -A TOKEN, --os_auth_token=TOKEN + Authentication token to use to identify the client to + the glance server + -I USER, --os_username=USER + User name used to acquire an authentication token + -K PASSWORD, --os_password=PASSWORD + Password used to acquire an authentication token + -R REGION, --os_region_name=REGION + Region name. When using keystone authentication + version 2.0 or later this identifies the region name + to use when selecting the service endpoint. A region + name must be provided if more than one region endpoint + is available + -T TENANT, --os_tenant_name=TENANT + Tenant name + -N AUTH_URL, --os_auth_url=AUTH_URL + Authentication URL + -S STRATEGY, --os_auth_strategy=STRATEGY + Authentication strategy (keystone or noauth) --limit=LIMIT Page size to use while requesting image metadata --marker=MARKER Image index after which to begin pagination --sort_key=KEY Sort results by this image attribute. @@ -119,6 +148,7 @@ confirmation --dry-run Don't actually execute the command, just print output showing what WOULD happen. + --can-share Allow member to further share image. With a ```` argument, more information on the command is shown, like so:: @@ -129,19 +159,26 @@ Updates an image's metadata in Glance. Specify metadata fields as arguments. + Metadata fields that are not specified in the update command will be deleted. + All field/value pairs are converted into a mapping that is passed to Glance that represents the metadata for an image. Field names that can be specified: name A name for the image. + location An external location to serve out from. + copy_from An external location (HTTP, S3 or Swift URI) to copy image + content from. is_public If specified, interpreted as a boolean value and sets or unsets the image's availability to the public. - disk_format Format of the disk image (required) - container_format Format of the container (required) + protected If specified, interpreted as a boolean value + and enables or disables deletion protection for the image. + disk_format Format of the disk image + container_format Format of the container All other field names are considered to be custom properties so be careful - to spell field names correctly. :) + to spell field names correctly. .. _glance-add: @@ -183,18 +220,13 @@ ``glance``. Let's walk through a simple example. Suppose we have a virtual disk image -stored on our local filesystem that we wish to "upload" to Glance. This image -is stored on our local filesystem in ``/tmp/images/myimage.iso``. - -We'd also like to tell Glance that this image should be called "My Image", and +stored on our local filesystem at ``/tmp/images/myimage.iso``. We'd also +like to tell Glance that this image should be called "My Image", and that the image should be public -- anyone should be able to fetch it. - -Here is how we'd upload this image to Glance. Change example IP number to your -server IP number.:: +Here is how we'd upload this image to Glance:: $> glance add name="My Image" is_public=true \ - container_format=ovf disk_format=raw \ - --host=65.114.169.29 < /tmp/images/myimage.iso + container_format=ovf disk_format=raw < /tmp/images/myimage.iso Note that the disk container formats are no longer defaulted and are thus strictly required. @@ -203,18 +235,17 @@ metadata attributes, you would see something like this:: $> glance add name="My Image" is_public=true \ - container_format=ovf disk_format=raw \ - --host=65.114.169.29 < /tmp/images/myimage.iso + container_format=ovf disk_format=raw < /tmp/images/myimage.iso Added new image with ID: 991baaf9-cc0d-4183-a201-8facdf1a1430 You can use the ``--verbose`` (or ``-v``) command-line option to print some more information about the metadata that was saved with the image:: $> glance --verbose add name="My Image" is_public=true \ - container_format=ovf disk_format=raw \ - --host=65.114.169.29 < /tmp/images/myimage.iso + container_format=ovf disk_format=raw < /tmp/images/myimage.iso Added new image with ID: 541424be-27b1-49d6-a55b-6430b8ae0f5f Returned the following metadata for the new image: + checksum => 2cec138d7dae2aa59038ef8c9aec2390 container_format => ovf created_at => 2011-02-22T19:20:53.298556 deleted => False @@ -222,27 +253,33 @@ disk_format => raw id => 541424be-27b1-49d6-a55b-6430b8ae0f5f is_public => True - location => file:///tmp/images/4 + min_disk => 0 + min_ram => 0 name => My Image + owner => tenant1 properties => {} + protected => False size => 58520278 status => active - updated_at => None + updated_at => 2011-02-22T19:20:54.451291 Completed in 0.6141 sec. If you are unsure about what will be added, you can use the ``--dry-run`` command-line option, which will simply show you what *would* have happened:: $> glance --dry-run add name="Foo" distro="Ubuntu" is_public=True \ - container_format=ovf disk_format=raw \ - --host=65.114.169.29 < /tmp/images/myimage.iso + container_format=ovf disk_format=raw < /tmp/images/myimage.iso Dry run. We would have done the following: Add new image with metadata: container_format => ovf disk_format => raw + id => None is_public => False + min_disk => 0 + min_ram => 0 name => Foo properties => {'is_public': 'True', 'distro': 'Ubuntu'} + protected => False This is useful for detecting problems and for seeing what the default field values supplied by ``glance`` are. For instance, there was a typo in @@ -257,53 +294,55 @@ To upload an EC2 tarball VM image:: $> glance add name="ubuntu-10.10-amd64" is_public=true \ - container_format=ovf disk_format=raw \ - < /root/maverick-server-uec-amd64.tar.gz + container_format=ovf disk_format=raw \ + < maverick-server-uec-amd64.tar.gz To upload an EC2 tarball VM image with an associated property (e.g., distro):: $> glance add name="ubuntu-10.10-amd64" is_public=true \ - container_format=ovf disk_format=raw \ - distro="ubuntu 10.10" < /root/maverick-server-uec-amd64.tar.gz + container_format=ovf disk_format=raw \ + distro="ubuntu 10.10" < /root/maverick-server-uec-amd64.tar.gz To reference an EC2 tarball VM image available at an external URL:: $> glance add name="ubuntu-10.04-amd64" is_public=true \ - container_format=ovf disk_format=raw \ - location="http://uec-images.ubuntu.com/lucid/current/\ - lucid-server-uec-amd64.tar.gz" + container_format=ovf disk_format=raw \ + location="http://uec-images.ubuntu.com/lucid/current/\ + lucid-server-uec-amd64.tar.gz" To upload a copy of that same EC2 tarball VM image:: $> glance add name="ubuntu-10.04-amd64" is_public=true \ - container_format=ovf disk_format=raw \ - copy_from="http://uec-images.ubuntu.com/lucid/current/\ - lucid-server-uec-amd64.tar.gz" + container_format=ovf disk_format=raw \ + copy_from="http://uec-images.ubuntu.com/lucid/current/lucid-server-uec-amd64.tar.gz" To upload a qcow2 image:: $> glance add name="ubuntu-11.04-amd64" is_public=true \ - container_format=ovf disk_format=qcow2 \ - distro="ubuntu 11.04" < /data/images/rock_natty.qcow2 + container_format=ovf disk_format=qcow2 \ + distro="ubuntu 11.04" < /data/images/rock_natty.qcow2 -To upload a kernel file, ramdisk file and filesystem image file:: +To upload kernel, ramdisk and machine image files:: $> glance add disk_format=aki container_format=aki \ - ./maverick-server-uec-amd64-vmlinuz-virtual \ - maverick-server-uec-amd64-vmlinuz-virtual + name="maverick-server-uec-amd64-vmlinuz-virtual" \ + < maverick-server-uec-amd64-vmlinuz-virtual $> glance add disk_format=ari container_format=ari \ - ./maverick-server-uec-amd64-loader maverick-server-uec-amd64-loader + name="maverick-server-uec-amd64-loader" \ + < maverick-server-uec-amd64-loader # Determine what the ids associated with the kernel and ramdisk files $> glance index - # Assuming the ids are 7 and 8: - $> glance add disk_format=ami container_format=ami kernel_id=7 \ - ramdisk_id=8 ./maverick-server-uec-amd64.img maverick-server-uec-amd64.img + # Assuming the ids are 94c2adcf-1bca-4881-92f1-62fe7593f108 and 6e75405d-7de0-4c99-b936-87f98ff4959f: + $> glance add disk_format=ami container_format=ami \ + name="maverick-server-uec-amd64" \ + kernel_id=94c2adcf-1bca-4881-92f1-62fe7593f108 \ + ramdisk_id=6e75405d-7de0-4c99-b936-87f98ff4959f \ + < maverick-server-uec-amd64.img To upload a raw image file:: $> glance add disk_format=raw container_format=ovf \ - ./maverick-server-uec-amd64.img maverick-server-uec-amd64.img_v2 - + name="maverick-server-uec-amd64.img_v2" < maverick-server-uec-amd64.img Register a virtual machine image in another location ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -322,24 +361,9 @@ ``http://example.com/images/myimage.vhd``. We can register this image with Glance using the following:: - $> glance --verbose add name="Some web image" disk_format=vhd \ - container_format=ovf location="http://example.com/images/myimage.vhd" + $> glance add name="Some web image" disk_format=vhd \ + container_format=ovf location="http://example.com/images/myimage.vhd" Added new image with ID: 71c675ab-d94f-49cd-a114-e12490b328d9 - Returned the following metadata for the new image: - container_format => ovf - created_at => 2011-02-23T00:42:04.688890 - deleted => False - deleted_at => None - disk_format => vhd - id => 71c675ab-d94f-49cd-a114-e12490b328d9 - is_public => True - location => http://example.com/images/myimage.vhd - name => Some web image - properties => {} - size => 0 - status => active - updated_at => None - Completed in 0.0356 sec. The ``update`` command ---------------------- @@ -355,27 +379,31 @@ glance update [field1=value1 field2=value2 ...] Let's say we have an image with identifier -'9afc4097-1c70-45c3-8c12-1b897f083faa' that we wish to change the is_public +'9afc4097-1c70-45c3-8c12-1b897f083faa' that we wish to change the 'is_public' attribute of the image from False to True. The following would accomplish this:: - $> glance update 9afc4097-1c70-45c3-8c12-1b897f083faa is_public=true \ - --host=65.114.169.29 + $> glance update 9afc4097-1c70-45c3-8c12-1b897f083faa is_public=true Updated image 9afc4097-1c70-45c3-8c12-1b897f083faa Using the ``--verbose`` flag will show you all the updated data about the image:: $> glance --verbose update 97243446-9c74-42af-a31a-34ba16555868 \ - is_public=true --host=65.114.169.29 + is_public=true Updated image 97243446-9c74-42af-a31a-34ba16555868 Updated image metadata for image 97243446-9c74-42af-a31a-34ba16555868: - URI: http://example.com/images/97243446-9c74-42af-a31a-34ba16555868 + URI: http://glance.example.com/v1/images/97243446-9c74-42af-a31a-34ba16555868 Id: 97243446-9c74-42af-a31a-34ba16555868 - Public? Yes + Public: Yes + Protected: No Name: My Image + Status: active Size: 58520278 Disk format: raw Container format: ovf + Minimum Ram Required (MB): 0 + Minimum Disk Required (GB): 0 + Owner: tenant1 Completed in 0.0596 sec. The ``delete`` command @@ -383,17 +411,17 @@ You can delete an image by using the ``delete`` command, shown below:: - $> glance --verbose delete 660c96a7-ef95-45e7-8e48-595df6937675 \ - --host=65.114.169.29 -f + $> glance --verbose -f delete 660c96a7-ef95-45e7-8e48-595df6937675 + Delete image 660c96a7-ef95-45e7-8e48-595df6937675? [y/N] y Deleted image 660c96a7-ef95-45e7-8e48-595df6937675 The ``index`` command --------------------- -The ``index`` command displays brief information about the *public* images -available in Glance, as shown below:: +The ``index`` command displays brief information about public images available +in Glance alongside any private images you can access, as shown below:: - $> glance index --host=65.114.169.29 + $> glance index ID Name Disk Format Container Format Size ------------------------------------ ------------------------------ -------------------- -------------------- -------------- baa87554-34d2-4e9e-9949-e9e5620422bb Ubuntu 10.10 vhd ovf 58520278 @@ -404,7 +432,7 @@ Image metadata such as 'name', 'disk_format', 'container_format' and 'status' may be used to filter the results of an index or details command. These commands also accept 'size_min' and 'size_max' as lower and upper bounds -of the image metadata 'size.' Any unrecognized fields are handled as +of the image attribute 'size.' Any unrecognized fields are handled as custom image properties. The 'limit' and 'marker' options are used by the index and details commands @@ -426,49 +454,65 @@ The ``details`` command displays detailed information about the *public* images available in Glance, as shown below:: - $> glance details --host=65.114.169.29 + $> glance details ============================================================================== URI: http://example.com/images/baa87554-34d2-4e9e-9949-e9e5620422bb Id: baa87554-34d2-4e9e-9949-e9e5620422bb - Public? Yes + Public: Yes + Protected: No Name: Ubuntu 10.10 Status: active Size: 58520278 Disk format: vhd Container format: ovf + Minimum Ram Required (MB): 0 + Minimum Disk Required (GB): 0 + Owner: None Property 'distro_version': 10.10 Property 'distro': Ubuntu ============================================================================== URI: http://example.com/images/9e1aede2-dc6e-4981-9f3e-93dee24d48b1 Id: 9e1aede2-dc6e-4981-9f3e-93dee24d48b1 - Public? Yes + Public: Yes + Protected: No Name: Ubuntu 10.04 Status: active Size: 58520278 Disk format: ami Container format: ami + Minimum Ram Required (MB): 0 + Minimum Disk Required (GB): 0 + Owner: None Property 'distro_version': 10.04 Property 'distro': Ubuntu ============================================================================== URI: http://example.com/images/771c0223-27b4-4789-a83d-79eb9c166578 Id: 771c0223-27b4-4789-a83d-79eb9c166578 - Public? Yes + Public: Yes + Protected: No Name: Fedora 9 Status: active Size: 3040 Disk format: vdi Container format: bare + Minimum Ram Required (MB): 512 + Minimum Disk Required (GB): 10 + Owner: None Property 'distro_version': 9 Property 'distro': Fedora ============================================================================== URI: http://example.com/images/cb8f4908-ef58-4e4b-884e-517cf09ead86 Id: cb8f4908-ef58-4e4b-884e-517cf09ead86 - Public? Yes + Public: Yes + Protected: No Name: Vanilla Linux 2.6.22 Status: active Size: 0 Disk format: qcow2 Container format: bare + Minimum Ram Required (MB): 0 + Minimum Disk Required (GB): 0 + Owner: tenant1 ============================================================================== The ``show`` command @@ -477,15 +521,19 @@ The ``show`` command displays detailed information about a specific image, specified with ````, as shown below:: - $> glance show 771c0223-27b4-4789-a83d-79eb9c166578 --host=65.114.169.29 + $> glance show 771c0223-27b4-4789-a83d-79eb9c166578 URI: http://example.com/images/771c0223-27b4-4789-a83d-79eb9c166578 Id: 771c0223-27b4-4789-a83d-79eb9c166578 - Public? Yes + Public: Yes + Protected: No Name: Fedora 9 Status: active Size: 3040 Disk format: vdi Container format: bare + Minimum Ram Required (MB): 512 + Minimum Disk Required (GB): 10 + Owner: None Property 'distro_version': 9 Property 'distro': Fedora @@ -496,7 +544,7 @@ and all image metadata. Passing the ``--verbose`` command will print brief information about all the images that were deleted, as shown below:: - $> glance --verbose clear --host=65.114.169.29 + $> glance --verbose clear Deleting image ab15b8d3-8f33-4467-abf2-9f89a042a8c4 "Some web image" ... done Deleting image dc9698b4-e9f1-4f75-b777-1a897633e488 "Some other web image" ... done Completed in 0.0328 sec. @@ -507,8 +555,7 @@ The ``image-members`` command displays the list of members with which a specific image, specified with ````, is shared, as shown below:: - $> glance image-members ab15b8d3-8f33-4467-abf2-9f89a042a8c4 \ - --host=65.114.169.29 + $> glance image-members ab15b8d3-8f33-4467-abf2-9f89a042a8c4 tenant1 tenant2 * @@ -520,7 +567,7 @@ The ``member-images`` command displays the list of images which are shared with a specific member, specified with ````, as shown below:: - $> glance member-images tenant1 --host=65.114.169.29 + $> glance member-images tenant1 ab15b8d3-8f33-4467-abf2-9f89a042a8c4 dc9698b4-e9f1-4f75-b777-1a897633e488 * @@ -533,10 +580,8 @@ to a private image, specified with ````. The ``--can-share`` flag can be given to allow the member to share the image, as shown below:: - $> glance member-add ab15b8d3-8f33-4467-abf2-9f89a042a8c4 tenant1 \ - --host=65.114.169.29 - $> glance member-add ab15b8d3-8f33-4467-abf2-9f89a042a8c4 tenant2 \ - --can-share --host=65.114.169.29 + $> glance member-add ab15b8d3-8f33-4467-abf2-9f89a042a8c4 tenant1 + $> glance member-add ab15b8d3-8f33-4467-abf2-9f89a042a8c4 tenant2 --can-share The ``member-delete`` Command ----------------------------- @@ -556,7 +601,7 @@ allow the member to share the image, as shown below:: $> glance members-replace ab15b8d3-8f33-4467-abf2-9f89a042a8c4 tenant1 \ - --can-share --host=65.114.169.29 + --can-share The command is given in plural form to make it clear that all existing memberships are affected by the command. diff -Nru glance-2012.1~rc1~20120309.1315/doc/source/identifiers.rst glance-2012.1~rc1~20120316.1354/doc/source/identifiers.rst --- glance-2012.1~rc1~20120309.1315/doc/source/identifiers.rst 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/doc/source/identifiers.rst 2012-03-16 00:16:11.000000000 +0000 @@ -20,7 +20,7 @@ Images are uniquely identified by way of a URI that matches the following signature:: - /images/ + /v1/images/ where `` is the resource location of the Glance service that knows about an image, and `` is the image's identifier. Image diff -Nru glance-2012.1~rc1~20120309.1315/doc/source/index.rst glance-2012.1~rc1~20120316.1354/doc/source/index.rst --- glance-2012.1~rc1~20120309.1315/doc/source/index.rst 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/doc/source/index.rst 2012-03-16 00:16:11.000000000 +0000 @@ -36,8 +36,7 @@ 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`_. Also see the :doc:`community` page for -other ways to interact with the community. +be found on the `OpenStack wiki`_. .. _`OpenStack wiki`: http://wiki.openstack.org @@ -48,7 +47,6 @@ :maxdepth: 1 identifiers - registries statuses formats @@ -58,7 +56,6 @@ .. toctree:: :maxdepth: 1 - gettingstarted installing controllingservers configuring @@ -78,11 +75,6 @@ architecture community -Outstanding Documentation Tasks -=============================== - -.. todolist:: - Indices and tables ================== diff -Nru glance-2012.1~rc1~20120309.1315/doc/source/installing.rst glance-2012.1~rc1~20120316.1354/doc/source/installing.rst --- glance-2012.1~rc1~20120309.1315/doc/source/installing.rst 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/doc/source/installing.rst 2012-03-16 00:16:11.000000000 +0000 @@ -47,11 +47,6 @@ $ su - # yum install openstack-glance -Mac OSX -####### - -.. todo:: No idea how to do install on Mac OSX. Somebody with a Mac should complete this section - Installing from source tarballs ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -140,8 +135,3 @@ $ su - # python setup.py install - -Mac OSX -####### - -.. todo:: No idea how to do install on Mac OSX. Somebody with a Mac should complete this section diff -Nru glance-2012.1~rc1~20120309.1315/doc/source/man/glancecachequeueimage.rst glance-2012.1~rc1~20120316.1354/doc/source/man/glancecachequeueimage.rst --- glance-2012.1~rc1~20120309.1315/doc/source/man/glancecachequeueimage.rst 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/doc/source/man/glancecachequeueimage.rst 1970-01-01 00:00:00.000000000 +0000 @@ -1,87 +0,0 @@ -======================== -glance-cache-queue-image -======================== - ----------------------------- -Queue images for prefetching ----------------------------- - -:Author: glance@lists.launchpad.net -:Date: 2012-01-03 -:Copyright: OpenStack LLC -:Version: 2012.1-dev -:Manual section: 1 -:Manual group: cloud computing - -SYNOPSIS -======== - - glance-cache-queue-image [OPTIONS] [ ... ] - -OPTIONS -======= - - **--version** - show program's version number and exit - - **-h, --help** - show this help message and exit - - **--config-file=PATH** - Path to a config file to use. Multiple config files - can be specified, with values in later files taking - precedence. The default files used are: [] - - **-d, --debug** - Print debugging output - - **--nodebug** - Do not print debugging output - - **-v, --verbose** - Print more verbose output - - **--noverbose** - Do not print more verbose output - - **--log-config=PATH** - If this option is specified, the logging configuration - file specified is used and overrides any other logging - options specified. Please see the Python logging - module documentation for details on logging - configuration files. - - **--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** - (Optional) Name of log file to output to. If not set, - logging will go to stdout. - - **--log-dir=LOG_DIR** - (Optional) The directory to keep log files in (will be - prepended to --logfile) - - **--use-syslog** - Use syslog for logging. - - **--nouse-syslog** - Do not use syslog for logging. - - **--syslog-log-facility=SYSLOG_LOG_FACILITY** - syslog facility to receive log lines - -SEE ALSO -======== - -* `OpenStack Glance `__ - -BUGS -==== - -* Glance is sourced in Launchpad so you can view current bugs at `OpenStack Glance `__ diff -Nru glance-2012.1~rc1~20120309.1315/doc/source/man/glanceregistry.rst glance-2012.1~rc1~20120316.1354/doc/source/man/glanceregistry.rst --- glance-2012.1~rc1~20120309.1315/doc/source/man/glanceregistry.rst 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/doc/source/man/glanceregistry.rst 2012-03-16 00:16:11.000000000 +0000 @@ -21,8 +21,8 @@ DESCRIPTION =========== -glance-registry is the reference implementation of a server daemon that serves -image metadata based on the Glance Registry REST-like API. +glance-registry is a server daemon that serves image metadata through a +REST-like API. OPTIONS ======= diff -Nru glance-2012.1~rc1~20120309.1315/doc/source/man/glancescrubber.rst glance-2012.1~rc1~20120316.1354/doc/source/man/glancescrubber.rst --- glance-2012.1~rc1~20120309.1315/doc/source/man/glancescrubber.rst 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/doc/source/man/glancescrubber.rst 2012-03-16 00:16:11.000000000 +0000 @@ -18,6 +18,25 @@ glance-scrubber [options] +DESCRIPTION +=========== + +glance-scrubber is an utility that cleans up images that have been deleted. The +mechanics of this differ depending on the backend store and pending_deletion +options chosen. + +Multiple glance-scrubbers can be run in a single deployment, but only one of +them may be designated as the 'cleanup_scrubber' in the glance-scrubber.conf +file. The 'cleanup_scrubber' coordinates other glance-scrubbers by maintaining +the master queue of images that need to be removed. + +The glance-scubber.conf file also specifies important configuration items such +as the time between runs ('wakeup_time' in seconds), length of time images +can be pending before their deletion ('cleanup_scrubber_time' in seconds) as +well as registry connectivity options. + +glance-scrubber can run as a periodic job or long-running daemon. + OPTIONS ======= @@ -84,10 +103,7 @@ wakeup_time interval as specified in the config. **--nodaemon** - Run as a long-running process. When not specified (the - default) run the scrub operation once and then exits. - When specified do not exit and run scrub on - wakeup_time interval as specified in the config. + The inverse of --daemon. Runs the scrub operation once and then exits. SEE ALSO ======== diff -Nru glance-2012.1~rc1~20120309.1315/doc/source/registries.rst glance-2012.1~rc1~20120316.1354/doc/source/registries.rst --- glance-2012.1~rc1~20120309.1315/doc/source/registries.rst 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/doc/source/registries.rst 1970-01-01 00:00:00.000000000 +0000 @@ -1,138 +0,0 @@ -.. - Copyright 2010 OpenStack, LLC - 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 Registries -================ - -Image metadata made available through Glance can be stored in image -`registries`. Image registries are any web service that adheres to the -Glance REST-like API for image metadata. - -Glance comes with a server program ``glance-registry`` that acts -as a reference implementation of a Glance Registry. - -Please see the document :doc:`on Controlling Servers ` -for more information on starting up the Glance registry server that ships -with Glance. - -Glance Registry API -------------------- - -Any web service that publishes an API that conforms to the following -REST-like API specification can be used by Glance as a registry. - -API in Summary -************** - -The following is a brief description of the Glance API:: - - GET /images Return brief information about public images - GET /images/detail Return detailed information about public images - GET /images/ Return metadata about an image in HTTP headers - POST /images Register metadata about a new image - PUT /images/ Update metadata about an existing image - DELETE /images/ Remove an image's metadata from the registry - -Filtering Images Returned via ``GET /images`` and ``GET /images/detail`` ------------------------------------------------------------------------- - -Both the ``GET /images`` and ``GET /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 ` - -* ``disk_format=FORMAT`` - - Filters images having a ``disk_format`` attribute matching ``FORMAT`` - - For more information, see :doc:`About Disk and Container Formats ` - -* ``status=STATUS`` - - Filters images having a ``status`` attribute matching ``STATUS`` - - For more information, see :doc:`About Image 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 sort 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. - - -``POST /images`` ----------------- - -The body of the request will be a JSON-encoded set of data about -the image to add to the registry. It will be in the following format:: - - {'image': - {'id': |None, - 'name': , - 'status': , - 'disk_format': , - 'container_format': , - 'properties': [ ... ] - } - } - -The request shall validate the following conditions and return a -``400 Bad request`` when any of the conditions are not met: - -* ``status`` must be non-empty, and must be one of **active**, **saving**, - **queued**, or **killed** - -* ``disk_format`` must be non-empty, and must be one of **ari**, **aki**, - **ami**, **raw**, **iso**, **vhd**, **vdi**, **qcow2**, or **vmdk** - -* ``container_format`` must be non-empty, and must be on of **ari**, - **aki**, **ami**, **bare**, or **ovf** - -* If ``disk_format`` *or* ``container_format`` is **ari**, **aki**, - **ami**, then *both* ``disk_format`` and ``container_format`` must be - the same. - -* ``id`` must be a uuid in hexadecimal string notation - (i.e. '71c675ab-d94f-49cd-a114-e12490b328d9') - -Examples -******** - -.. todo:: Complete examples for Glance registry API diff -Nru glance-2012.1~rc1~20120309.1315/etc/glance-cache.conf glance-2012.1~rc1~20120316.1354/etc/glance-cache.conf --- glance-2012.1~rc1~20120309.1315/etc/glance-cache.conf 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/etc/glance-cache.conf 2012-03-16 00:16:11.000000000 +0000 @@ -36,5 +36,8 @@ # Port the registry server is listening on registry_port = 9191 -# Admin token to use if using Keystone -# admin_token = 123 +# Auth settings if using Keystone +# auth_url = http://127.0.0.1:5000/v2.0/ +# admin_tenant_name = %SERVICE_TENANT_NAME% +# admin_user = %SERVICE_USER% +# admin_password = %SERVICE_PASSWORD% diff -Nru glance-2012.1~rc1~20120309.1315/glance/api/cached_images.py glance-2012.1~rc1~20120316.1354/glance/api/cached_images.py --- glance-2012.1~rc1~20120309.1315/glance/api/cached_images.py 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/glance/api/cached_images.py 2012-03-16 00:16:11.000000000 +0000 @@ -21,13 +21,9 @@ import logging -import webob.exc - -from glance.common import exception -from glance.common import wsgi from glance.api.v1 import controller +from glance.common import wsgi from glance import image_cache -from glance import registry logger = logging.getLogger(__name__) diff -Nru glance-2012.1~rc1~20120309.1315/glance/api/middleware/cache_manage.py glance-2012.1~rc1~20120316.1354/glance/api/middleware/cache_manage.py --- glance-2012.1~rc1~20120309.1315/glance/api/middleware/cache_manage.py 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/glance/api/middleware/cache_manage.py 2012-03-16 00:16:18.000000000 +0000 @@ -21,6 +21,8 @@ import logging +import routes + from glance.api import cached_images from glance.common import wsgi @@ -29,43 +31,56 @@ class CacheManageFilter(wsgi.Middleware): def __init__(self, app, conf, **local_conf): - map = app.map + mapper = routes.Mapper() resource = cached_images.create_resource(conf) - map.connect("/cached_images", - controller=resource, - action="get_cached_images", - conditions=dict(method=["GET"])) - - map.connect("/cached_images/{image_id}", - controller=resource, - action="delete_cached_image", - conditions=dict(method=["DELETE"])) - - map.connect("/cached_images", - controller=resource, - action="delete_cached_images", - conditions=dict(method=["DELETE"])) - - map.connect("/queued_images/{image_id}", - controller=resource, - action="queue_image", - conditions=dict(method=["PUT"])) - - map.connect("/queued_images", - controller=resource, - action="get_queued_images", - conditions=dict(method=["GET"])) - - map.connect("/queued_images/{image_id}", - controller=resource, - action="delete_queued_image", - conditions=dict(method=["DELETE"])) - - map.connect("/queued_images", - controller=resource, - action="delete_queued_images", - conditions=dict(method=["DELETE"])) + mapper.connect("/v1/cached_images", + controller=resource, + action="get_cached_images", + conditions=dict(method=["GET"])) + + mapper.connect("/v1/cached_images/{image_id}", + controller=resource, + action="delete_cached_image", + conditions=dict(method=["DELETE"])) + + mapper.connect("/v1/cached_images", + controller=resource, + action="delete_cached_images", + conditions=dict(method=["DELETE"])) + + mapper.connect("/v1/queued_images/{image_id}", + controller=resource, + action="queue_image", + conditions=dict(method=["PUT"])) + + mapper.connect("/v1/queued_images", + controller=resource, + action="get_queued_images", + conditions=dict(method=["GET"])) + + mapper.connect("/v1/queued_images/{image_id}", + controller=resource, + action="delete_queued_image", + conditions=dict(method=["DELETE"])) + + mapper.connect("/v1/queued_images", + controller=resource, + action="delete_queued_images", + conditions=dict(method=["DELETE"])) + + self._mapper = mapper + self._resource = resource logger.info(_("Initialized image cache management middleware")) super(CacheManageFilter, self).__init__(app) + + def process_request(self, request): + # Map request to our resource object if we can handle it + match = self._mapper.match(request.path, request.environ) + if match: + request.environ['wsgiorg.routing_args'] = (None, match) + return self._resource(request) + # Pass off downstream if we don't match the request path + else: + return None diff -Nru glance-2012.1~rc1~20120309.1315/glance/api/middleware/cache.py glance-2012.1~rc1~20120316.1354/glance/api/middleware/cache.py --- glance-2012.1~rc1~20120309.1315/glance/api/middleware/cache.py 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/glance/api/middleware/cache.py 2012-03-16 00:16:11.000000000 +0000 @@ -30,12 +30,12 @@ import webob -from glance import image_cache -from glance import registry from glance.api.v1 import images from glance.common import exception from glance.common import utils from glance.common import wsgi +from glance import image_cache +from glance import registry logger = logging.getLogger(__name__) get_images_re = re.compile(r'^(/v\d+)*/images/([^\/]+)$') diff -Nru glance-2012.1~rc1~20120309.1315/glance/api/middleware/version_negotiation.py glance-2012.1~rc1~20120316.1354/glance/api/middleware/version_negotiation.py --- glance-2012.1~rc1~20120309.1315/glance/api/middleware/version_negotiation.py 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/glance/api/middleware/version_negotiation.py 2012-03-16 00:16:11.000000000 +0000 @@ -24,9 +24,6 @@ import logging import re -import routes - -from glance.api import v1 from glance.api import versions from glance.common import wsgi diff -Nru glance-2012.1~rc1~20120309.1315/glance/api/v1/images.py glance-2012.1~rc1~20120316.1354/glance/api/v1/images.py --- glance-2012.1~rc1~20120309.1315/glance/api/v1/images.py 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/glance/api/v1/images.py 2012-03-16 00:16:11.000000000 +0000 @@ -29,7 +29,6 @@ HTTPConflict, HTTPBadRequest, HTTPForbidden, - HTTPUnauthorized, HTTPRequestEntityTooLarge, HTTPServiceUnavailable, ) @@ -104,7 +103,7 @@ try: self.policy.enforce(req.context, action, {}) except exception.NotAuthorized: - raise HTTPUnauthorized() + raise HTTPForbidden() def index(self, req): """ @@ -388,7 +387,7 @@ "%(max_image_size)d. Supplied image size was " "%(image_size)d") % locals() logger.warn(msg) - raise HTTPBadRequest(msg, request=request) + raise HTTPBadRequest(msg, request=req) location, size, checksum = store.add(image_meta['id'], image_data, diff -Nru glance-2012.1~rc1~20120309.1315/glance/api/v1/members.py glance-2012.1~rc1~20120316.1354/glance/api/v1/members.py --- glance-2012.1~rc1~20120309.1315/glance/api/v1/members.py 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/glance/api/v1/members.py 2012-03-16 00:16:11.000000000 +0000 @@ -1,9 +1,24 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2012 OpenStack LLC. +# 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 logging import webob.exc -from glance import api from glance.common import exception from glance.common import wsgi from glance import registry diff -Nru glance-2012.1~rc1~20120309.1315/glance/api/versions.py glance-2012.1~rc1~20120316.1354/glance/api/versions.py --- glance-2012.1~rc1~20120309.1315/glance/api/versions.py 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/glance/api/versions.py 2012-03-16 00:16:11.000000000 +0000 @@ -24,8 +24,6 @@ import webob.dec -from glance.common import wsgi - class Controller(object): diff -Nru glance-2012.1~rc1~20120309.1315/glance/client.py glance-2012.1~rc1~20120316.1354/glance/client.py --- glance-2012.1~rc1~20120309.1315/glance/client.py 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/glance/client.py 2012-03-16 00:16:11.000000000 +0000 @@ -399,3 +399,51 @@ return transfer_info Client = V1Client + + +def get_client(host, port=None, username=None, + password=None, tenant=None, + auth_url=None, auth_strategy=None, + auth_token=None, region=None, + is_silent_upload=False, insecure=False): + """ + Returns a new client Glance client object based on common kwargs. + If an option isn't specified falls back to common environment variable + defaults. + """ + + if auth_url or os.getenv('OS_AUTH_URL'): + force_strategy = 'keystone' + else: + force_strategy = None + + creds = dict(username=username or + os.getenv('OS_AUTH_USER', os.getenv('OS_USERNAME')), + password=password or + os.getenv('OS_AUTH_KEY', os.getenv('OS_PASSWORD')), + tenant=tenant or + os.getenv('OS_AUTH_TENANT', + os.getenv('OS_TENANT_NAME')), + auth_url=auth_url or os.getenv('OS_AUTH_URL'), + strategy=force_strategy or auth_strategy or + os.getenv('OS_AUTH_STRATEGY', 'noauth'), + region=region or os.getenv('OS_REGION_NAME'), + ) + + if creds['strategy'] == 'keystone' and not creds['auth_url']: + msg = ("--os_auth_url option or OS_AUTH_URL environment variable " + "required when keystone authentication strategy is enabled\n") + raise exception.ClientConfigurationError(msg) + + use_ssl = (creds['auth_url'] is not None and + creds['auth_url'].find('https') != -1) + + client = (ProgressClient if not is_silent_upload else Client) + + return client(host=host, + port=port, + use_ssl=use_ssl, + auth_tok=auth_token or + os.getenv('OS_TOKEN'), + creds=creds, + insecure=insecure) diff -Nru glance-2012.1~rc1~20120309.1315/glance/common/auth.py glance-2012.1~rc1~20120316.1354/glance/common/auth.py --- glance-2012.1~rc1~20120309.1315/glance/common/auth.py 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/glance/common/auth.py 2012-03-16 00:16:11.000000000 +0000 @@ -30,10 +30,11 @@ > auth_plugin.management_url http://service_endpoint/ """ -import httplib2 import json import urlparse +import httplib2 + from glance.common import exception diff -Nru glance-2012.1~rc1~20120309.1315/glance/common/client.py glance-2012.1~rc1~20120316.1354/glance/common/client.py --- glance-2012.1~rc1~20120309.1315/glance/common/client.py 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/glance/common/client.py 2012-03-16 00:16:11.000000000 +0000 @@ -23,8 +23,8 @@ import errno import functools import httplib -import logging import os +import select import urllib import urlparse @@ -129,10 +129,23 @@ return self.len while self.sending: - sent = sendfile.sendfile(self.connection.sock.fileno(), - self.body.fileno(), - self.offset, - CHUNKSIZE) + try: + sent = sendfile.sendfile(self.connection.sock.fileno(), + self.body.fileno(), + self.offset, + CHUNKSIZE) + except OSError as e: + # suprisingly, sendfile may fail transiently instead of + # blocking, in which case we select on the socket in order + # to wait on its return to a writeable state before resuming + # the send loop + if e.errno in (errno.EAGAIN, errno.EBUSY): + wlist = [self.connection.sock.fileno()] + rfds, wfds, efds = select.select([], wlist, []) + if wfds: + continue + raise + self.sending = (sent != 0) self.offset += sent yield OfLength(sent) @@ -211,7 +224,8 @@ def __init__(self, host, port=None, use_ssl=False, auth_tok=None, creds=None, doc_root=None, key_file=None, - cert_file=None, ca_file=None, insecure=False): + cert_file=None, ca_file=None, insecure=False, + configure_via_auth=True): """ Creates a new client to some service. @@ -247,23 +261,31 @@ self.auth_tok = auth_tok self.creds = creds or {} self.connection = None + self.configure_via_auth = configure_via_auth # doc_root can be a nullstring, which is valid, and why we # cannot simply do doc_root or self.DEFAULT_DOC_ROOT below. self.doc_root = (doc_root if doc_root is not None else self.DEFAULT_DOC_ROOT) self.auth_plugin = self.make_auth_plugin(self.creds) - self.connect_kwargs = {} - if use_ssl: - if key_file is None: - key_file = os.environ.get('GLANCE_CLIENT_KEY_FILE') - if cert_file is None: - cert_file = os.environ.get('GLANCE_CLIENT_CERT_FILE') - if ca_file is None: - ca_file = os.environ.get('GLANCE_CLIENT_CA_FILE') + self.key_file = key_file + self.cert_file = cert_file + self.ca_file = ca_file + self.insecure = insecure + self.connect_kwargs = self.get_connect_kwargs() + + def get_connect_kwargs(self): + connect_kwargs = {} + if self.use_ssl: + if self.key_file is None: + self.key_file = os.environ.get('GLANCE_CLIENT_KEY_FILE') + if self.cert_file is None: + self.cert_file = os.environ.get('GLANCE_CLIENT_CERT_FILE') + if self.ca_file is None: + self.ca_file = os.environ.get('GLANCE_CLIENT_CA_FILE') # Check that key_file/cert_file are either both set or both unset - if cert_file is not None and key_file is None: + if self.cert_file is not None and self.key_file is None: msg = _("You have selected to use SSL in connecting, " "and you have supplied a cert, " "however you have failed to supply either a " @@ -271,7 +293,7 @@ "GLANCE_CLIENT_KEY_FILE environ variable") raise exception.ClientConnectionError(msg) - if key_file is not None and cert_file is None: + if self.key_file is not None and self.cert_file is None: msg = _("You have selected to use SSL in connecting, " "and you have supplied a key, " "however you have failed to supply either a " @@ -279,31 +301,36 @@ "GLANCE_CLIENT_CERT_FILE environ variable") raise exception.ClientConnectionError(msg) - if key_file is not None and not os.path.exists(key_file): + if (self.key_file is not None and + not os.path.exists(self.key_file)): msg = _("The key file you specified %s does not " - "exist") % key_file + "exist") % self.key_file raise exception.ClientConnectionError(msg) - self.connect_kwargs['key_file'] = key_file + connect_kwargs['key_file'] = self.key_file - if cert_file is not None and not os.path.exists(cert_file): + if (self.cert_file is not None and + not os.path.exists(self.cert_file)): msg = _("The cert file you specified %s does not " - "exist") % cert_file + "exist") % self.cert_file raise exception.ClientConnectionError(msg) - self.connect_kwargs['cert_file'] = cert_file + connect_kwargs['cert_file'] = self.cert_file - if ca_file is not None and not os.path.exists(ca_file): + if (self.ca_file is not None and + not os.path.exists(self.ca_file)): msg = _("The CA file you specified %s does not " - "exist") % ca_file + "exist") % self.ca_file raise exception.ClientConnectionError(msg) - if ca_file is None: + if self.ca_file is None: for ca in self.DEFAULT_CA_FILE_PATH.split(":"): if os.path.exists(ca): - ca_file = ca + self.ca_file = ca break - self.connect_kwargs['ca_file'] = ca_file - self.connect_kwargs['insecure'] = insecure + connect_kwargs['ca_file'] = self.ca_file + connect_kwargs['insecure'] = self.insecure + + return connect_kwargs def set_auth_token(self, auth_tok): """ @@ -334,6 +361,10 @@ self.port = parsed.port or 80 self.doc_root = parsed.path + # ensure connection kwargs are re-evaluated after the service catalog + # publicURL is parsed for potential SSL usage + self.connect_kwargs = self.get_connect_kwargs() + def make_auth_plugin(self, creds): """ Returns an instantiated authentication plugin. @@ -365,7 +396,7 @@ self.auth_tok = auth_plugin.auth_token management_url = auth_plugin.management_url - if management_url: + if management_url and self.configure_via_auth: self.configure_from_url(management_url) @handle_unauthorized @@ -385,7 +416,6 @@ self._authenticate() url = self._construct_url(action, params) - return self._do_request(method=method, url=url, body=body, headers=headers) @@ -491,6 +521,10 @@ raise TypeError('Unsupported image type: %s' % body.__class__) res = c.getresponse() + + def _retry(res): + return res.getheader('Retry-After') + status_code = self.get_status_code(res) if status_code in self.OK_RESPONSE_CODES: return res @@ -508,8 +542,13 @@ raise exception.Invalid(res.read()) elif status_code == httplib.MULTIPLE_CHOICES: raise exception.MultipleChoices(body=res.read()) + elif status_code == httplib.REQUEST_ENTITY_TOO_LARGE: + raise exception.LimitExceeded(retry=_retry(res), + body=res.read()) elif status_code == httplib.INTERNAL_SERVER_ERROR: raise Exception("Internal Server error: %s" % res.read()) + elif status_code == httplib.SERVICE_UNAVAILABLE: + raise exception.ServiceUnavailable(retry=_retry(res)) else: raise Exception("Unknown error occurred! %s" % res.read()) diff -Nru glance-2012.1~rc1~20120309.1315/glance/common/config.py glance-2012.1~rc1~20120316.1354/glance/common/config.py --- glance-2012.1~rc1~20120309.1315/glance/common/config.py 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/glance/common/config.py 2012-03-16 00:16:11.000000000 +0000 @@ -26,9 +26,9 @@ import os import sys -from glance import version from glance.common import cfg from glance.common import wsgi +from glance import version paste_deploy_group = cfg.OptGroup('paste_deploy') @@ -169,8 +169,6 @@ # Setup logging early setup_logging(conf) - logger = logging.getLogger(app_name) - app = wsgi.paste_deploy_app(conf_file, app_name, conf) # Log the options used when starting if we're in debug mode... diff -Nru glance-2012.1~rc1~20120309.1315/glance/common/context.py glance-2012.1~rc1~20120316.1354/glance/common/context.py --- glance-2012.1~rc1~20120309.1315/glance/common/context.py 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/glance/common/context.py 2012-03-16 00:16:11.000000000 +0000 @@ -19,7 +19,6 @@ from glance.common import exception from glance.common import utils from glance.common import wsgi -from glance.registry.db import api as db_api class RequestContext(object): diff -Nru glance-2012.1~rc1~20120309.1315/glance/common/crypt.py glance-2012.1~rc1~20120316.1354/glance/common/crypt.py --- glance-2012.1~rc1~20120309.1315/glance/common/crypt.py 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/glance/common/crypt.py 2012-03-16 00:16:11.000000000 +0000 @@ -21,8 +21,6 @@ """ import base64 -import string -import os from Crypto.Cipher import AES from Crypto import Random diff -Nru glance-2012.1~rc1~20120309.1315/glance/common/exception.py glance-2012.1~rc1~20120316.1354/glance/common/exception.py --- glance-2012.1~rc1~20120309.1315/glance/common/exception.py 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/glance/common/exception.py 2012-03-16 00:16:11.000000000 +0000 @@ -143,6 +143,28 @@ "request URI.\n\nThe body of response returned:\n%(body)s") +class LimitExceeded(GlanceException): + message = _("The request returned a 413 Request Entity Too Large. This " + "generally means that rate limiting or a quota threshold was " + "breached.\n\nThe response body:\n%(body)s") + + def __init__(self, *args, **kwargs): + self.retry_after = (int(kwargs['retry']) if kwargs.get('retry') + else None) + super(LimitExceeded, self).__init__(*args, **kwargs) + + +class ServiceUnavailable(GlanceException): + message = _("The request returned a 503 ServiceUnavilable. This " + "generally occurs on service overload or other transient " + "outage.") + + def __init__(self, *args, **kwargs): + self.retry_after = (int(kwargs['retry']) if kwargs.get('retry') + else None) + super(ServiceUnavailable, self).__init__(*args, **kwargs) + + class InvalidContentType(GlanceException): message = _("Invalid content type %(content_type)s") diff -Nru glance-2012.1~rc1~20120309.1315/glance/common/utils.py glance-2012.1~rc1~20120316.1354/glance/common/utils.py --- glance-2012.1~rc1~20120309.1315/glance/common/utils.py 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/glance/common/utils.py 2012-03-16 00:16:11.000000000 +0000 @@ -22,13 +22,10 @@ import datetime import errno -import inspect import logging import os import platform -import random import subprocess -import socket import sys import uuid @@ -327,9 +324,11 @@ if not height_width: try: p = subprocess.Popen(['stty', 'size'], - shell=false, + shell=False, stdout=subprocess.PIPE) - return tuple(int(x) for x in p.communicate()[0].split()) + result = p.communicate() + if p.returncode == 0: + return tuple(int(x) for x in result[0].split()) except: pass diff -Nru glance-2012.1~rc1~20120309.1315/glance/image_cache/drivers/base.py glance-2012.1~rc1~20120316.1354/glance/image_cache/drivers/base.py --- glance-2012.1~rc1~20120309.1315/glance/image_cache/drivers/base.py 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/glance/image_cache/drivers/base.py 2012-03-16 00:16:11.000000000 +0000 @@ -22,8 +22,6 @@ import logging import os.path -from contextlib import contextmanager - from glance.common import exception from glance.common import utils diff -Nru glance-2012.1~rc1~20120309.1315/glance/image_cache/drivers/sqlite.py glance-2012.1~rc1~20120316.1354/glance/image_cache/drivers/sqlite.py --- glance-2012.1~rc1~20120309.1315/glance/image_cache/drivers/sqlite.py 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/glance/image_cache/drivers/sqlite.py 2012-03-16 00:16:11.000000000 +0000 @@ -21,8 +21,6 @@ from __future__ import absolute_import from contextlib import contextmanager -import datetime -import itertools import logging import os import stat diff -Nru glance-2012.1~rc1~20120309.1315/glance/image_cache/drivers/xattr.py glance-2012.1~rc1~20120316.1354/glance/image_cache/drivers/xattr.py --- glance-2012.1~rc1~20120309.1315/glance/image_cache/drivers/xattr.py 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/glance/image_cache/drivers/xattr.py 2012-03-16 00:16:11.000000000 +0000 @@ -57,7 +57,6 @@ from contextlib import contextmanager import datetime import errno -import itertools import logging import os import stat diff -Nru glance-2012.1~rc1~20120309.1315/glance/image_cache/__init__.py glance-2012.1~rc1~20120316.1354/glance/image_cache/__init__.py --- glance-2012.1~rc1~20120309.1315/glance/image_cache/__init__.py 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/glance/image_cache/__init__.py 2012-03-16 00:16:11.000000000 +0000 @@ -20,7 +20,6 @@ """ import logging -import os from glance.common import cfg from glance.common import exception diff -Nru glance-2012.1~rc1~20120309.1315/glance/image_cache/prefetcher.py glance-2012.1~rc1~20120316.1354/glance/image_cache/prefetcher.py --- glance-2012.1~rc1~20120309.1315/glance/image_cache/prefetcher.py 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/glance/image_cache/prefetcher.py 2012-03-16 00:16:11.000000000 +0000 @@ -26,6 +26,7 @@ from glance.common import exception from glance.image_cache import ImageCache from glance import registry +from glance.registry import context import glance.store import glance.store.filesystem import glance.store.http @@ -45,10 +46,11 @@ glance.store.create_stores(conf) self.cache = ImageCache(conf) registry.configure_registry_client(conf) + registry.configure_registry_admin_creds(conf) def fetch_image_into_cache(self, image_id): - ctx = registry.get_client_context(self.conf, - is_admin=True, show_deleted=True) + ctx = context.RequestContext(is_admin=True, show_deleted=True) + try: image_meta = registry.get_image_metadata(ctx, image_id) if image_meta['status'] != 'active': diff -Nru glance-2012.1~rc1~20120309.1315/glance/image_cache/queue_image.py glance-2012.1~rc1~20120316.1354/glance/image_cache/queue_image.py --- glance-2012.1~rc1~20120309.1315/glance/image_cache/queue_image.py 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/glance/image_cache/queue_image.py 2012-03-16 00:16:11.000000000 +0000 @@ -26,6 +26,7 @@ from glance.common import exception from glance.image_cache import ImageCache from glance import registry +from glance.registry import context logger = logging.getLogger(__name__) @@ -37,10 +38,10 @@ self.conf = conf self.cache = ImageCache(conf) registry.configure_registry_client(conf) + registry.configure_registry_admin_creds(conf) def queue_image(self, image_id): - ctx = \ - registry.get_client_context(conf, is_admin=True, show_deleted=True) + ctx = context.RequestContext(is_admin=True, show_deleted=True) try: image_meta = registry.get_image_metadata(ctx, image_id) if image_meta['status'] != 'active': diff -Nru glance-2012.1~rc1~20120309.1315/glance/locale/glance.pot glance-2012.1~rc1~20120316.1354/glance/locale/glance.pot --- glance-2012.1~rc1~20120309.1315/glance/locale/glance.pot 1970-01-01 00:00:00.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/glance/locale/glance.pot 2012-03-16 00:16:11.000000000 +0000 @@ -0,0 +1,1214 @@ +# Translations template for glance. +# Copyright (C) 2012 ORGANIZATION +# This file is distributed under the same license as the glance project. +# FIRST AUTHOR , 2012. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: glance 2012.1\n" +"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" +"POT-Creation-Date: 2012-02-19 17:19-0800\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 0.9.6\n" + +#: glance/api/middleware/cache.py:50 +msgid "Initialized image cache middleware" +msgstr "" + +#: glance/api/middleware/cache.py:77 +#, python-format +msgid "Cache hit for image '%s'" +msgstr "" + +#: glance/api/middleware/cache.py:93 +#, python-format +msgid "" +"Image cache contained image file for image '%s', however the registry did" +" not contain metadata for that image!" +msgstr "" + +#: glance/api/middleware/cache.py:121 +#, python-format +msgid "Removing image %s from cache" +msgstr "" + +#: glance/api/middleware/cache_manage.py:70 +msgid "Initialized image cache management middleware" +msgstr "" + +#: glance/api/middleware/version_negotiation.py:53 +#, python-format +msgid "Processing request: %(method)s %(path)s Accept: %(accept)s" +msgstr "" + +#: glance/api/middleware/version_negotiation.py:66 +#, python-format +msgid "Matched versioned URI. Version: %d.%d" +msgstr "" + +#: glance/api/middleware/version_negotiation.py:73 +#, python-format +msgid "Unknown version in versioned URI: %d.%d. Returning version choices." +msgstr "" + +#: glance/api/middleware/version_negotiation.py:87 +#, python-format +msgid "Matched versioned media type. Version: %d.%d" +msgstr "" + +#: glance/api/middleware/version_negotiation.py:93 +#, python-format +msgid "Unknown version in accept header: %d.%d...returning version choices." +msgstr "" + +#: glance/api/middleware/version_negotiation.py:100 +#, python-format +msgid "Unknown accept header: %s...returning version choices." +msgstr "" + +#: glance/api/v1/controller.py:43 glance/api/v1/members.py:37 +#, python-format +msgid "Image with identifier %s not found" +msgstr "" + +#: glance/api/v1/controller.py:48 glance/api/v1/members.py:41 +msgid "Unauthorized image access" +msgstr "" + +#: glance/api/v1/controller.py:60 +#, python-format +msgid "Image %s is not active" +msgstr "" + +#: glance/api/v1/images.py:292 +#, python-format +msgid "An image with identifier %s already exists" +msgstr "" + +#: glance/api/v1/images.py:297 +#, python-format +msgid "Failed to reserve image. Got error: %(e)s" +msgstr "" + +#: glance/api/v1/images.py:302 +msgid "Not authorized to reserve image." +msgstr "" + +#: glance/api/v1/images.py:324 +msgid "Content-Type must be application/octet-stream" +msgstr "" + +#: glance/api/v1/images.py:334 +#, python-format +msgid "Setting image %s to status 'saving'" +msgstr "" + +#: glance/api/v1/images.py:338 +#, python-format +msgid "Uploading image data for image %(image_id)s to %(store_name)s store" +msgstr "" + +#: glance/api/v1/images.py:345 +msgid "Got request with no content-length and no x-image-meta-size header" +msgstr "" + +#: glance/api/v1/images.py:351 +#, python-format +msgid "" +"Denying attempt to upload image larger than %(max_image_size)d. Supplied " +"image size was %(image_size)d" +msgstr "" + +#: glance/api/v1/images.py:365 +#, python-format +msgid "" +"Supplied checksum (%(supplied_checksum)s) and checksum generated from " +"uploaded image (%(checksum)s) did not match. Setting image status to " +"'killed'." +msgstr "" + +#: glance/api/v1/images.py:376 +#, python-format +msgid "" +"Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " +"to %(size)d" +msgstr "" + +#: glance/api/v1/images.py:387 +#, python-format +msgid "Attempt to upload duplicate image: %s" +msgstr "" + +#: glance/api/v1/images.py:394 +#, python-format +msgid "Unauthorized upload attempt: %s" +msgstr "" + +#: glance/api/v1/images.py:402 +#, python-format +msgid "Image storage media is full: %s" +msgstr "" + +#: glance/api/v1/images.py:410 +#, python-format +msgid "Insufficient permissions on image storage media: %s" +msgstr "" + +#: glance/api/v1/images.py:428 +#, python-format +msgid "Error uploading image: (%(class_name)s): %(exc)s" +msgstr "" + +#: glance/api/v1/images.py:473 +#, python-format +msgid "Unable to kill image %(id)s: %(exc)s" +msgstr "" + +#: glance/api/v1/images.py:532 glance/api/v1/images.py:564 +#: glance/api/v1/images.py:637 +msgid "Read-only access" +msgstr "" + +#: glance/api/v1/images.py:585 +msgid "Cannot upload to an unqueued image" +msgstr "" + +#: glance/api/v1/images.py:591 +msgid "Attempted to update Location field for an image not in queued status." +msgstr "" + +#: glance/api/v1/images.py:602 glance/registry/api/v1/images.py:392 +#, python-format +msgid "Failed to update image metadata. Got error: %(e)s" +msgstr "" + +#: glance/api/v1/images.py:644 +msgid "Image is protected" +msgstr "" + +#: glance/api/v1/images.py:680 +#, python-format +msgid "Requested store %s not available on this Glance server" +msgstr "" + +#: glance/api/v1/images.py:696 +#, python-format +msgid "Default store %s not available on this Glance server\n" +msgstr "" + +#: glance/api/v1/images.py:714 +#, python-format +msgid "Incoming image size of %s was not convertible to an integer." +msgstr "" + +#: glance/api/v1/images.py:723 +#, python-format +msgid "" +"Denying attempt to upload image larger than %(max_image_size)d. Supplied " +"image size was %(incoming_image_size)d" +msgstr "" + +#: glance/api/v1/images.py:800 +#, python-format +msgid "An error occurred during image.send notification: %(err)s" +msgstr "" + +#: glance/api/v1/images.py:831 +#, python-format +msgid "" +"An error occurred reading from backend storage for image %(image_id): " +"%(err)s" +msgstr "" + +#: glance/api/v1/images.py:837 +#, python-format +msgid "" +"Backend storage for image %(image_id)s disconnected after writing only " +"%(bytes_written)d bytes" +msgstr "" + +#: glance/api/v1/images.py:841 +#, python-format +msgid "Corrupt image download for image %(image_id)s" +msgstr "" + +#: glance/api/v1/members.py:53 glance/api/v1/members.py:88 +#: glance/api/v1/members.py:124 glance/registry/api/v1/members.py:70 +#: glance/registry/api/v1/members.py:173 glance/registry/api/v1/members.py:228 +msgid "No authenticated user" +msgstr "" + +#: glance/common/auth.py:168 glance/common/auth.py:213 +#, python-format +msgid "Unexpected response: %s" +msgstr "" + +#: glance/common/auth.py:235 +#, python-format +msgid "Unknown auth strategy '%s'" +msgstr "" + +#: glance/common/client.py:267 +msgid "" +"You have selected to use SSL in connecting, and you have supplied a cert," +" however you have failed to supply either a key_file parameter or set the" +" GLANCE_CLIENT_KEY_FILE environ variable" +msgstr "" + +#: glance/common/client.py:275 +msgid "" +"You have selected to use SSL in connecting, and you have supplied a key, " +"however you have failed to supply either a cert_file parameter or set the" +" GLANCE_CLIENT_CERT_FILE environ variable" +msgstr "" + +#: glance/common/client.py:283 +#, python-format +msgid "The key file you specified %s does not exist" +msgstr "" + +#: glance/common/client.py:289 +#, python-format +msgid "The cert file you specified %s does not exist" +msgstr "" + +#: glance/common/client.py:295 +#, python-format +msgid "The CA file you specified %s does not exist" +msgstr "" + +#: glance/common/config.py:90 +msgid "Invalid syslog facility" +msgstr "" + +#: glance/common/exception.py:37 +msgid "An unknown exception occurred" +msgstr "" + +#: glance/common/exception.py:59 +msgid "Missing required argument." +msgstr "" + +#: glance/common/exception.py:63 +#, python-format +msgid "Missing required credential: %(required)s" +msgstr "" + +#: glance/common/exception.py:67 +msgid "An object with the specified identifier was not found." +msgstr "" + +#: glance/common/exception.py:71 +#, python-format +msgid "Unknown scheme '%(scheme)s' found in URI" +msgstr "" + +#: glance/common/exception.py:75 +#, python-format +msgid "The Store URI %(uri)s was malformed. Reason: %(reason)s" +msgstr "" + +#: glance/common/exception.py:79 +msgid "An object with the same identifier already exists." +msgstr "" + +#: glance/common/exception.py:83 +msgid "There is not enough disk space on the image storage media." +msgstr "" + +#: glance/common/exception.py:87 +msgid "Permission to write image storage media denied." +msgstr "" + +#: glance/common/exception.py:91 +#, python-format +msgid "" +"Failed to import requested object/class: '%(import_str)s'. Reason: " +"%(reason)s" +msgstr "" + +#: glance/common/exception.py:96 +#, python-format +msgid "Connect error/bad request to Auth service at URL %(url)s." +msgstr "" + +#: glance/common/exception.py:100 +#, python-format +msgid "Auth service at URL %(url)s not found." +msgstr "" + +#: glance/common/exception.py:104 +msgid "Authorization failed." +msgstr "" + +#: glance/common/exception.py:108 glance/common/exception.py:112 +msgid "You are not authorized to complete this action." +msgstr "" + +#: glance/common/exception.py:116 +msgid "Data supplied was not valid." +msgstr "" + +#: glance/common/exception.py:120 +#, python-format +msgid "Redirecting to %(uri)s for authorization." +msgstr "" + +#: glance/common/exception.py:124 +msgid "There was an error migrating the database." +msgstr "" + +#: glance/common/exception.py:128 +msgid "There was an error connecting to a server" +msgstr "" + +#: glance/common/exception.py:132 +msgid "There was an error configuring the client." +msgstr "" + +#: glance/common/exception.py:136 +#, python-format +msgid "" +"The request returned a 302 Multiple Choices. This generally means that " +"you have not included a version indicator in a request URI.\n" +"\n" +"The body of response returned:\n" +"%(body)s" +msgstr "" + +#: glance/common/exception.py:142 +#, python-format +msgid "Invalid content type %(content_type)s" +msgstr "" + +#: glance/common/exception.py:146 +#, python-format +msgid "Registry was not configured correctly on API server. Reason: %(reason)s" +msgstr "" + +#: glance/common/exception.py:151 +#, python-format +msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" +msgstr "" + +#: glance/common/exception.py:156 +#, python-format +msgid "" +"Driver %(driver_name)s could not be configured correctly. Reason: " +"%(reason)s" +msgstr "" + +#: glance/common/exception.py:161 +msgid "Deleting images from this store is not supported." +msgstr "" + +#: glance/common/exception.py:165 +msgid "Configuration for store failed. Adding images to this store is disabled." +msgstr "" + +#: glance/common/exception.py:170 +#, python-format +msgid "'%(strategy)s' is not an available notifier strategy." +msgstr "" + +#: glance/common/exception.py:174 +#, python-format +msgid "Maximum redirects (%(redirects)s) was exceeded." +msgstr "" + +#: glance/common/exception.py:178 +msgid "Received invalid HTTP redirect." +msgstr "" + +#: glance/common/exception.py:182 +msgid "Response from Keystone does not contain a Glance endpoint." +msgstr "" + +#: glance/common/wsgi.py:106 +msgid "" +"When running server in SSL mode, you must specify both a cert_file and " +"key_file option value in your configuration file" +msgstr "" + +#: glance/common/wsgi.py:124 +#, python-format +msgid "Could not bind to %s:%s after trying for 30 seconds" +msgstr "" + +#: glance/common/wsgi.py:155 +msgid "SIGTERM received" +msgstr "" + +#: glance/common/wsgi.py:164 +msgid "SIGHUP received" +msgstr "" + +#: glance/common/wsgi.py:180 +#, python-format +msgid "Starting %d workers" +msgstr "" + +#: glance/common/wsgi.py:191 +#, python-format +msgid "Removing dead child %s" +msgstr "" + +#: glance/common/wsgi.py:199 +msgid "Caught keyboard interrupt. Exiting." +msgstr "" + +#: glance/common/wsgi.py:203 +msgid "Exited" +msgstr "" + +#: glance/common/wsgi.py:221 +#, python-format +msgid "Child %d exiting normally" +msgstr "" + +#: glance/common/wsgi.py:224 +#, python-format +msgid "Started child %s" +msgstr "" + +#: glance/common/wsgi.py:243 +msgid "Starting single process server" +msgstr "" + +#: glance/image_cache/__init__.py:57 +#, python-format +msgid "Image cache loaded driver '%s'." +msgstr "" + +#: glance/image_cache/__init__.py:60 +#, python-format +msgid "" +"Image cache driver '%(driver_name)s' failed to load. Got error: " +"'%(import_err)s." +msgstr "" + +#: glance/image_cache/__init__.py:65 glance/image_cache/__init__.py:82 +msgid "Defaulting to SQLite driver." +msgstr "" + +#: glance/image_cache/__init__.py:79 +#, python-format +msgid "" +"Image cache driver '%(driver_module)s' failed to configure. Got error: " +"'%(config_err)s" +msgstr "" + +#: glance/image_cache/__init__.py:164 +msgid "Image cache has free space, skipping prune..." +msgstr "" + +#: glance/image_cache/__init__.py:168 +#, python-format +msgid "" +"Image cache currently %(overage)d bytes over max size. Starting prune to " +"max size of %(max_size)d " +msgstr "" + +#: glance/image_cache/__init__.py:177 +#, python-format +msgid "Pruning '%(image_id)s' to free %(size)d bytes" +msgstr "" + +#: glance/image_cache/__init__.py:185 +#, python-format +msgid "" +"Pruning finished pruning. Pruned %(total_files_pruned)d and " +"%(total_bytes_pruned)d." +msgstr "" + +#: glance/image_cache/__init__.py:220 +#, python-format +msgid "Tee'ing image '%s' into cache" +msgstr "" + +#: glance/image_cache/__init__.py:232 +#, python-format +msgid "" +"Exception encountered while tee'ing image '%s' into cache. Continuing " +"with response." +msgstr "" + +#: glance/image_cache/prefetcher.py:55 +#, python-format +msgid "Image '%s' is not active. Not caching." +msgstr "" + +#: glance/image_cache/prefetcher.py:60 glance/image_cache/queue_image.py:52 +#, python-format +msgid "No metadata found for image '%s'" +msgstr "" + +#: glance/image_cache/prefetcher.py:64 +#, python-format +msgid "Caching image '%s'" +msgstr "" + +#: glance/image_cache/prefetcher.py:72 +msgid "Nothing to prefetch." +msgstr "" + +#: glance/image_cache/prefetcher.py:76 +#, python-format +msgid "Found %d images to prefetch" +msgstr "" + +#: glance/image_cache/prefetcher.py:82 +msgid "Failed to successfully cache all images in queue." +msgstr "" + +#: glance/image_cache/prefetcher.py:86 +#, python-format +msgid "Successfully cached all %d images" +msgstr "" + +#: glance/image_cache/queue_image.py:47 +#, python-format +msgid "Image '%s' is not active. Not queueing." +msgstr "" + +#: glance/image_cache/queue_image.py:55 +#, python-format +msgid "Queueing image '%s'" +msgstr "" + +#: glance/image_cache/queue_image.py:63 +msgid "No images to queue!" +msgstr "" + +#: glance/image_cache/queue_image.py:66 +#, python-format +msgid "Received %d images to queue" +msgstr "" + +#: glance/image_cache/queue_image.py:72 +msgid "Failed to successfully queue all images in queue." +msgstr "" + +#: glance/image_cache/queue_image.py:76 +#, python-format +msgid "Successfully queued all %d images" +msgstr "" + +#: glance/image_cache/drivers/base.py:65 +#, python-format +msgid "Failed to read %s from config" +msgstr "" + +#: glance/image_cache/drivers/sqlite.py:120 +#, python-format +msgid "Failed to initialize the image cache database. Got error: %s" +msgstr "" + +#: glance/image_cache/drivers/sqlite.py:159 +#: glance/image_cache/drivers/xattr.py:143 +msgid "Gathering cached image entries." +msgstr "" + +#: glance/image_cache/drivers/sqlite.py:294 +#: glance/image_cache/drivers/xattr.py:273 +#, python-format +msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" +msgstr "" + +#: glance/image_cache/drivers/sqlite.py:318 +#: glance/image_cache/drivers/xattr.py:289 +#, python-format +msgid "" +"Fetch of cache file failed, rolling back by moving '%(incomplete_path)s' " +"to '%(invalid_path)s'" +msgstr "" + +#: glance/image_cache/drivers/sqlite.py:372 +#, python-format +msgid "Error executing SQLite call. Got error: %s" +msgstr "" + +#: glance/image_cache/drivers/sqlite.py:388 +#: glance/image_cache/drivers/xattr.py:327 +#, python-format +msgid "Not queueing image '%s'. Already cached." +msgstr "" + +#: glance/image_cache/drivers/sqlite.py:393 +#: glance/image_cache/drivers/xattr.py:332 +#, python-format +msgid "Not queueing image '%s'. Already being written to cache" +msgstr "" + +#: glance/image_cache/drivers/sqlite.py:399 +#: glance/image_cache/drivers/xattr.py:338 +#, python-format +msgid "Not queueing image '%s'. Already queued." +msgstr "" + +#: glance/image_cache/drivers/sqlite.py:460 +#: glance/image_cache/drivers/xattr.py:429 +#, python-format +msgid "Deleting image cache file '%s'" +msgstr "" + +#: glance/image_cache/drivers/sqlite.py:463 +#: glance/image_cache/drivers/xattr.py:432 +#, python-format +msgid "Cached image file '%s' doesn't exist, unable to delete" +msgstr "" + +#: glance/image_cache/drivers/xattr.py:104 +#, python-format +msgid "" +"The device housing the image cache directory %(image_cache_dir)s does not" +" support xattr. It is likely you need to edit your fstab and add the " +"user_xattr option to the appropriate line for the device housing the " +"cache directory." +msgstr "" + +#: glance/image_cache/drivers/xattr.py:281 +#, python-format +msgid "Removing image '%s' from queue after caching it." +msgstr "" + +#: glance/image_cache/drivers/xattr.py:343 +#, python-format +msgid "Queueing image '%s'." +msgstr "" + +#: glance/image_cache/drivers/xattr.py:375 +#, python-format +msgid "No grace period, reaping '%(path)s' immediately" +msgstr "" + +#: glance/image_cache/drivers/xattr.py:380 +#, python-format +msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" +msgstr "" + +#: glance/image_cache/drivers/xattr.py:385 +#, python-format +msgid "Reaped %(reaped)s %(entry_type)s cache entries" +msgstr "" + +#: glance/notifier/notify_kombu.py:88 +#, python-format +msgid "Reconnecting to AMQP server on %(hostname)s:%(port)d" +msgstr "" + +#: glance/notifier/notify_kombu.py:92 +#, python-format +msgid "Connecting to AMQP server on %(hostname)s:%(port)d" +msgstr "" + +#: glance/notifier/notify_kombu.py:121 +#, python-format +msgid "Connected to AMQP server on %(hostname)s:%(port)d" +msgstr "" + +#: glance/notifier/notify_kombu.py:150 +#, python-format +msgid "" +"Unable to connect to AMQP server on %(hostname)s:%(port)d after " +"%(max_retries)d tries: %(err_str)s" +msgstr "" + +#: glance/notifier/notify_kombu.py:162 +#, python-format +msgid "" +"AMQP server on %(hostname)s:%(port)d is unreachable: %(err_str)s. Trying " +"again in %(sleep_time)d seconds." +msgstr "" + +#: glance/notifier/notify_kombu.py:169 +#, python-format +msgid "Notification with priority %(priority)s failed; msg=%s" +msgstr "" + +#: glance/notifier/notify_kombu.py:206 +#, python-format +msgid "Unable to send notification: %s" +msgstr "" + +#: glance/notifier/notify_qpid.py:113 +#, python-format +msgid "Connected to AMQP server on %s" +msgstr "" + +#: glance/registry/__init__.py:66 +msgid "Configuration option was not valid" +msgstr "" + +#: glance/registry/__init__.py:70 +msgid "Could not find required configuration option" +msgstr "" + +#: glance/registry/__init__.py:117 +msgid "Adding image metadata..." +msgstr "" + +#: glance/registry/__init__.py:124 +#, python-format +msgid "Updating image metadata for image %s..." +msgstr "" + +#: glance/registry/__init__.py:130 +#, python-format +msgid "Deleting image metadata for image %s..." +msgstr "" + +#: glance/registry/api/v1/images.py:70 +msgid "Invalid marker. Image could not be found." +msgstr "" + +#: glance/registry/api/v1/images.py:171 +msgid "Unrecognized changes-since value" +msgstr "" + +#: glance/registry/api/v1/images.py:176 +msgid "protected must be True, or False" +msgstr "" + +#: glance/registry/api/v1/images.py:202 +msgid "limit param must be an integer" +msgstr "" + +#: glance/registry/api/v1/images.py:205 +msgid "limit param must be positive" +msgstr "" + +#: glance/registry/api/v1/images.py:214 +msgid "Invalid marker format" +msgstr "" + +#: glance/registry/api/v1/images.py:224 +#, python-format +msgid "Unsupported sort_key. Acceptable values: %s" +msgstr "" + +#: glance/registry/api/v1/images.py:233 +#, python-format +msgid "Unsupported sort_dir. Acceptable values: %s" +msgstr "" + +#: glance/registry/api/v1/images.py:259 +msgid "is_public must be None, True, or False" +msgstr "" + +#: glance/registry/api/v1/images.py:280 glance/registry/api/v1/images.py:403 +#: glance/registry/api/v1/members.py:47 glance/registry/api/v1/members.py:81 +#: glance/registry/api/v1/members.py:183 glance/registry/api/v1/members.py:238 +#, python-format +msgid "Access by %(user)s to image %(id)s denied" +msgstr "" + +#: glance/registry/api/v1/images.py:306 +#, python-format +msgid "Access by %(user)s to delete public image %(id)s denied" +msgstr "" + +#: glance/registry/api/v1/images.py:312 +#, python-format +msgid "Access by %(user)s to delete private image %(id)s denied" +msgstr "" + +#: glance/registry/api/v1/images.py:345 +msgid "Invalid image id format" +msgstr "" + +#: glance/registry/api/v1/images.py:352 +#, python-format +msgid "Image with identifier %s already exists!" +msgstr "" + +#: glance/registry/api/v1/images.py:356 +#, python-format +msgid "Failed to add image metadata. Got error: %(e)s" +msgstr "" + +#: glance/registry/api/v1/images.py:382 +#, python-format +msgid "Updating image %(id)s with metadata: %(image_data)r" +msgstr "" + +#: glance/registry/api/v1/members.py:89 glance/registry/api/v1/members.py:191 +#: glance/registry/api/v1/members.py:246 +msgid "No permission to share that image" +msgstr "" + +#: glance/registry/api/v1/members.py:97 glance/registry/api/v1/members.py:110 +#: glance/registry/api/v1/members.py:201 +#, python-format +msgid "Invalid membership association: %s" +msgstr "" + +#: glance/registry/api/v1/members.py:275 +msgid "Invalid marker. Membership could not be found." +msgstr "" + +#: glance/registry/db/api.py:83 +#, python-format +msgid "" +"Error configuring registry database with supplied sql_connection " +"'%(sql_connection)s'. Got error:\n" +"%(err)s" +msgstr "" + +#: glance/registry/db/api.py:100 +msgid "Attempted to modify image user did not own." +msgstr "" + +#: glance/registry/db/api.py:101 +msgid "You do not own this image" +msgstr "" + +#: glance/registry/db/migration.py:47 +#, python-format +msgid "database '%(sql_connection)s' is not under migration control" +msgstr "" + +#: glance/registry/db/migration.py:64 +#, python-format +msgid "Upgrading %(sql_connection)s to version %(version_str)s" +msgstr "" + +#: glance/registry/db/migration.py:80 +#, python-format +msgid "Downgrading %(sql_connection)s to version %(version)s" +msgstr "" + +#: glance/registry/db/migration.py:95 +#, python-format +msgid "database '%(sql_connection)s' is already under migration control" +msgstr "" + +#: glance/registry/db/migrate_repo/schema.py:96 +#, python-format +msgid "creating table %(table)s" +msgstr "" + +#: glance/registry/db/migrate_repo/schema.py:102 +#, python-format +msgid "dropping table %(table)s" +msgstr "" + +#: glance/store/__init__.py:196 +#, python-format +msgid "Failed to delete image at %s from store (%s)" +msgstr "" + +#: glance/store/__init__.py:209 +#, python-format +msgid "Image id %(image_id)s already queued for delete" +msgstr "" + +#: glance/store/base.py:44 +msgid "Failed to configure store correctly. Disabling add method." +msgstr "" + +#: glance/store/filesystem.py:59 +msgid "No path specified" +msgstr "" + +#: glance/store/filesystem.py:111 +#, python-format +msgid "Could not find %s in configuration options." +msgstr "" + +#: glance/store/filesystem.py:118 +#, python-format +msgid "Directory to write image files does not exist (%s). Creating." +msgstr "" + +#: glance/store/filesystem.py:124 +#, python-format +msgid "Unable to create datadir: %s" +msgstr "" + +#: glance/store/filesystem.py:142 +#, python-format +msgid "Image file %s not found" +msgstr "" + +#: glance/store/filesystem.py:144 +#, python-format +msgid "Found image at %s. Returning in ChunkedFile." +msgstr "" + +#: glance/store/filesystem.py:163 +#, python-format +msgid "Deleting image at %(fn)s" +msgstr "" + +#: glance/store/filesystem.py:166 +#, python-format +msgid "You cannot delete file %s" +msgstr "" + +#: glance/store/filesystem.py:169 +#, python-format +msgid "Image file %s does not exist" +msgstr "" + +#: glance/store/filesystem.py:194 +#, python-format +msgid "Image file %s already exists!" +msgstr "" + +#: glance/store/filesystem.py:218 +#, python-format +msgid "" +"Wrote %(bytes_written)d bytes to %(filepath)s with checksum " +"%(checksum_hex)s" +msgstr "" + +#: glance/store/http.py:76 +#, python-format +msgid "Credentials '%s' not well-formatted." +msgstr "" + +#: glance/store/http.py:82 +msgid "No address specified in HTTP URL" +msgstr "" + +#: glance/store/location.py:123 +#, python-format +msgid "Unable to find StoreLocation class in store %s" +msgstr "" + +#: glance/store/rbd.py:63 +msgid "URI must start with rbd://" +msgstr "" + +#: glance/store/rbd.py:96 glance/store/rbd.py:202 +#, python-format +msgid "RBD image %s does not exist" +msgstr "" + +#: glance/store/rbd.py:128 +#, python-format +msgid "Error in store configuration: %s" +msgstr "" + +#: glance/store/rbd.py:172 +#, python-format +msgid "RBD image %s already exists" +msgstr "" + +#: glance/store/s3.py:90 +msgid "" +"URI cannot contain more than one occurrence of a scheme.If you have " +"specified a URI like " +"s3://accesskey:secretkey@https://s3.amazonaws.com/bucket/key-id, you need" +" to change it to use the s3+https:// scheme, like so: " +"s3+https://accesskey:secretkey@s3.amazonaws.com/bucket/key-id" +msgstr "" + +#: glance/store/s3.py:125 +#, python-format +msgid "Badly formed S3 credentials %s" +msgstr "" + +#: glance/store/s3.py:137 +msgid "Badly formed S3 URI. Missing s3 service URL." +msgstr "" + +#: glance/store/s3.py:140 +msgid "Badly formed S3 URI" +msgstr "" + +#: glance/store/s3.py:233 glance/store/swift.py:312 +#, python-format +msgid "Could not find %(param)s in configuration options." +msgstr "" + +#: glance/store/s3.py:281 +#, python-format +msgid "" +"Retrieved image object from S3 using (s3_host=%(s3_host)s, " +"access_key=%(accesskey)s, bucket=%(bucket)s, key=%(obj_name)s)" +msgstr "" + +#: glance/store/s3.py:333 +#, python-format +msgid "S3 already has an image at location %s" +msgstr "" + +#: glance/store/s3.py:336 +#, python-format +msgid "" +"Adding image object to S3 using (s3_host=%(s3_host)s, " +"access_key=%(access_key)s, bucket=%(bucket)s, key=%(obj_name)s)" +msgstr "" + +#: glance/store/s3.py:357 +#, python-format +msgid "Writing request body file to temporary file for %s" +msgstr "" + +#: glance/store/s3.py:371 +#, python-format +msgid "Uploading temporary file to S3 for %s" +msgstr "" + +#: glance/store/s3.py:379 +#, python-format +msgid "" +"Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " +"%(checksum_hex)s" +msgstr "" + +#: glance/store/s3.py:404 +#, python-format +msgid "" +"Deleting image object from S3 using (s3_host=%(s3_host)s, " +"access_key=%(accesskey)s, bucket=%(bucket)s, key=%(obj_name)s)" +msgstr "" + +#: glance/store/s3.py:425 +#, python-format +msgid "Could not find bucket with ID %(bucket_id)s" +msgstr "" + +#: glance/store/s3.py:473 +#, python-format +msgid "Could not find key %(obj)s in bucket %(bucket)s" +msgstr "" + +#: glance/store/scrubber.py:42 +#, python-format +msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" +msgstr "" + +#: glance/store/scrubber.py:55 +msgid "Daemon Shutdown on KeyboardInterrupt" +msgstr "" + +#: glance/store/scrubber.py:59 +msgid "Runing application" +msgstr "" + +#: glance/store/scrubber.py:62 +#, python-format +msgid "Next run scheduled in %s seconds" +msgstr "" + +#: glance/store/scrubber.py:83 +#, python-format +msgid "Initializing scrubber with conf: %s" +msgstr "" + +#: glance/store/scrubber.py:98 +#, python-format +msgid "%s does not exist" +msgstr "" + +#: glance/store/scrubber.py:120 glance/store/scrubber.py:175 +#, python-format +msgid "Deleting %s images" +msgstr "" + +#: glance/store/scrubber.py:129 +#, python-format +msgid "Deleting %(uri)s" +msgstr "" + +#: glance/store/scrubber.py:132 +#, python-format +msgid "Failed to delete image from store (%(uri)s)." +msgstr "" + +#: glance/store/scrubber.py:151 +#, python-format +msgid "Getting images deleted before %s" +msgstr "" + +#: glance/store/swift.py:105 +msgid "" +"URI cannot contain more than one occurrence of a scheme.If you have " +"specified a URI like " +"swift://user:pass@http://authurl.com/v1/container/obj, you need to change" +" it to use the swift+http:// scheme, like so: " +"swift+http://user:pass@authurl.com/v1/container/obj" +msgstr "" + +#: glance/store/swift.py:142 +#, python-format +msgid "Badly formed credentials '%(creds)s' in Swift URI" +msgstr "" + +#: glance/store/swift.py:163 +msgid "Badly formed Swift URI" +msgstr "" + +#: glance/store/swift.py:229 +#, python-format +msgid "Error in configuration conf: %s" +msgstr "" + +#: glance/store/swift.py:264 glance/store/swift.py:506 +#, python-format +msgid "Swift could not find image at uri %(uri)s" +msgstr "" + +#: glance/store/swift.py:303 +#, python-format +msgid "" +"Creating Swift connection with (auth_address=%(auth_url)s, user=%(user)s," +" snet=%(snet)s)" +msgstr "" + +#: glance/store/swift.py:367 +#, python-format +msgid "Adding image object '%(obj_name)s' to Swift" +msgstr "" + +#: glance/store/swift.py:387 +msgid "Cannot determine image size. Adding as a segmented object to Swift." +msgstr "" + +#: glance/store/swift.py:411 +#, python-format +msgid "" +"Wrote chunk %(chunk_id)d/%(total_chunks)s of length %(bytes_read)d to " +"Swift returning MD5 of content: %(chunk_etag)s" +msgstr "" + +#: glance/store/swift.py:420 +msgid "Deleting final zero-length chunk" +msgstr "" + +#: glance/store/swift.py:456 +#, python-format +msgid "Swift already has an image at location %s" +msgstr "" + +#: glance/store/swift.py:458 +#, python-format +msgid "" +"Failed to add object to Swift.\n" +"Got error from Swift: %(e)s" +msgstr "" + +#: glance/store/swift.py:546 +#, python-format +msgid "" +"Failed to add container to Swift.\n" +"Got error from Swift: %(e)s" +msgstr "" + +#: glance/store/swift.py:550 +#, python-format +msgid "" +"The container %(container)s does not exist in Swift. Please set the " +"swift_store_create_container_on_put optionto add container to Swift " +"automatically." +msgstr "" + diff -Nru glance-2012.1~rc1~20120309.1315/glance/notifier/__init__.py glance-2012.1~rc1~20120316.1354/glance/notifier/__init__.py --- glance-2012.1~rc1~20120309.1315/glance/notifier/__init__.py 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/glance/notifier/__init__.py 2012-03-16 00:16:11.000000000 +0000 @@ -17,8 +17,8 @@ import datetime -import uuid import socket +import uuid from glance.common import cfg from glance.common import exception @@ -46,7 +46,7 @@ strategy = conf.notifier_strategy try: self.strategy = utils.import_class(_STRATEGIES[strategy])(conf) - except KeyError, ImportError: + except (KeyError, ImportError): raise exception.InvalidNotifierStrategy(strategy=strategy) @staticmethod diff -Nru glance-2012.1~rc1~20120309.1315/glance/registry/api/v1/__init__.py glance-2012.1~rc1~20120316.1354/glance/registry/api/v1/__init__.py --- glance-2012.1~rc1~20120309.1315/glance/registry/api/v1/__init__.py 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/glance/registry/api/v1/__init__.py 2012-03-16 00:16:11.000000000 +0000 @@ -17,9 +17,9 @@ import routes +from glance.common import wsgi from glance.registry.api.v1 import images from glance.registry.api.v1 import members -from glance.common import wsgi class API(wsgi.Router): diff -Nru glance-2012.1~rc1~20120309.1315/glance/registry/client.py glance-2012.1~rc1~20120316.1354/glance/registry/client.py --- glance-2012.1~rc1~20120309.1315/glance/registry/client.py 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/glance/registry/client.py 2012-03-16 00:16:11.000000000 +0000 @@ -21,7 +21,6 @@ """ import json -import urllib from glance.common.client import BaseClient from glance.common import crypt @@ -40,7 +39,11 @@ :param metadata_encryption_key: Key used to encrypt 'location' metadata """ self.metadata_encryption_key = metadata_encryption_key - BaseClient.__init__(self, host, port, **kwargs) + # NOTE (dprince): by default base client overwrites host and port + # settings when using keystone. configure_via_auth=False disables + # this behaviour to ensure we still send requests to the Registry API + BaseClient.__init__(self, host, port, configure_via_auth=False, + **kwargs) def decrypt_metadata(self, image_metadata): if (self.metadata_encryption_key is not None diff -Nru glance-2012.1~rc1~20120309.1315/glance/registry/db/api.py glance-2012.1~rc1~20120316.1354/glance/registry/db/api.py --- glance-2012.1~rc1~20120309.1315/glance/registry/db/api.py 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/glance/registry/db/api.py 2012-03-16 00:16:11.000000000 +0000 @@ -26,7 +26,6 @@ from sqlalchemy import asc, create_engine, desc from sqlalchemy.exc import IntegrityError -from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import exc from sqlalchemy.orm import joinedload from sqlalchemy.orm import sessionmaker diff -Nru glance-2012.1~rc1~20120309.1315/glance/registry/db/migrate_repo/schema.py glance-2012.1~rc1~20120316.1354/glance/registry/db/migrate_repo/schema.py --- glance-2012.1~rc1~20120309.1315/glance/registry/db/migrate_repo/schema.py 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/glance/registry/db/migrate_repo/schema.py 2012-03-16 00:16:11.000000000 +0000 @@ -22,7 +22,6 @@ import logging import sqlalchemy.types -from sqlalchemy.schema import MetaData logger = logging.getLogger('glance.registry.db.migrate_repo.schema') diff -Nru glance-2012.1~rc1~20120309.1315/glance/registry/db/models.py glance-2012.1~rc1~20120316.1354/glance/registry/db/models.py --- glance-2012.1~rc1~20120309.1315/glance/registry/db/models.py 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/glance/registry/db/models.py 2012-03-16 00:16:11.000000000 +0000 @@ -20,17 +20,15 @@ SQLAlchemy models for glance data """ -import sys import datetime -from sqlalchemy.orm import relationship, backref, exc, object_mapper, validates +from sqlalchemy.orm import relationship, backref, object_mapper from sqlalchemy import Column, Integer, String, BigInteger from sqlalchemy import ForeignKey, DateTime, Boolean, Text from sqlalchemy import UniqueConstraint from sqlalchemy.ext.declarative import declarative_base import glance.registry.db.api -from glance.common import exception from glance.common import utils BASE = declarative_base() diff -Nru glance-2012.1~rc1~20120309.1315/glance/registry/__init__.py glance-2012.1~rc1~20120316.1354/glance/registry/__init__.py --- glance-2012.1~rc1~20120309.1315/glance/registry/__init__.py 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/glance/registry/__init__.py 2012-03-16 00:16:11.000000000 +0000 @@ -20,6 +20,7 @@ """ import logging +import os from glance.common import cfg from glance.common import exception @@ -27,6 +28,7 @@ logger = logging.getLogger('glance.registry') +_CLIENT_CREDS = None _CLIENT_HOST = None _CLIENT_PORT = None _CLIENT_KWARGS = {} @@ -45,7 +47,14 @@ cfg.StrOpt('registry_client_ca_file'), cfg.StrOpt('metadata_encryption_key'), ] -admin_token_opt = cfg.StrOpt('admin_token') +registry_client_ctx_opts = [ + cfg.StrOpt('admin_user'), + cfg.StrOpt('admin_password'), + cfg.StrOpt('admin_tenant_name'), + cfg.StrOpt('auth_url'), + cfg.StrOpt('auth_strategy', default='noauth'), + cfg.StrOpt('auth_region'), + ] def get_registry_addr(conf): @@ -84,16 +93,33 @@ } -def get_client_context(conf, **kwargs): - conf.register_opt(admin_token_opt) - from glance.common import context - return context.RequestContext(auth_tok=conf.admin_token, **kwargs) +def configure_registry_admin_creds(conf): + global _CLIENT_CREDS + conf.register_opts(registry_client_ctx_opts) + + if conf.auth_url or os.getenv('OS_AUTH_URL'): + strategy = 'keystone' + else: + strategy = conf.auth_strategy + + _CLIENT_CREDS = { + 'user': conf.admin_user, + 'password': conf.admin_password, + 'username': conf.admin_user, + 'tenant': conf.admin_tenant_name, + 'auth_url': conf.auth_url, + 'strategy': strategy, + 'region': conf.auth_region, + } def get_registry_client(cxt): - global _CLIENT_KWARGS, _CLIENT_HOST, _CLIENT_PORT, _METADATA_ENCRYPTION_KEY + global _CLIENT_CREDS, _CLIENT_KWARGS, _CLIENT_HOST, _CLIENT_PORT + global _METADATA_ENCRYPTION_KEY kwargs = _CLIENT_KWARGS.copy() kwargs['auth_tok'] = cxt.auth_tok + if _CLIENT_CREDS: + kwargs['creds'] = _CLIENT_CREDS return client.RegistryClient(_CLIENT_HOST, _CLIENT_PORT, _METADATA_ENCRYPTION_KEY, **kwargs) diff -Nru glance-2012.1~rc1~20120309.1315/glance/store/__init__.py glance-2012.1~rc1~20120316.1354/glance/store/__init__.py --- glance-2012.1~rc1~20120309.1315/glance/store/__init__.py 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/glance/store/__init__.py 2012-03-16 00:16:11.000000000 +0000 @@ -16,16 +16,14 @@ # under the License. import logging -import optparse import os import sys import time -import urlparse -from glance import registry from glance.common import cfg from glance.common import exception from glance.common import utils +from glance import registry from glance.store import location logger = logging.getLogger('glance.store') diff -Nru glance-2012.1~rc1~20120309.1315/glance/store/scrubber.py glance-2012.1~rc1~20120316.1354/glance/store/scrubber.py --- glance-2012.1~rc1~20120309.1315/glance/store/scrubber.py 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/glance/store/scrubber.py 2012-03-16 00:16:11.000000000 +0000 @@ -29,8 +29,6 @@ from glance import store from glance.common import cfg from glance.common import utils -from glance.common import exception -from glance.registry import context from glance.registry import client @@ -121,7 +119,7 @@ pool.starmap(self._delete, delete_work) if self.cleanup: - self._cleanup() + self._cleanup(pool) def _delete(self, id, uri, now): file_path = os.path.join(self.datadir, str(id)) @@ -136,7 +134,7 @@ self.registry.update_image(id, {'status': 'deleted'}) utils.safe_remove(file_path) - def _cleanup(self): + def _cleanup(self, pool): now = time.time() cleanup_file = os.path.join(self.datadir, self.CLEANUP_FILE) if not os.path.exists(cleanup_file): diff -Nru glance-2012.1~rc1~20120309.1315/glance/store/swift.py glance-2012.1~rc1~20120316.1354/glance/store/swift.py --- glance-2012.1~rc1~20120309.1315/glance/store/swift.py 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/glance/store/swift.py 2012-03-16 00:16:11.000000000 +0000 @@ -23,7 +23,6 @@ import httplib import logging import math -import tempfile import urlparse from glance.common import cfg @@ -266,13 +265,6 @@ else: raise - #if expected_size: - # obj_size = int(resp_headers['content-length']) - # if obj_size != expected_size: - # raise glance.store.BackendException( - # "Expected %s byte file, Swift has %s bytes" % - # (expected_size, obj_size)) - class ResponseIndexable(glance.store.Indexable): def another(self): try: @@ -448,8 +440,8 @@ # of each chunk...so we ignore this result in favour of # the MD5 of the entire image file contents, so that # users can verify the image file contents accordingly - _ignored = swift_conn.put_object(self.container, obj_name, - None, headers=headers) + swift_conn.put_object(self.container, obj_name, + None, headers=headers) obj_etag = checksum.hexdigest() # NOTE: We return the user and key here! Have to because @@ -550,7 +542,7 @@ if conf.swift_store_create_container_on_put: try: swift_conn.put_container(container) - except ClientException, e: + except swift_client.ClientException, e: msg = _("Failed to add container to Swift.\n" "Got error from Swift: %(e)s") % locals() raise glance.store.BackendException(msg) diff -Nru glance-2012.1~rc1~20120309.1315/glance/tests/functional/store_utils.py glance-2012.1~rc1~20120316.1354/glance/tests/functional/store_utils.py --- glance-2012.1~rc1~20120309.1315/glance/tests/functional/store_utils.py 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/glance/tests/functional/store_utils.py 2012-03-16 00:16:11.000000000 +0000 @@ -173,7 +173,9 @@ def get_swift_uri(test, image_id): - uri = ('swift+http://%(swift_store_user)s:%(swift_store_key)s' % + # Apparently we must use HTTPS with Cloud Files now, otherwise + # we will get a 301 Moved.... :( + uri = ('swift+https://%(swift_store_user)s:%(swift_store_key)s' % test.__dict__) uri += ('@%(swift_store_auth_address)s/%(swift_store_container)s/' % test.__dict__) diff -Nru glance-2012.1~rc1~20120309.1315/glance/tests/functional/test_bin_glance.py glance-2012.1~rc1~20120316.1354/glance/tests/functional/test_bin_glance.py --- glance-2012.1~rc1~20120309.1315/glance/tests/functional/test_bin_glance.py 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/glance/tests/functional/test_bin_glance.py 2012-03-16 00:16:11.000000000 +0000 @@ -145,6 +145,47 @@ self.assertEqual('0', size, "Expected image to be 0 bytes in size, " "but got %s. " % size) + def test_add_no_name(self): + self.cleanup() + self.start_servers(**self.__dict__.copy()) + + api_port = self.api_port + registry_port = self.registry_port + + # 0. Verify no public images + cmd = "bin/glance --port=%d index" % api_port + + exitcode, out, err = execute(cmd) + + self.assertEqual(0, exitcode) + self.assertEqual('', out.strip()) + + # 1. Add public image + # Can't use minimal_add_command since that uses + # name... + cmd = ("bin/glance --port=%d add is_public=True" + " disk_format=raw container_format=ovf" + " %s" % (api_port, 'location=http://example.com')) + exitcode, out, err = execute(cmd) + + self.assertEqual(0, exitcode) + self.assertTrue(out.strip().startswith('Added new image with ID:')) + + # 2. Verify image added as public image + cmd = "bin/glance --port=%d index" % api_port + + exitcode, out, err = execute(cmd) + + self.assertEqual(0, exitcode) + lines = out.split("\n")[2:-1] + self.assertEqual(1, len(lines)) + + line = lines[0] + + image_id, name, disk_format, container_format, size = \ + [c.strip() for c in line.split()] + self.assertEqual('None', name) + @requires(setup_http, teardown_http) def test_add_copying_from(self): self.cleanup() diff -Nru glance-2012.1~rc1~20120309.1315/glance/tests/functional/test_client_exceptions.py glance-2012.1~rc1~20120316.1354/glance/tests/functional/test_client_exceptions.py --- glance-2012.1~rc1~20120309.1315/glance/tests/functional/test_client_exceptions.py 1970-01-01 00:00:00.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/glance/tests/functional/test_client_exceptions.py 2012-03-16 00:16:11.000000000 +0000 @@ -0,0 +1,101 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2011 OpenStack, LLC +# Copyright 2012 Red Hat, Inc +# 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. + +"""Functional test asserting strongly typed exceptions from glance client""" + +import eventlet.patcher +import webob.dec +import webob.exc + +from glance.common import client +from glance.common import exception +from glance.common import wsgi +from glance.tests import functional +from glance.tests import utils + + +eventlet.patcher.monkey_patch(socket=True) + + +class ExceptionTestApp(object): + """ + Test WSGI application which can respond with multiple kinds of HTTP + status codes + """ + + @webob.dec.wsgify + def __call__(self, request): + path = request.path_qs + + if path == "/rate-limit": + request.response = webob.exc.HTTPRequestEntityTooLarge() + + elif path == "/rate-limit-retry": + request.response.retry_after = 10 + request.response.status = 413 + + if path == "/service-unavailable": + request.response = webob.exc.HTTPServiceUnavailable() + + elif path == "/service-unavailable-retry": + request.response.retry_after = 10 + request.response.status = 503 + + +class TestClientExceptions(functional.FunctionalTest): + + def setUp(self): + super(TestClientExceptions, self).setUp() + self.port = utils.get_unused_port() + server = wsgi.Server() + conf = utils.TestConfigOpts({'bind_host': '127.0.0.1'}) + server.start(ExceptionTestApp(), conf, self.port) + self.client = client.BaseClient("127.0.0.1", self.port) + + def _do_test_exception(self, path, exc_type): + try: + self.client.do_request("GET", path) + self.fail('expected %s' % exc_type) + except exc_type as e: + self.assertEquals('retry' in path, e.retry_after == 10) + + def test_rate_limited(self): + """ + Test rate limited response + """ + self._do_test_exception('/rate-limit', exception.LimitExceeded) + + def test_rate_limited_retry(self): + """ + Test rate limited response with retry + """ + self._do_test_exception('/rate-limit-retry', exception.LimitExceeded) + + def test_service_unavailable(self): + """ + Test service unavailable response + """ + self._do_test_exception('/service-unavailable', + exception.ServiceUnavailable) + + def test_service_unavailable_retry(self): + """ + Test service unavailable response with retry + """ + self._do_test_exception('/service-unavailable-retry', + exception.ServiceUnavailable) diff -Nru glance-2012.1~rc1~20120309.1315/glance/tests/functional/test_copy_to_file.py glance-2012.1~rc1~20120316.1354/glance/tests/functional/test_copy_to_file.py --- glance-2012.1~rc1~20120309.1315/glance/tests/functional/test_copy_to_file.py 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/glance/tests/functional/test_copy_to_file.py 2012-03-16 00:16:11.000000000 +0000 @@ -111,6 +111,7 @@ data = json.loads(content) copy_image_id = data['image']['id'] + self.assertNotEqual(copy_image_id, original_image_id) # GET image and make sure image content is as expected path = "http://%s:%d/v1/images/%s" % ("0.0.0.0", self.api_port, diff -Nru glance-2012.1~rc1~20120309.1315/glance/tests/functional/test_private_images.py glance-2012.1~rc1~20120316.1354/glance/tests/functional/test_private_images.py --- glance-2012.1~rc1~20120309.1315/glance/tests/functional/test_private_images.py 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/glance/tests/functional/test_private_images.py 2012-03-16 00:16:11.000000000 +0000 @@ -781,7 +781,8 @@ # Test that we can update is_public through the CLI args = (self.api_port, keystone_utils.pattieblack_token, image_id) - cmd = "bin/glance --port=%d --auth_token=%s update %s is_public=True" + cmd = ("bin/glance --port=%d --os_auth_token=%s update %s " + "is_public=True") exitcode, out, err = execute(cmd % args) self.assertEqual(0, exitcode) @@ -801,7 +802,7 @@ # Test that admin can change the owner args = (self.api_port, keystone_utils.admin_token, image_id) - cmd = "bin/glance --port=%d --auth_token=%s update %s owner=froggy" + cmd = "bin/glance --port=%d --os_auth_token=%s update %s owner=froggy" exitcode, out, err = execute(cmd % args) self.assertEqual(0, exitcode) @@ -820,7 +821,7 @@ # Test that admin can remove the owner args = (self.api_port, keystone_utils.admin_token, image_id) - cmd = "bin/glance --port=%d --auth_token=%s update %s owner=" + cmd = "bin/glance --port=%d --os_auth_token=%s update %s owner=" exitcode, out, err = execute(cmd % args) self.assertEqual(0, exitcode) @@ -851,7 +852,7 @@ """ Test the CLI with the noauth strategy defaulted to. """ - suffix = '--auth_token=%s' % keystone_utils.pattieblack_token + suffix = '--os_auth_token=%s' % keystone_utils.pattieblack_token cmd = minimal_add_command(self.api_port, 'MyImage', suffix, False) self._do_test_glance_cli(cmd) @@ -863,8 +864,8 @@ """ substitutions = (self.auth_port, 'keystone', 'pattieblack', 'secrete') - suffix = ("--auth_url=http://localhost:%d/v1.0 " - "--auth_strategy=%s --username=%s --password=%s " + suffix = ("--os_auth_url=http://localhost:%d/v1.0 " + "--os_auth_strategy=%s --os_username=%s --os_password=%s " % substitutions) cmd = minimal_add_command(self.api_port, 'MyImage', suffix, False) self._do_test_glance_cli(cmd) @@ -890,13 +891,13 @@ auth url missing. """ substitutions = (self.api_port, 'keystone', 'pattieblack', 'secrete') - cmd = ("bin/glance --port=%d --auth_strategy=%s " - "--username=%s --password=%s index" % substitutions) + cmd = ("bin/glance --port=%d --os_auth_strategy=%s " + "--os_username=%s --os_password=%s index" % substitutions) exitcode, out, err = execute(cmd, raise_error=False) self.assertEqual(1, exitcode) - msg = ("--auth_url option or OS_AUTH_URL environment variable " + msg = ("--os_auth_url option or OS_AUTH_URL environment variable " "required when keystone authentication strategy is enabled") self.assertTrue(msg in err, 'expected "%s" in "%s"' % (msg, err)) diff -Nru glance-2012.1~rc1~20120309.1315/glance/tests/functional/test_s3.py glance-2012.1~rc1~20120316.1354/glance/tests/functional/test_s3.py --- glance-2012.1~rc1~20120309.1315/glance/tests/functional/test_s3.py 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/glance/tests/functional/test_s3.py 2012-03-16 00:16:11.000000000 +0000 @@ -209,6 +209,7 @@ data = json.loads(content) copy_image_id = data['image']['id'] + self.assertNotEqual(copy_image_id, original_image_id) # GET image and make sure image content is as expected path = "http://%s:%d/v1/images/%s" % ("0.0.0.0", self.api_port, diff -Nru glance-2012.1~rc1~20120309.1315/glance/tests/functional/test_shared_images.py glance-2012.1~rc1~20120316.1354/glance/tests/functional/test_shared_images.py --- glance-2012.1~rc1~20120309.1315/glance/tests/functional/test_shared_images.py 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/glance/tests/functional/test_shared_images.py 2012-03-16 00:16:11.000000000 +0000 @@ -417,7 +417,7 @@ # Test that we can add froggy as a shared image member args = (self.api_port, keystone_utils.pattieblack_token, image_id, keystone_utils.froggy_id) - cmd = "bin/glance --port=%d --auth_token=%s member-add %s %s" % args + cmd = "bin/glance --port=%d --os_auth_token=%s member-add %s %s" % args exitcode, out, err = execute(cmd) self.assertEqual(0, exitcode) @@ -435,7 +435,7 @@ self.assertEqual(data['members'][0]['can_share'], False) # Test that we can replace a shared image membership list - cmd = ("bin/glance --port=%d --auth_token=%s members-replace %s %s " + cmd = ("bin/glance --port=%d --os_auth_token=%s members-replace %s %s " "--can-share" % (self.api_port, keystone_utils.pattieblack_token, image_id, keystone_utils.bacon_id)) @@ -456,7 +456,7 @@ self.assertEqual(data['members'][0]['can_share'], True) # Test that we can delete an image membership - cmd = ("bin/glance --port=%d --auth_token=%s member-delete %s %s" % + cmd = ("bin/glance --port=%d --os_auth_token=%s member-delete %s %s" % (self.api_port, keystone_utils.pattieblack_token, image_id, keystone_utils.bacon_id)) exitcode, out, err = execute(cmd) @@ -490,23 +490,23 @@ image2_id = data['image']['id'] # Share images with froggy and bacon - cmd = ("bin/glance --port=%d --auth_token=%s member-add %s %s" % + cmd = ("bin/glance --port=%d --os_auth_token=%s member-add %s %s" % (self.api_port, keystone_utils.pattieblack_token, image1_id, keystone_utils.froggy_id)) exitcode, out, err = execute(cmd) self.assertEqual(0, exitcode) - cmd = ("bin/glance --port=%d --auth_token=%s member-add %s %s" % + cmd = ("bin/glance --port=%d --os_auth_token=%s member-add %s %s" % (self.api_port, keystone_utils.pattieblack_token, image1_id, keystone_utils.bacon_id)) exitcode, out, err = execute(cmd) self.assertEqual(0, exitcode) - cmd = ("bin/glance --port=%d --auth_token=%s member-add %s %s " + cmd = ("bin/glance --port=%d --os_auth_token=%s member-add %s %s " "--can-share" % (self.api_port, keystone_utils.pattieblack_token, image2_id, keystone_utils.froggy_id)) exitcode, out, err = execute(cmd) self.assertEqual(0, exitcode) - cmd = ("bin/glance --port=%d --auth_token=%s member-add %s %s " + cmd = ("bin/glance --port=%d --os_auth_token=%s member-add %s %s " "--can-share" % (self.api_port, keystone_utils.pattieblack_token, image2_id, keystone_utils.bacon_id)) @@ -514,7 +514,7 @@ self.assertEqual(0, exitcode) # Get the list of image members - cmd = ("bin/glance --port=%d --auth_token=%s image-members %s" % + cmd = ("bin/glance --port=%d --os_auth_token=%s image-members %s" % (self.api_port, keystone_utils.pattieblack_token, image1_id)) exitcode, out, err = execute(cmd) self.assertEqual(0, exitcode) @@ -524,7 +524,7 @@ self.assertTrue(keystone_utils.bacon_id in result) # Try again for can_share - cmd = ("bin/glance --port=%d --auth_token=%s image-members %s" % + cmd = ("bin/glance --port=%d --os_auth_token=%s image-members %s" % (self.api_port, keystone_utils.pattieblack_token, image2_id)) exitcode, out, err = execute(cmd) self.assertEqual(0, exitcode) @@ -535,7 +535,7 @@ self.assertTrue(keystone_utils.bacon_id + ' *' in result[:-2]) # Get the list of member images - cmd = ("bin/glance --port=%d --auth_token=%s member-images %s" % + cmd = ("bin/glance --port=%d --os_auth_token=%s member-images %s" % (self.api_port, keystone_utils.pattieblack_token, keystone_utils.froggy_id)) exitcode, out, err = execute(cmd) diff -Nru glance-2012.1~rc1~20120309.1315/glance/tests/functional/test_swift.py glance-2012.1~rc1~20120316.1354/glance/tests/functional/test_swift.py --- glance-2012.1~rc1~20120309.1315/glance/tests/functional/test_swift.py 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/glance/tests/functional/test_swift.py 2012-03-16 00:16:11.000000000 +0000 @@ -480,6 +480,7 @@ data = json.loads(content) copy_image_id = data['image']['id'] + self.assertNotEqual(copy_image_id, original_image_id) # GET image and make sure image content is as expected path = "http://%s:%d/v1/images/%s" % ("0.0.0.0", self.api_port, diff -Nru glance-2012.1~rc1~20120309.1315/glance/tests/unit/test_api.py glance-2012.1~rc1~20120316.1354/glance/tests/unit/test_api.py --- glance-2012.1~rc1~20120309.1315/glance/tests/unit/test_api.py 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/glance/tests/unit/test_api.py 2012-03-16 00:16:11.000000000 +0000 @@ -2194,7 +2194,7 @@ req.headers['Content-Type'] = 'application/octet-stream' req.body = "chunk00000remainder" res = req.get_response(self.api) - self.assertEquals(res.status_int, 401) + self.assertEquals(res.status_int, 403) def _do_test_post_image_content_missing_format(self, missing): """Tests creation of an image with missing format""" @@ -2563,14 +2563,14 @@ self.set_policy_rules(rules) req = webob.Request.blank('/images/detail') res = req.get_response(self.api) - self.assertEquals(res.status_int, 401) + self.assertEquals(res.status_int, 403) def test_get_images_unauthorized(self): rules = {"get_images": [["false:false"]]} self.set_policy_rules(rules) req = webob.Request.blank('/images/detail') res = req.get_response(self.api) - self.assertEquals(res.status_int, 401) + self.assertEquals(res.status_int, 403) def test_store_location_not_revealed(self): """ @@ -2732,7 +2732,7 @@ req = webob.Request.blank("/images/%s" % UUID2) req.method = 'HEAD' res = req.get_response(self.api) - self.assertEquals(res.status_int, 401) + self.assertEquals(res.status_int, 403) def test_show_image_basic(self): req = webob.Request.blank("/images/%s" % UUID2) @@ -2751,7 +2751,7 @@ self.set_policy_rules(rules) req = webob.Request.blank("/images/%s" % UUID2) res = req.get_response(self.api) - self.assertEqual(res.status_int, 401) + self.assertEqual(res.status_int, 403) def test_delete_image(self): req = webob.Request.blank("/images/%s" % UUID2) @@ -2833,7 +2833,7 @@ req = webob.Request.blank("/images/%s" % UUID2) req.method = 'DELETE' res = req.get_response(self.api) - self.assertEquals(res.status_int, 401) + self.assertEquals(res.status_int, 403) def test_get_details_invalid_marker(self): """ diff -Nru glance-2012.1~rc1~20120309.1315/glance/vcsversion.py glance-2012.1~rc1~20120316.1354/glance/vcsversion.py --- glance-2012.1~rc1~20120309.1315/glance/vcsversion.py 2012-03-09 16:03:56.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/glance/vcsversion.py 2012-03-16 00:18:46.000000000 +0000 @@ -2,6 +2,6 @@ # This file is automatically generated by setup.py, So don't edit it. :) version_info = { 'branch_nick': '(no', - 'revision_id': '7041f19696e75c38c27e8dacaa7bbc8d56144af8', - 'revno': 1315 + 'revision_id': '8a533f9cfeda10bb759b0aa68757e4cea2ce4b43', + 'revno': 1354 } diff -Nru glance-2012.1~rc1~20120309.1315/glance.egg-info/SOURCES.txt glance-2012.1~rc1~20120316.1354/glance.egg-info/SOURCES.txt --- glance-2012.1~rc1~20120309.1315/glance.egg-info/SOURCES.txt 2012-03-09 16:03:57.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/glance.egg-info/SOURCES.txt 2012-03-16 00:18:47.000000000 +0000 @@ -3,6 +3,7 @@ LICENSE MANIFEST.in README.rst +babel.cfg pylintrc run_tests.py run_tests.sh @@ -15,7 +16,6 @@ bin/glance-cache-manage bin/glance-cache-prefetcher bin/glance-cache-pruner -bin/glance-cache-queue-image bin/glance-control bin/glance-manage bin/glance-registry @@ -24,12 +24,10 @@ doc/source/authentication.rst doc/source/cache.rst doc/source/client.rst -doc/source/community.rst doc/source/conf.py doc/source/configuring.rst doc/source/controllingservers.rst doc/source/formats.rst -doc/source/gettingstarted.rst doc/source/glance.rst doc/source/glanceapi.rst doc/source/identifiers.rst @@ -37,7 +35,6 @@ doc/source/installing.rst doc/source/notifications.rst doc/source/policies.rst -doc/source/registries.rst doc/source/statuses.rst doc/source/_static/basic.css doc/source/_static/default.css @@ -52,7 +49,6 @@ doc/source/man/glancecachemanage.rst doc/source/man/glancecacheprefetcher.rst doc/source/man/glancecachepruner.rst -doc/source/man/glancecachequeueimage.rst doc/source/man/glancecontrol.rst doc/source/man/glancemanage.rst doc/source/man/glanceregistry.rst @@ -111,6 +107,7 @@ glance/image_cache/drivers/sqlite.py glance/image_cache/drivers/xattr.py glance/locale/__init__.py +glance/locale/glance.pot glance/notifier/__init__.py glance/notifier/notify_kombu.py glance/notifier/notify_log.py @@ -174,6 +171,7 @@ glance/tests/functional/test_bin_glance.py glance/tests/functional/test_bin_glance_cache_manage.py glance/tests/functional/test_cache_middleware.py +glance/tests/functional/test_client_exceptions.py glance/tests/functional/test_client_redirects.py glance/tests/functional/test_copy_to_file.py glance/tests/functional/test_logging.py @@ -215,7 +213,6 @@ glance/tests/var/certificate.crt glance/tests/var/privatekey.key tools/install_venv.py -tools/nova_to_os_env.sh tools/pip-requires tools/test-requires tools/with_venv.sh \ No newline at end of file diff -Nru glance-2012.1~rc1~20120309.1315/MANIFEST.in glance-2012.1~rc1~20120316.1354/MANIFEST.in --- glance-2012.1~rc1~20120309.1315/MANIFEST.in 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/MANIFEST.in 2012-03-16 00:16:11.000000000 +0000 @@ -5,7 +5,8 @@ include run_tests.py include HACKING.rst include LICENSE -include tox.ini +include babel.cfg tox.ini +include glance/locale/glance.pot include glance/registry/db/migrate_repo/README include glance/registry/db/migrate_repo/migrate.cfg include glance/registry/db/migrate_repo/versions/*.sql diff -Nru glance-2012.1~rc1~20120309.1315/setup.py glance-2012.1~rc1~20120316.1354/setup.py --- glance-2012.1~rc1~20120309.1315/setup.py 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/setup.py 2012-03-16 00:16:18.000000000 +0000 @@ -108,7 +108,6 @@ 'bin/glance-api', 'bin/glance-cache-prefetcher', 'bin/glance-cache-pruner', - 'bin/glance-cache-queue-image', 'bin/glance-cache-manage', 'bin/glance-cache-cleaner', 'bin/glance-control', diff -Nru glance-2012.1~rc1~20120309.1315/tools/nova_to_os_env.sh glance-2012.1~rc1~20120316.1354/tools/nova_to_os_env.sh --- glance-2012.1~rc1~20120309.1315/tools/nova_to_os_env.sh 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/tools/nova_to_os_env.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -# This file is intended to be sourced to convert old-style NOVA environment -# variables to new-style OS. -# -# The plan is to add this to novarc, but until that lands, it's useful to have -# this in Glance. -export OS_AUTH_USER=$NOVA_USERNAME -export OS_AUTH_KEY=$NOVA_API_KEY -export OS_AUTH_TENANT=$NOVA_PROJECT_ID -export OS_AUTH_URL=$NOVA_URL -export OS_AUTH_STRATEGY=$NOVA_AUTH_STRATEGY diff -Nru glance-2012.1~rc1~20120309.1315/tox.ini glance-2012.1~rc1~20120316.1354/tox.ini --- glance-2012.1~rc1~20120309.1315/tox.ini 2012-03-09 16:01:13.000000000 +0000 +++ glance-2012.1~rc1~20120316.1354/tox.ini 2012-03-16 00:16:11.000000000 +0000 @@ -17,11 +17,8 @@ [testenv:venv] commands = {posargs} -[testenv:jenkins] +[tox:jenkins] downloadcache = ~/cache/pip -commands = - pip freeze - nosetests [testenv:jenkins26] basepython = python2.6